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 
11 #ifndef API_VIDEO_I420_BUFFER_H_
12 #define API_VIDEO_I420_BUFFER_H_
13 
14 #include <memory>
15 
16 #include "api/video/video_rotation.h"
17 #include "api/video/video_frame_buffer.h"
18 #include "system_wrappers/include/aligned_malloc.h"
19 
20 namespace webrtc {
21 
22 // Plain I420 buffer in standard memory.
23 class I420Buffer : public I420BufferInterface {
24  public:
25   static rtc::scoped_refptr<I420Buffer> Create(int width, int height);
26   static rtc::scoped_refptr<I420Buffer> Create(int width,
27                                                int height,
28                                                int stride_y,
29                                                int stride_u,
30                                                int stride_v);
31 
32   // Create a new buffer and copy the pixel data.
33   static rtc::scoped_refptr<I420Buffer> Copy(const I420BufferInterface& buffer);
34   // Deprecated.
Copy(const VideoFrameBuffer & buffer)35   static rtc::scoped_refptr<I420Buffer> Copy(const VideoFrameBuffer& buffer) {
36     return Copy(*buffer.GetI420());
37   }
38 
39   static rtc::scoped_refptr<I420Buffer> Copy(
40       int width, int height,
41       const uint8_t* data_y, int stride_y,
42       const uint8_t* data_u, int stride_u,
43       const uint8_t* data_v, int stride_v);
44 
45   // Returns a rotated copy of |src|.
46   static rtc::scoped_refptr<I420Buffer> Rotate(const I420BufferInterface& src,
47                                                VideoRotation rotation);
48   // Deprecated.
Rotate(const VideoFrameBuffer & src,VideoRotation rotation)49   static rtc::scoped_refptr<I420Buffer> Rotate(const VideoFrameBuffer& src,
50                                                VideoRotation rotation) {
51     return Rotate(*src.GetI420(), rotation);
52   }
53 
54   // Sets the buffer to all black.
55   static void SetBlack(I420Buffer* buffer);
56 
57   // Sets all three planes to all zeros. Used to work around for
58   // quirks in memory checkers
59   // (https://bugs.chromium.org/p/libyuv/issues/detail?id=377) and
60   // ffmpeg (http://crbug.com/390941).
61   // TODO(nisse): Deprecated. Should be deleted if/when those issues
62   // are resolved in a better way. Or in the mean time, use SetBlack.
63   void InitializeData();
64 
65   int width() const override;
66   int height() const override;
67   const uint8_t* DataY() const override;
68   const uint8_t* DataU() const override;
69   const uint8_t* DataV() const override;
70 
71   int StrideY() const override;
72   int StrideU() const override;
73   int StrideV() const override;
74 
75   uint8_t* MutableDataY();
76   uint8_t* MutableDataU();
77   uint8_t* MutableDataV();
78 
79   // Scale the cropped area of |src| to the size of |this| buffer, and
80   // write the result into |this|.
81   void CropAndScaleFrom(const I420BufferInterface& src,
82                         int offset_x,
83                         int offset_y,
84                         int crop_width,
85                         int crop_height);
86 
87   // The common case of a center crop, when needed to adjust the
88   // aspect ratio without distorting the image.
89   void CropAndScaleFrom(const I420BufferInterface& src);
90 
91   // Scale all of |src| to the size of |this| buffer, with no cropping.
92   void ScaleFrom(const I420BufferInterface& src);
93 
94  protected:
95   I420Buffer(int width, int height);
96   I420Buffer(int width, int height, int stride_y, int stride_u, int stride_v);
97 
98   ~I420Buffer() override;
99 
100  private:
101   const int width_;
102   const int height_;
103   const int stride_y_;
104   const int stride_u_;
105   const int stride_v_;
106   const std::unique_ptr<uint8_t, AlignedFreeDeleter> data_;
107 };
108 
109 }  // namespace webrtc
110 
111 #endif  // API_VIDEO_I420_BUFFER_H_
112