tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pipewire_utils.h (2881B)


      1 /*
      2 *  Copyright 2022 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #ifndef MODULES_PORTAL_PIPEWIRE_UTILS_H_
     12 #define MODULES_PORTAL_PIPEWIRE_UTILS_H_
     13 
     14 #include <asm-generic/ioctl.h>
     15 #include <sys/ioctl.h>
     16 #include <sys/mman.h>
     17 
     18 #include <cerrno>
     19 #include <cstdint>
     20 
     21 // static
     22 struct dma_buf_sync {
     23  uint64_t flags;
     24 };
     25 #define DMA_BUF_SYNC_READ (1 << 0)
     26 #define DMA_BUF_SYNC_START (0 << 2)
     27 #define DMA_BUF_SYNC_END (1 << 2)
     28 #define DMA_BUF_BASE 'b'
     29 #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
     30 
     31 struct pw_thread_loop;
     32 
     33 namespace webrtc {
     34 
     35 constexpr int kInvalidPipeWireFd = -1;
     36 
     37 // Prepare PipeWire so that it is ready to be used. If it needs to be dlopen'd
     38 // this will do so. Note that this does not guarantee a PipeWire server is
     39 // running nor does it establish a connection to one.
     40 bool InitializePipeWire();
     41 
     42 // Locks pw_thread_loop in the current scope
     43 class PipeWireThreadLoopLock {
     44 public:
     45  explicit PipeWireThreadLoopLock(pw_thread_loop* loop);
     46  ~PipeWireThreadLoopLock();
     47 
     48 private:
     49  pw_thread_loop* const loop_;
     50 };
     51 
     52 // We should synchronize DMA Buffer object access from CPU to avoid potential
     53 // cache incoherency and data loss.
     54 // See
     55 // https://01.org/linuxgraphics/gfx-docs/drm/driver-api/dma-buf.html#cpu-access-to-dma-buffer-objects
     56 static bool SyncDmaBuf(int fd, uint64_t start_or_end) {
     57  struct dma_buf_sync sync = {0};
     58 
     59  sync.flags = start_or_end | DMA_BUF_SYNC_READ;
     60 
     61  while (true) {
     62    int ret;
     63    ret = ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync);
     64    if (ret == -1 && errno == EINTR) {
     65      continue;
     66    } else if (ret == -1) {
     67      return false;
     68    } else {
     69      break;
     70    }
     71  }
     72 
     73  return true;
     74 }
     75 
     76 class ScopedBuf {
     77 public:
     78  ScopedBuf() {}
     79  ScopedBuf(uint8_t* map, int map_size, int fd, bool is_dma_buf = false)
     80      : map_(map), map_size_(map_size), fd_(fd), is_dma_buf_(is_dma_buf) {}
     81  ~ScopedBuf() {
     82    if (map_ != MAP_FAILED) {
     83      if (is_dma_buf_) {
     84        SyncDmaBuf(fd_, DMA_BUF_SYNC_END);
     85      }
     86      munmap(map_, map_size_);
     87    }
     88  }
     89 
     90  explicit operator bool() { return map_ != MAP_FAILED; }
     91 
     92  void initialize(uint8_t* map, int map_size, int fd, bool is_dma_buf = false) {
     93    map_ = map;
     94    map_size_ = map_size;
     95    is_dma_buf_ = is_dma_buf;
     96    fd_ = fd;
     97 
     98    if (is_dma_buf_) {
     99      SyncDmaBuf(fd_, DMA_BUF_SYNC_START);
    100    }
    101  }
    102 
    103  uint8_t* get() { return map_; }
    104 
    105 protected:
    106  uint8_t* map_ = static_cast<uint8_t*>(MAP_FAILED);
    107  int map_size_;
    108  int fd_;
    109  bool is_dma_buf_;
    110 };
    111 
    112 }  // namespace webrtc
    113 
    114 #endif  // MODULES_PORTAL_PIPEWIRE_UTILS_H_