nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 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 | |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 11 | #ifndef API_VIDEO_VIDEO_FRAME_H_ |
| 12 | #define API_VIDEO_VIDEO_FRAME_H_ |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 13 | |
| 14 | #include <stdint.h> |
Chen Xing | f00bf42 | 2019-06-20 10:05:55 +0200 | [diff] [blame^] | 15 | #include <utility> |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 16 | |
Emircan Uysaler | 800787f | 2018-07-16 10:01:49 -0700 | [diff] [blame] | 17 | #include "absl/types/optional.h" |
Chen Xing | f00bf42 | 2019-06-20 10:05:55 +0200 | [diff] [blame^] | 18 | #include "api/rtp_packet_infos.h" |
Mirko Bonadei | d970807 | 2019-01-25 20:26:48 +0100 | [diff] [blame] | 19 | #include "api/scoped_refptr.h" |
Emircan Uysaler | 800787f | 2018-07-16 10:01:49 -0700 | [diff] [blame] | 20 | #include "api/video/color_space.h" |
Johannes Kron | fbf1683 | 2018-11-05 16:13:02 +0100 | [diff] [blame] | 21 | #include "api/video/hdr_metadata.h" |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 22 | #include "api/video/video_frame_buffer.h" |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 23 | #include "api/video/video_rotation.h" |
Ilya Nikolaevskiy | 6aca0b7 | 2019-02-13 11:55:57 +0100 | [diff] [blame] | 24 | #include "rtc_base/checks.h" |
Mirko Bonadei | ac19414 | 2018-10-22 17:08:37 +0200 | [diff] [blame] | 25 | #include "rtc_base/system/rtc_export.h" |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 26 | |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 27 | namespace webrtc { |
| 28 | |
Mirko Bonadei | ac19414 | 2018-10-22 17:08:37 +0200 | [diff] [blame] | 29 | class RTC_EXPORT VideoFrame { |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 30 | public: |
Ilya Nikolaevskiy | 6aca0b7 | 2019-02-13 11:55:57 +0100 | [diff] [blame] | 31 | struct UpdateRect { |
| 32 | int offset_x; |
| 33 | int offset_y; |
| 34 | int width; |
| 35 | int height; |
Ilya Nikolaevskiy | 71aee3a | 2019-02-18 13:01:26 +0100 | [diff] [blame] | 36 | |
| 37 | // Makes this UpdateRect a bounding box of this and other rect. |
| 38 | void Union(const UpdateRect& other); |
| 39 | |
| 40 | // Makes this UpdateRect an intersection of this and other rect. |
| 41 | void Intersect(const UpdateRect& other); |
| 42 | |
| 43 | // Sets everything to 0, making this UpdateRect a zero-size (empty) update. |
| 44 | void MakeEmptyUpdate(); |
| 45 | |
| 46 | bool IsEmpty() const; |
Ilya Nikolaevskiy | 6aca0b7 | 2019-02-13 11:55:57 +0100 | [diff] [blame] | 47 | }; |
| 48 | |
Emircan Uysaler | 800787f | 2018-07-16 10:01:49 -0700 | [diff] [blame] | 49 | // Preferred way of building VideoFrame objects. |
| 50 | class Builder { |
| 51 | public: |
| 52 | Builder(); |
| 53 | ~Builder(); |
| 54 | |
| 55 | VideoFrame build(); |
| 56 | Builder& set_video_frame_buffer( |
| 57 | const rtc::scoped_refptr<VideoFrameBuffer>& buffer); |
| 58 | Builder& set_timestamp_ms(int64_t timestamp_ms); |
| 59 | Builder& set_timestamp_us(int64_t timestamp_us); |
| 60 | Builder& set_timestamp_rtp(uint32_t timestamp_rtp); |
| 61 | Builder& set_ntp_time_ms(int64_t ntp_time_ms); |
| 62 | Builder& set_rotation(VideoRotation rotation); |
Danil Chapovalov | b769894 | 2019-02-05 11:32:19 +0100 | [diff] [blame] | 63 | Builder& set_color_space(const absl::optional<ColorSpace>& color_space); |
Johannes Kron | 4749e4e | 2018-11-21 10:18:18 +0100 | [diff] [blame] | 64 | Builder& set_color_space(const ColorSpace* color_space); |
Artem Titov | 1ebfb6a | 2019-01-03 23:49:37 +0100 | [diff] [blame] | 65 | Builder& set_id(uint16_t id); |
Ilya Nikolaevskiy | 6aca0b7 | 2019-02-13 11:55:57 +0100 | [diff] [blame] | 66 | Builder& set_update_rect(const UpdateRect& update_rect); |
Chen Xing | f00bf42 | 2019-06-20 10:05:55 +0200 | [diff] [blame^] | 67 | Builder& set_packet_infos(RtpPacketInfos packet_infos); |
Emircan Uysaler | 800787f | 2018-07-16 10:01:49 -0700 | [diff] [blame] | 68 | |
| 69 | private: |
Artem Titov | 1ebfb6a | 2019-01-03 23:49:37 +0100 | [diff] [blame] | 70 | uint16_t id_ = 0; |
Emircan Uysaler | 800787f | 2018-07-16 10:01:49 -0700 | [diff] [blame] | 71 | rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer_; |
| 72 | int64_t timestamp_us_ = 0; |
| 73 | uint32_t timestamp_rtp_ = 0; |
| 74 | int64_t ntp_time_ms_ = 0; |
| 75 | VideoRotation rotation_ = kVideoRotation_0; |
| 76 | absl::optional<ColorSpace> color_space_; |
Ilya Nikolaevskiy | 6aca0b7 | 2019-02-13 11:55:57 +0100 | [diff] [blame] | 77 | absl::optional<UpdateRect> update_rect_; |
Chen Xing | f00bf42 | 2019-06-20 10:05:55 +0200 | [diff] [blame^] | 78 | RtpPacketInfos packet_infos_; |
Emircan Uysaler | 800787f | 2018-07-16 10:01:49 -0700 | [diff] [blame] | 79 | }; |
| 80 | |
| 81 | // To be deprecated. Migrate all use to Builder. |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 82 | VideoFrame(const rtc::scoped_refptr<VideoFrameBuffer>& buffer, |
| 83 | webrtc::VideoRotation rotation, |
| 84 | int64_t timestamp_us); |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 85 | VideoFrame(const rtc::scoped_refptr<VideoFrameBuffer>& buffer, |
Niels Möller | 2ac6446 | 2018-06-11 11:14:32 +0200 | [diff] [blame] | 86 | uint32_t timestamp_rtp, |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 87 | int64_t render_time_ms, |
| 88 | VideoRotation rotation); |
| 89 | |
| 90 | ~VideoFrame(); |
| 91 | |
| 92 | // Support move and copy. |
| 93 | VideoFrame(const VideoFrame&); |
| 94 | VideoFrame(VideoFrame&&); |
| 95 | VideoFrame& operator=(const VideoFrame&); |
| 96 | VideoFrame& operator=(VideoFrame&&); |
| 97 | |
| 98 | // Get frame width. |
| 99 | int width() const; |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 100 | // Get frame height. |
| 101 | int height() const; |
kthelgason | 2bc6864 | 2017-02-07 07:02:22 -0800 | [diff] [blame] | 102 | // Get frame size in pixels. |
| 103 | uint32_t size() const; |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 104 | |
Artem Titov | 1ebfb6a | 2019-01-03 23:49:37 +0100 | [diff] [blame] | 105 | // Get frame ID. Returns 0 if ID is not set. Not guarantee to be transferred |
| 106 | // from the sender to the receiver, but preserved on single side. The id |
| 107 | // should be propagated between all frame modifications during its lifetime |
| 108 | // from capturing to sending as encoded image. It is intended to be unique |
| 109 | // over a time window of a few minutes for peer connection, to which |
| 110 | // corresponding video stream belongs to. |
| 111 | uint16_t id() const { return id_; } |
| 112 | void set_id(uint16_t id) { id_ = id; } |
| 113 | |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 114 | // System monotonic clock, same timebase as rtc::TimeMicros(). |
| 115 | int64_t timestamp_us() const { return timestamp_us_; } |
| 116 | void set_timestamp_us(int64_t timestamp_us) { timestamp_us_ = timestamp_us; } |
| 117 | |
| 118 | // TODO(nisse): After the cricket::VideoFrame and webrtc::VideoFrame |
| 119 | // merge, timestamps other than timestamp_us will likely be |
| 120 | // deprecated. |
| 121 | |
| 122 | // Set frame timestamp (90kHz). |
| 123 | void set_timestamp(uint32_t timestamp) { timestamp_rtp_ = timestamp; } |
| 124 | |
| 125 | // Get frame timestamp (90kHz). |
| 126 | uint32_t timestamp() const { return timestamp_rtp_; } |
| 127 | |
| 128 | // For now, transport_frame_id and rtp timestamp are the same. |
| 129 | // TODO(nisse): Must be handled differently for QUIC. |
| 130 | uint32_t transport_frame_id() const { return timestamp(); } |
| 131 | |
| 132 | // Set capture ntp time in milliseconds. |
nisse | 1c0dea8 | 2017-01-30 02:43:18 -0800 | [diff] [blame] | 133 | // TODO(nisse): Deprecated. Migrate all users to timestamp_us(). |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 134 | void set_ntp_time_ms(int64_t ntp_time_ms) { ntp_time_ms_ = ntp_time_ms; } |
| 135 | |
| 136 | // Get capture ntp time in milliseconds. |
nisse | 1c0dea8 | 2017-01-30 02:43:18 -0800 | [diff] [blame] | 137 | // TODO(nisse): Deprecated. Migrate all users to timestamp_us(). |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 138 | int64_t ntp_time_ms() const { return ntp_time_ms_; } |
| 139 | |
| 140 | // Naming convention for Coordination of Video Orientation. Please see |
| 141 | // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ts_126114v120700p.pdf |
| 142 | // |
| 143 | // "pending rotation" or "pending" = a frame that has a VideoRotation > 0. |
| 144 | // |
| 145 | // "not pending" = a frame that has a VideoRotation == 0. |
| 146 | // |
| 147 | // "apply rotation" = modify a frame from being "pending" to being "not |
| 148 | // pending" rotation (a no-op for "unrotated"). |
| 149 | // |
| 150 | VideoRotation rotation() const { return rotation_; } |
| 151 | void set_rotation(VideoRotation rotation) { rotation_ = rotation; } |
| 152 | |
Johannes Kron | fbf1683 | 2018-11-05 16:13:02 +0100 | [diff] [blame] | 153 | // Get color space when available. |
Danil Chapovalov | b769894 | 2019-02-05 11:32:19 +0100 | [diff] [blame] | 154 | const absl::optional<ColorSpace>& color_space() const { return color_space_; } |
| 155 | void set_color_space(const absl::optional<ColorSpace>& color_space) { |
| 156 | color_space_ = color_space; |
Johannes Kron | f7f13e0 | 2018-12-12 11:17:43 +0100 | [diff] [blame] | 157 | } |
Johannes Kron | fbf1683 | 2018-11-05 16:13:02 +0100 | [diff] [blame] | 158 | |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 159 | // Get render time in milliseconds. |
nisse | 1c0dea8 | 2017-01-30 02:43:18 -0800 | [diff] [blame] | 160 | // TODO(nisse): Deprecated. Migrate all users to timestamp_us(). |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 161 | int64_t render_time_ms() const; |
| 162 | |
Ilya Nikolaevskiy | 871e144 | 2019-02-11 13:35:03 +0100 | [diff] [blame] | 163 | // Return the underlying buffer. Never nullptr for a properly |
| 164 | // initialized VideoFrame. |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 165 | rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer() const; |
| 166 | |
Ilya Nikolaevskiy | 4fc0855 | 2019-06-05 15:59:12 +0200 | [diff] [blame] | 167 | void set_video_frame_buffer( |
| 168 | const rtc::scoped_refptr<VideoFrameBuffer>& buffer); |
| 169 | |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 170 | // TODO(nisse): Deprecated. |
| 171 | // Return true if the frame is stored in a texture. |
| 172 | bool is_texture() const { |
magjed | 3f07549 | 2017-06-01 10:02:26 -0700 | [diff] [blame] | 173 | return video_frame_buffer()->type() == VideoFrameBuffer::Type::kNative; |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 174 | } |
| 175 | |
Ilya Nikolaevskiy | 6aca0b7 | 2019-02-13 11:55:57 +0100 | [diff] [blame] | 176 | // Always initialized to whole frame update, can be set by Builder or manually |
| 177 | // by |set_update_rect|. |
| 178 | UpdateRect update_rect() const { return update_rect_; } |
| 179 | // Rectangle must be within the frame dimensions. |
| 180 | void set_update_rect(const VideoFrame::UpdateRect& update_rect) { |
| 181 | RTC_DCHECK_GE(update_rect.offset_x, 0); |
| 182 | RTC_DCHECK_GE(update_rect.offset_y, 0); |
| 183 | RTC_DCHECK_LE(update_rect.offset_x + update_rect.width, width()); |
| 184 | RTC_DCHECK_LE(update_rect.offset_y + update_rect.height, height()); |
| 185 | update_rect_ = update_rect; |
| 186 | } |
| 187 | |
Chen Xing | f00bf42 | 2019-06-20 10:05:55 +0200 | [diff] [blame^] | 188 | // Get information about packets used to assemble this video frame. Might be |
| 189 | // empty if the information isn't available. |
| 190 | const RtpPacketInfos& packet_infos() const { return packet_infos_; } |
| 191 | void set_packet_infos(RtpPacketInfos value) { |
| 192 | packet_infos_ = std::move(value); |
| 193 | } |
| 194 | |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 195 | private: |
Ilya Nikolaevskiy | 871e144 | 2019-02-11 13:35:03 +0100 | [diff] [blame] | 196 | VideoFrame(uint16_t id, |
| 197 | const rtc::scoped_refptr<VideoFrameBuffer>& buffer, |
| 198 | int64_t timestamp_us, |
| 199 | uint32_t timestamp_rtp, |
| 200 | int64_t ntp_time_ms, |
| 201 | VideoRotation rotation, |
Ilya Nikolaevskiy | 6aca0b7 | 2019-02-13 11:55:57 +0100 | [diff] [blame] | 202 | const absl::optional<ColorSpace>& color_space, |
Chen Xing | f00bf42 | 2019-06-20 10:05:55 +0200 | [diff] [blame^] | 203 | const absl::optional<UpdateRect>& update_rect, |
| 204 | RtpPacketInfos packet_infos); |
Emircan Uysaler | 800787f | 2018-07-16 10:01:49 -0700 | [diff] [blame] | 205 | |
Artem Titov | 1ebfb6a | 2019-01-03 23:49:37 +0100 | [diff] [blame] | 206 | uint16_t id_; |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 207 | // An opaque reference counted handle that stores the pixel data. |
| 208 | rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer_; |
| 209 | uint32_t timestamp_rtp_; |
| 210 | int64_t ntp_time_ms_; |
| 211 | int64_t timestamp_us_; |
| 212 | VideoRotation rotation_; |
Emircan Uysaler | 800787f | 2018-07-16 10:01:49 -0700 | [diff] [blame] | 213 | absl::optional<ColorSpace> color_space_; |
Ilya Nikolaevskiy | 6aca0b7 | 2019-02-13 11:55:57 +0100 | [diff] [blame] | 214 | // Updated since the last frame area. Unless set explicitly, will always be |
| 215 | // a full frame rectangle. |
| 216 | UpdateRect update_rect_; |
Chen Xing | f00bf42 | 2019-06-20 10:05:55 +0200 | [diff] [blame^] | 217 | // Information about packets used to assemble this video frame. This is needed |
| 218 | // by |SourceTracker| when the frame is delivered to the RTCRtpReceiver's |
| 219 | // MediaStreamTrack, in order to implement getContributingSources(). See: |
| 220 | // https://w3c.github.io/webrtc-pc/#dom-rtcrtpreceiver-getcontributingsources |
| 221 | RtpPacketInfos packet_infos_; |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 222 | }; |
| 223 | |
| 224 | } // namespace webrtc |
| 225 | |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 226 | #endif // API_VIDEO_VIDEO_FRAME_H_ |