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
20namespace webrtc {
21
22class 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).
106  void set_timestamp(uint32_t timestamp) { timestamp_ = timestamp; }
107
108  // Get frame timestamp (90kHz).
109  uint32_t timestamp() const { return timestamp_; }
110
111  // Set capture ntp time in miliseconds.
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.
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  //
129  VideoRotation rotation() const { return rotation_; }
130  void set_rotation(VideoRotation rotation) {
131    rotation_ = rotation;
132  }
133
134  // Set render time in miliseconds.
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.
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.
174class EncodedImage {
175 public:
176  EncodedImage() : EncodedImage(nullptr, 0, 0) {}
177  EncodedImage(uint8_t* buffer, size_t length, size_t size)
178      : _buffer(buffer), _length(length), _size(size) {}
179
180  struct AdaptReason {
181    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