1 /*
2  *  Copyright (c) 2014 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 WEBRTC_VIDEO_FRAME_H_
12 #define WEBRTC_VIDEO_FRAME_H_
13 
14 #include "webrtc/base/scoped_ref_ptr.h"
15 #include "webrtc/common_types.h"
16 #include "webrtc/common_video/include/video_frame_buffer.h"
17 #include "webrtc/common_video/rotation.h"
18 #include "webrtc/typedefs.h"
19 
20 namespace webrtc {
21 
22 class VideoFrame {
23  public:
24   VideoFrame();
25   VideoFrame(const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
26              uint32_t timestamp,
27              int64_t render_time_ms,
28              VideoRotation rotation);
29 
30   // TODO(pbos): Make all create/copy functions void, they should not be able to
31   // fail (which should be RTC_DCHECK/CHECKed instead).
32 
33   // CreateEmptyFrame: Sets frame dimensions and allocates buffers based
34   // on set dimensions - height and plane stride.
35   // If required size is bigger than the allocated one, new buffers of adequate
36   // size will be allocated.
37   // Return value: 0 on success, -1 on error.
38   int CreateEmptyFrame(int width,
39                        int height,
40                        int stride_y,
41                        int stride_u,
42                        int stride_v);
43 
44   // CreateFrame: Sets the frame's members and buffers. If required size is
45   // bigger than allocated one, new buffers of adequate size will be allocated.
46   // Return value: 0 on success, -1 on error.
47   int CreateFrame(const uint8_t* buffer_y,
48                   const uint8_t* buffer_u,
49                   const uint8_t* buffer_v,
50                   int width,
51                   int height,
52                   int stride_y,
53                   int stride_u,
54                   int stride_v);
55 
56   // TODO(guoweis): remove the previous CreateFrame when chromium has this code.
57   int CreateFrame(const uint8_t* buffer_y,
58                   const uint8_t* buffer_u,
59                   const uint8_t* buffer_v,
60                   int width,
61                   int height,
62                   int stride_y,
63                   int stride_u,
64                   int stride_v,
65                   VideoRotation rotation);
66 
67   // CreateFrame: Sets the frame's members and buffers. If required size is
68   // bigger than allocated one, new buffers of adequate size will be allocated.
69   // |buffer| must be a packed I420 buffer.
70   // Return value: 0 on success, -1 on error.
71   int CreateFrame(const uint8_t* buffer,
72                   int width,
73                   int height,
74                   VideoRotation rotation);
75 
76   // Deep copy frame: If required size is bigger than allocated one, new
77   // buffers of adequate size will be allocated.
78   // Return value: 0 on success, -1 on error.
79   int CopyFrame(const VideoFrame& videoFrame);
80 
81   // Creates a shallow copy of |videoFrame|, i.e, the this object will retain a
82   // reference to the video buffer also retained by |videoFrame|.
83   void ShallowCopy(const VideoFrame& videoFrame);
84 
85   // Release frame buffer and reset time stamps.
86   void Reset();
87 
88   // Get pointer to buffer per plane.
89   uint8_t* buffer(PlaneType type);
90   // Overloading with const.
91   const uint8_t* buffer(PlaneType type) const;
92 
93   // Get allocated size per plane.
94   int allocated_size(PlaneType type) const;
95 
96   // Get allocated stride per plane.
97   int stride(PlaneType type) const;
98 
99   // Get frame width.
100   int width() const;
101 
102   // Get frame height.
103   int height() const;
104 
105   // Set frame timestamp (90kHz).
set_timestamp(uint32_t timestamp)106   void set_timestamp(uint32_t timestamp) { timestamp_ = timestamp; }
107 
108   // Get frame timestamp (90kHz).
timestamp()109   uint32_t timestamp() const { return timestamp_; }
110 
111   // Set capture ntp time in miliseconds.
set_ntp_time_ms(int64_t ntp_time_ms)112   void set_ntp_time_ms(int64_t ntp_time_ms) {
113     ntp_time_ms_ = ntp_time_ms;
114   }
115 
116   // Get capture ntp time in miliseconds.
ntp_time_ms()117   int64_t ntp_time_ms() const { return ntp_time_ms_; }
118 
119   // Naming convention for Coordination of Video Orientation. Please see
120   // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ts_126114v120700p.pdf
121   //
122   // "pending rotation" or "pending" = a frame that has a VideoRotation > 0.
123   //
124   // "not pending" = a frame that has a VideoRotation == 0.
125   //
126   // "apply rotation" = modify a frame from being "pending" to being "not
127   //                    pending" rotation (a no-op for "unrotated").
128   //
rotation()129   VideoRotation rotation() const { return rotation_; }
set_rotation(VideoRotation rotation)130   void set_rotation(VideoRotation rotation) {
131     rotation_ = rotation;
132   }
133 
134   // Set render time in miliseconds.
set_render_time_ms(int64_t render_time_ms)135   void set_render_time_ms(int64_t render_time_ms) {
136     render_time_ms_ = render_time_ms;
137   }
138 
139   // Get render time in miliseconds.
render_time_ms()140   int64_t render_time_ms() const { return render_time_ms_; }
141 
142   // Return true if underlying plane buffers are of zero size, false if not.
143   bool IsZeroSize() const;
144 
145   // Return the handle of the underlying video frame. This is used when the
146   // frame is backed by a texture. The object should be destroyed when it is no
147   // longer in use, so the underlying resource can be freed.
148   void* native_handle() const;
149 
150   // Return the underlying buffer.
151   rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer() const;
152 
153   // Set the underlying buffer.
154   void set_video_frame_buffer(
155       const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer);
156 
157   // Convert native-handle frame to memory-backed I420 frame. Should not be
158   // called on a non-native-handle frame.
159   VideoFrame ConvertNativeToI420Frame() const;
160 
161   bool EqualsFrame(const VideoFrame& frame) const;
162 
163  private:
164   // An opaque reference counted handle that stores the pixel data.
165   rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer_;
166   uint32_t timestamp_;
167   int64_t ntp_time_ms_;
168   int64_t render_time_ms_;
169   VideoRotation rotation_;
170 };
171 
172 
173 // TODO(pbos): Rename EncodedFrame and reformat this class' members.
174 class EncodedImage {
175  public:
EncodedImage()176   EncodedImage() : EncodedImage(nullptr, 0, 0) {}
EncodedImage(uint8_t * buffer,size_t length,size_t size)177   EncodedImage(uint8_t* buffer, size_t length, size_t size)
178       : _buffer(buffer), _length(length), _size(size) {}
179 
180   struct AdaptReason {
AdaptReasonAdaptReason181     AdaptReason()
182         : quality_resolution_downscales(-1),
183           bw_resolutions_disabled(-1) {}
184 
185     int quality_resolution_downscales;  // Number of times this frame is down
186                                         // scaled in resolution due to quality.
187                                         // Or -1 if information is not provided.
188     int bw_resolutions_disabled;  // Number of resolutions that are not sent
189                                   // due to bandwidth for this frame.
190                                   // Or -1 if information is not provided.
191   };
192   uint32_t _encodedWidth = 0;
193   uint32_t _encodedHeight = 0;
194   uint32_t _timeStamp = 0;
195   // NTP time of the capture time in local timebase in milliseconds.
196   int64_t ntp_time_ms_ = 0;
197   int64_t capture_time_ms_ = 0;
198   FrameType _frameType = kVideoFrameDelta;
199   uint8_t* _buffer;
200   size_t _length;
201   size_t _size;
202   bool _completeFrame = false;
203   AdaptReason adapt_reason_;
204   int qp_ = -1;  // Quantizer value.
205 };
206 
207 }  // namespace webrtc
208 #endif  // WEBRTC_VIDEO_FRAME_H_
209