tor-browser

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

video_frame_buffer.cc (12825B)


      1 /*
      2 *  Copyright (c) 2015 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 #include "common_video/include/video_frame_buffer.h"
     11 
     12 #include <cstdint>
     13 #include <functional>
     14 
     15 #include "api/make_ref_counted.h"
     16 #include "api/scoped_refptr.h"
     17 #include "api/video/i420_buffer.h"
     18 #include "api/video/video_frame_buffer.h"
     19 #include "rtc_base/checks.h"
     20 #include "rtc_base/ref_counted_object.h"
     21 #include "third_party/libyuv/include/libyuv/convert.h"
     22 
     23 namespace webrtc {
     24 
     25 namespace {
     26 
     27 // Template to implement a wrapped buffer for a I4??BufferInterface.
     28 template <typename Base>
     29 class WrappedYuvBuffer : public Base {
     30 public:
     31  WrappedYuvBuffer(int width,
     32                   int height,
     33                   const uint8_t* y_plane,
     34                   int y_stride,
     35                   const uint8_t* u_plane,
     36                   int u_stride,
     37                   const uint8_t* v_plane,
     38                   int v_stride,
     39                   std::function<void()> no_longer_used)
     40      : width_(width),
     41        height_(height),
     42        y_plane_(y_plane),
     43        u_plane_(u_plane),
     44        v_plane_(v_plane),
     45        y_stride_(y_stride),
     46        u_stride_(u_stride),
     47        v_stride_(v_stride),
     48        no_longer_used_cb_(no_longer_used) {}
     49 
     50  ~WrappedYuvBuffer() override { no_longer_used_cb_(); }
     51 
     52  int width() const override { return width_; }
     53 
     54  int height() const override { return height_; }
     55 
     56  const uint8_t* DataY() const override { return y_plane_; }
     57 
     58  const uint8_t* DataU() const override { return u_plane_; }
     59 
     60  const uint8_t* DataV() const override { return v_plane_; }
     61 
     62  int StrideY() const override { return y_stride_; }
     63 
     64  int StrideU() const override { return u_stride_; }
     65 
     66  int StrideV() const override { return v_stride_; }
     67 
     68 private:
     69  friend class RefCountedObject<WrappedYuvBuffer>;
     70 
     71  const int width_;
     72  const int height_;
     73  const uint8_t* const y_plane_;
     74  const uint8_t* const u_plane_;
     75  const uint8_t* const v_plane_;
     76  const int y_stride_;
     77  const int u_stride_;
     78  const int v_stride_;
     79  std::function<void()> no_longer_used_cb_;
     80 };
     81 
     82 // Template to implement a wrapped buffer for a I4??BufferInterface.
     83 template <typename BaseWithA>
     84 class WrappedYuvaBuffer : public WrappedYuvBuffer<BaseWithA> {
     85 public:
     86  WrappedYuvaBuffer(int width,
     87                    int height,
     88                    const uint8_t* y_plane,
     89                    int y_stride,
     90                    const uint8_t* u_plane,
     91                    int u_stride,
     92                    const uint8_t* v_plane,
     93                    int v_stride,
     94                    const uint8_t* a_plane,
     95                    int a_stride,
     96                    std::function<void()> no_longer_used)
     97      : WrappedYuvBuffer<BaseWithA>(width,
     98                                    height,
     99                                    y_plane,
    100                                    y_stride,
    101                                    u_plane,
    102                                    u_stride,
    103                                    v_plane,
    104                                    v_stride,
    105                                    no_longer_used),
    106        a_plane_(a_plane),
    107        a_stride_(a_stride) {}
    108 
    109  const uint8_t* DataA() const override { return a_plane_; }
    110  int StrideA() const override { return a_stride_; }
    111 
    112 private:
    113  const uint8_t* const a_plane_;
    114  const int a_stride_;
    115 };
    116 
    117 class I444BufferBase : public I444BufferInterface {
    118 public:
    119  scoped_refptr<I420BufferInterface> ToI420() final;
    120 };
    121 
    122 scoped_refptr<I420BufferInterface> I444BufferBase::ToI420() {
    123  scoped_refptr<I420Buffer> i420_buffer = I420Buffer::Create(width(), height());
    124  libyuv::I444ToI420(DataY(), StrideY(), DataU(), StrideU(), DataV(), StrideV(),
    125                     i420_buffer->MutableDataY(), i420_buffer->StrideY(),
    126                     i420_buffer->MutableDataU(), i420_buffer->StrideU(),
    127                     i420_buffer->MutableDataV(), i420_buffer->StrideV(),
    128                     width(), height());
    129  return i420_buffer;
    130 }
    131 
    132 class I422BufferBase : public I422BufferInterface {
    133 public:
    134  scoped_refptr<I420BufferInterface> ToI420() final;
    135 };
    136 
    137 scoped_refptr<I420BufferInterface> I422BufferBase::ToI420() {
    138  scoped_refptr<I420Buffer> i420_buffer = I420Buffer::Create(width(), height());
    139  libyuv::I422ToI420(DataY(), StrideY(), DataU(), StrideU(), DataV(), StrideV(),
    140                     i420_buffer->MutableDataY(), i420_buffer->StrideY(),
    141                     i420_buffer->MutableDataU(), i420_buffer->StrideU(),
    142                     i420_buffer->MutableDataV(), i420_buffer->StrideV(),
    143                     width(), height());
    144  return i420_buffer;
    145 }
    146 
    147 // Template to implement a wrapped buffer for a PlanarYuv16BBuffer.
    148 template <typename Base>
    149 class WrappedYuv16BBuffer : public Base {
    150 public:
    151  WrappedYuv16BBuffer(int width,
    152                      int height,
    153                      const uint16_t* y_plane,
    154                      int y_stride,
    155                      const uint16_t* u_plane,
    156                      int u_stride,
    157                      const uint16_t* v_plane,
    158                      int v_stride,
    159                      std::function<void()> no_longer_used)
    160      : width_(width),
    161        height_(height),
    162        y_plane_(y_plane),
    163        u_plane_(u_plane),
    164        v_plane_(v_plane),
    165        y_stride_(y_stride),
    166        u_stride_(u_stride),
    167        v_stride_(v_stride),
    168        no_longer_used_cb_(no_longer_used) {}
    169 
    170  ~WrappedYuv16BBuffer() override { no_longer_used_cb_(); }
    171 
    172  int width() const override { return width_; }
    173 
    174  int height() const override { return height_; }
    175 
    176  const uint16_t* DataY() const override { return y_plane_; }
    177 
    178  const uint16_t* DataU() const override { return u_plane_; }
    179 
    180  const uint16_t* DataV() const override { return v_plane_; }
    181 
    182  int StrideY() const override { return y_stride_; }
    183 
    184  int StrideU() const override { return u_stride_; }
    185 
    186  int StrideV() const override { return v_stride_; }
    187 
    188 private:
    189  friend class RefCountedObject<WrappedYuv16BBuffer>;
    190 
    191  const int width_;
    192  const int height_;
    193  const uint16_t* const y_plane_;
    194  const uint16_t* const u_plane_;
    195  const uint16_t* const v_plane_;
    196  const int y_stride_;
    197  const int u_stride_;
    198  const int v_stride_;
    199  std::function<void()> no_longer_used_cb_;
    200 };
    201 
    202 class I010BufferBase : public I010BufferInterface {
    203 public:
    204  scoped_refptr<I420BufferInterface> ToI420() final;
    205 };
    206 
    207 scoped_refptr<I420BufferInterface> I010BufferBase::ToI420() {
    208  scoped_refptr<I420Buffer> i420_buffer = I420Buffer::Create(width(), height());
    209  libyuv::I010ToI420(DataY(), StrideY(), DataU(), StrideU(), DataV(), StrideV(),
    210                     i420_buffer->MutableDataY(), i420_buffer->StrideY(),
    211                     i420_buffer->MutableDataU(), i420_buffer->StrideU(),
    212                     i420_buffer->MutableDataV(), i420_buffer->StrideV(),
    213                     width(), height());
    214  return i420_buffer;
    215 }
    216 
    217 class I210BufferBase : public I210BufferInterface {
    218 public:
    219  scoped_refptr<I420BufferInterface> ToI420() final;
    220 };
    221 
    222 scoped_refptr<I420BufferInterface> I210BufferBase::ToI420() {
    223  scoped_refptr<I420Buffer> i420_buffer = I420Buffer::Create(width(), height());
    224  libyuv::I210ToI420(DataY(), StrideY(), DataU(), StrideU(), DataV(), StrideV(),
    225                     i420_buffer->MutableDataY(), i420_buffer->StrideY(),
    226                     i420_buffer->MutableDataU(), i420_buffer->StrideU(),
    227                     i420_buffer->MutableDataV(), i420_buffer->StrideV(),
    228                     width(), height());
    229  return i420_buffer;
    230 }
    231 
    232 class I410BufferBase : public I410BufferInterface {
    233 public:
    234  scoped_refptr<I420BufferInterface> ToI420() final;
    235 };
    236 
    237 scoped_refptr<I420BufferInterface> I410BufferBase::ToI420() {
    238  scoped_refptr<I420Buffer> i420_buffer = I420Buffer::Create(width(), height());
    239  libyuv::I410ToI420(DataY(), StrideY(), DataU(), StrideU(), DataV(), StrideV(),
    240                     i420_buffer->MutableDataY(), i420_buffer->StrideY(),
    241                     i420_buffer->MutableDataU(), i420_buffer->StrideU(),
    242                     i420_buffer->MutableDataV(), i420_buffer->StrideV(),
    243                     width(), height());
    244  return i420_buffer;
    245 }
    246 
    247 }  // namespace
    248 
    249 scoped_refptr<I420BufferInterface> WrapI420Buffer(
    250    int width,
    251    int height,
    252    const uint8_t* y_plane,
    253    int y_stride,
    254    const uint8_t* u_plane,
    255    int u_stride,
    256    const uint8_t* v_plane,
    257    int v_stride,
    258    std::function<void()> no_longer_used) {
    259  return scoped_refptr<I420BufferInterface>(
    260      make_ref_counted<WrappedYuvBuffer<I420BufferInterface>>(
    261          width, height, y_plane, y_stride, u_plane, u_stride, v_plane,
    262          v_stride, no_longer_used));
    263 }
    264 
    265 scoped_refptr<I420ABufferInterface> WrapI420ABuffer(
    266    int width,
    267    int height,
    268    const uint8_t* y_plane,
    269    int y_stride,
    270    const uint8_t* u_plane,
    271    int u_stride,
    272    const uint8_t* v_plane,
    273    int v_stride,
    274    const uint8_t* a_plane,
    275    int a_stride,
    276    std::function<void()> no_longer_used) {
    277  return scoped_refptr<I420ABufferInterface>(
    278      make_ref_counted<WrappedYuvaBuffer<I420ABufferInterface>>(
    279          width, height, y_plane, y_stride, u_plane, u_stride, v_plane,
    280          v_stride, a_plane, a_stride, no_longer_used));
    281 }
    282 
    283 scoped_refptr<I422BufferInterface> WrapI422Buffer(
    284    int width,
    285    int height,
    286    const uint8_t* y_plane,
    287    int y_stride,
    288    const uint8_t* u_plane,
    289    int u_stride,
    290    const uint8_t* v_plane,
    291    int v_stride,
    292    std::function<void()> no_longer_used) {
    293  return scoped_refptr<I422BufferBase>(
    294      make_ref_counted<WrappedYuvBuffer<I422BufferBase>>(
    295          width, height, y_plane, y_stride, u_plane, u_stride, v_plane,
    296          v_stride, no_longer_used));
    297 }
    298 
    299 scoped_refptr<I444BufferInterface> WrapI444Buffer(
    300    int width,
    301    int height,
    302    const uint8_t* y_plane,
    303    int y_stride,
    304    const uint8_t* u_plane,
    305    int u_stride,
    306    const uint8_t* v_plane,
    307    int v_stride,
    308    std::function<void()> no_longer_used) {
    309  return scoped_refptr<I444BufferInterface>(
    310      make_ref_counted<WrappedYuvBuffer<I444BufferBase>>(
    311          width, height, y_plane, y_stride, u_plane, u_stride, v_plane,
    312          v_stride, no_longer_used));
    313 }
    314 
    315 scoped_refptr<PlanarYuvBuffer> WrapYuvBuffer(
    316    VideoFrameBuffer::Type type,
    317    int width,
    318    int height,
    319    const uint8_t* y_plane,
    320    int y_stride,
    321    const uint8_t* u_plane,
    322    int u_stride,
    323    const uint8_t* v_plane,
    324    int v_stride,
    325    std::function<void()> no_longer_used) {
    326  switch (type) {
    327    case VideoFrameBuffer::Type::kI420:
    328      return WrapI420Buffer(width, height, y_plane, y_stride, u_plane, u_stride,
    329                            v_plane, v_stride, no_longer_used);
    330    case VideoFrameBuffer::Type::kI422:
    331      return WrapI422Buffer(width, height, y_plane, y_stride, u_plane, u_stride,
    332                            v_plane, v_stride, no_longer_used);
    333    case VideoFrameBuffer::Type::kI444:
    334      return WrapI444Buffer(width, height, y_plane, y_stride, u_plane, u_stride,
    335                            v_plane, v_stride, no_longer_used);
    336    default:
    337      RTC_CHECK_NOTREACHED();
    338  }
    339 }
    340 
    341 scoped_refptr<I010BufferInterface> WrapI010Buffer(
    342    int width,
    343    int height,
    344    const uint16_t* y_plane,
    345    int y_stride,
    346    const uint16_t* u_plane,
    347    int u_stride,
    348    const uint16_t* v_plane,
    349    int v_stride,
    350    std::function<void()> no_longer_used) {
    351  return scoped_refptr<I010BufferInterface>(
    352      make_ref_counted<WrappedYuv16BBuffer<I010BufferBase>>(
    353          width, height, y_plane, y_stride, u_plane, u_stride, v_plane,
    354          v_stride, no_longer_used));
    355 }
    356 
    357 scoped_refptr<I210BufferInterface> WrapI210Buffer(
    358    int width,
    359    int height,
    360    const uint16_t* y_plane,
    361    int y_stride,
    362    const uint16_t* u_plane,
    363    int u_stride,
    364    const uint16_t* v_plane,
    365    int v_stride,
    366    std::function<void()> no_longer_used) {
    367  return scoped_refptr<I210BufferInterface>(
    368      make_ref_counted<WrappedYuv16BBuffer<I210BufferBase>>(
    369          width, height, y_plane, y_stride, u_plane, u_stride, v_plane,
    370          v_stride, no_longer_used));
    371 }
    372 
    373 scoped_refptr<I410BufferInterface> WrapI410Buffer(
    374    int width,
    375    int height,
    376    const uint16_t* y_plane,
    377    int y_stride,
    378    const uint16_t* u_plane,
    379    int u_stride,
    380    const uint16_t* v_plane,
    381    int v_stride,
    382    std::function<void()> no_longer_used) {
    383  return scoped_refptr<I410BufferInterface>(
    384      make_ref_counted<WrappedYuv16BBuffer<I410BufferBase>>(
    385          width, height, y_plane, y_stride, u_plane, u_stride, v_plane,
    386          v_stride, no_longer_used));
    387 }
    388 
    389 }  // namespace webrtc