blob: cf90ff22c1fc9a092e2b543b90f16bac988a02f2 [file] [log] [blame]
nisseaf916892017-01-10 07:44:26 -08001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef API_VIDEO_VIDEO_FRAME_BUFFER_H_
12#define API_VIDEO_VIDEO_FRAME_BUFFER_H_
nisseaf916892017-01-10 07:44:26 -080013
14#include <stdint.h>
15
Evan Shrubsoleb556b082020-10-08 14:56:45 +020016#include "api/array_view.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010017#include "api/scoped_refptr.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "rtc_base/ref_count.h"
Mirko Bonadei35214fc2019-09-23 14:54:28 +020019#include "rtc_base/system/rtc_export.h"
nisseaf916892017-01-10 07:44:26 -080020
21namespace webrtc {
22
magjedeaf4a1e2017-05-30 01:21:59 -070023class I420BufferInterface;
Emircan Uysaler574eaa42017-11-09 12:33:24 -080024class I420ABufferInterface;
Sergio Garcia Murillob63536f2022-03-25 09:04:09 +010025class I422BufferInterface;
magjedeaf4a1e2017-05-30 01:21:59 -070026class I444BufferInterface;
Emircan Uysaler901e0ff2018-06-26 12:22:38 -070027class I010BufferInterface;
Sergio Garcia Murillo8545eba2022-06-17 11:48:14 +020028class I210BufferInterface;
Evan Shrubsole84995432020-09-09 16:14:19 +020029class NV12BufferInterface;
magjed712338e2017-05-11 05:11:57 -070030
31// Base class for frame buffers of different types of pixel format and storage.
32// The tag in type() indicates how the data is represented, and each type is
33// implemented as a subclass. To access the pixel data, call the appropriate
34// GetXXX() function, where XXX represents the type. There is also a function
35// ToI420() that returns a frame buffer in I420 format, converting from the
36// underlying representation if necessary. I420 is the most widely accepted
37// format and serves as a fallback for video sinks that can only handle I420,
38// e.g. the internal WebRTC software encoders. A special enum value 'kNative' is
39// provided for external clients to implement their own frame buffer
40// representations, e.g. as textures. The external client can produce such
41// native frame buffers from custom video sources, and then cast it back to the
42// correct subclass in custom video sinks. The purpose of this is to improve
43// performance by providing an optimized path without intermediate conversions.
44// Frame metadata such as rotation and timestamp are stored in
45// webrtc::VideoFrame, and not here.
Mirko Bonadei35214fc2019-09-23 14:54:28 +020046class RTC_EXPORT VideoFrameBuffer : public rtc::RefCountInterface {
nisseaf916892017-01-10 07:44:26 -080047 public:
magjed712338e2017-05-11 05:11:57 -070048 // New frame buffer types will be added conservatively when there is an
49 // opportunity to optimize the path between some pair of video source and
50 // video sink.
Byoungchan Leef740c252021-07-24 06:16:20 +090051 // GENERATED_JAVA_ENUM_PACKAGE: org.webrtc
52 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: VideoFrameBufferType
magjed712338e2017-05-11 05:11:57 -070053 enum class Type {
54 kNative,
55 kI420,
Emircan Uysaler574eaa42017-11-09 12:33:24 -080056 kI420A,
Sergio Garcia Murillob63536f2022-03-25 09:04:09 +010057 kI422,
magjed712338e2017-05-11 05:11:57 -070058 kI444,
Emircan Uysaler901e0ff2018-06-26 12:22:38 -070059 kI010,
Sergio Garcia Murillo8545eba2022-06-17 11:48:14 +020060 kI210,
Evan Shrubsole84995432020-09-09 16:14:19 +020061 kNV12,
magjed712338e2017-05-11 05:11:57 -070062 };
63
64 // This function specifies in what pixel format the data is stored in.
Magnus Jedvert224e6592017-06-30 12:14:42 +000065 virtual Type type() const = 0;
magjed712338e2017-05-11 05:11:57 -070066
nisseaf916892017-01-10 07:44:26 -080067 // The resolution of the frame in pixels. For formats where some planes are
68 // subsampled, this is the highest-resolution plane.
69 virtual int width() const = 0;
70 virtual int height() const = 0;
71
magjed712338e2017-05-11 05:11:57 -070072 // Returns a memory-backed frame buffer in I420 format. If the pixel data is
73 // in another format, a conversion will take place. All implementations must
74 // provide a fallback to I420 for compatibility with e.g. the internal WebRTC
75 // software encoders.
Fabian Bergmarkf7a76982021-09-20 14:09:53 +020076 // Conversion may fail, for example if reading the pixel data from a texture
77 // fails. If the conversion fails, nullptr is returned.
Magnus Jedvert224e6592017-06-30 12:14:42 +000078 virtual rtc::scoped_refptr<I420BufferInterface> ToI420() = 0;
magjed712338e2017-05-11 05:11:57 -070079
Ilya Nikolaevskiyade0dc92019-04-29 11:25:50 +020080 // GetI420() methods should return I420 buffer if conversion is trivial, i.e
81 // no change for binary data is needed. Otherwise these methods should return
82 // nullptr. One example of buffer with that property is
83 // WebrtcVideoFrameAdapter in Chrome - it's I420 buffer backed by a shared
84 // memory buffer. Therefore it must have type kNative. Yet, ToI420()
85 // doesn't affect binary data at all. Another example is any I420A buffer.
Evan Shrubsoleb556b082020-10-08 14:56:45 +020086 // TODO(https://crbug.com/webrtc/12021): Make this method non-virtual and
87 // behave as the other GetXXX methods below.
Ilya Nikolaevskiya8507e32019-05-03 11:39:26 +020088 virtual const I420BufferInterface* GetI420() const;
Ilya Nikolaevskiyade0dc92019-04-29 11:25:50 +020089
Ilya Nikolaevskiy38e9b062020-10-08 14:36:33 +000090 // A format specific scale function. Default implementation works by
91 // converting to I420. But more efficient implementations may override it,
92 // especially for kNative.
Artem Titov0e61fdd2021-07-25 21:50:14 +020093 // First, the image is cropped to `crop_width` and `crop_height` and then
94 // scaled to `scaled_width` and `scaled_height`.
Ilya Nikolaevskiy38e9b062020-10-08 14:36:33 +000095 virtual rtc::scoped_refptr<VideoFrameBuffer> CropAndScale(int offset_x,
96 int offset_y,
97 int crop_width,
98 int crop_height,
99 int scaled_width,
100 int scaled_height);
101
102 // Alias for common use case.
103 rtc::scoped_refptr<VideoFrameBuffer> Scale(int scaled_width,
104 int scaled_height) {
105 return CropAndScale(0, 0, width(), height(), scaled_width, scaled_height);
106 }
107
Ilya Nikolaevskiyade0dc92019-04-29 11:25:50 +0200108 // These functions should only be called if type() is of the correct type.
109 // Calling with a different type will result in a crash.
Emircan Uysaler574eaa42017-11-09 12:33:24 -0800110 const I420ABufferInterface* GetI420A() const;
Sergio Garcia Murillob63536f2022-03-25 09:04:09 +0100111 const I422BufferInterface* GetI422() const;
magjed3f075492017-06-01 10:02:26 -0700112 const I444BufferInterface* GetI444() const;
Emircan Uysaler901e0ff2018-06-26 12:22:38 -0700113 const I010BufferInterface* GetI010() const;
Sergio Garcia Murillo8545eba2022-06-17 11:48:14 +0200114 const I210BufferInterface* GetI210() const;
Evan Shrubsole84995432020-09-09 16:14:19 +0200115 const NV12BufferInterface* GetNV12() const;
magjed712338e2017-05-11 05:11:57 -0700116
Evan Shrubsoleb556b082020-10-08 14:56:45 +0200117 // From a kNative frame, returns a VideoFrameBuffer with a pixel format in
118 // the list of types that is in the main memory with a pixel perfect
119 // conversion for encoding with a software encoder. Returns nullptr if the
120 // frame type is not supported, mapping is not possible, or if the kNative
121 // frame has not implemented this method. Only callable if type() is kNative.
122 virtual rtc::scoped_refptr<VideoFrameBuffer> GetMappedFrameBuffer(
123 rtc::ArrayView<Type> types);
124
nisseaf916892017-01-10 07:44:26 -0800125 protected:
126 ~VideoFrameBuffer() override {}
127};
128
Evan Shrubsoleb556b082020-10-08 14:56:45 +0200129// Update when VideoFrameBuffer::Type is updated.
130const char* VideoFrameBufferTypeToString(VideoFrameBuffer::Type type);
131
Emircan Uysaler901e0ff2018-06-26 12:22:38 -0700132// This interface represents planar formats.
magjed712338e2017-05-11 05:11:57 -0700133class PlanarYuvBuffer : public VideoFrameBuffer {
134 public:
magjedeaf4a1e2017-05-30 01:21:59 -0700135 virtual int ChromaWidth() const = 0;
136 virtual int ChromaHeight() const = 0;
magjed712338e2017-05-11 05:11:57 -0700137
Emircan Uysaler901e0ff2018-06-26 12:22:38 -0700138 // Returns the number of steps(in terms of Data*() return type) between
139 // successive rows for a given plane.
Magnus Jedvert224e6592017-06-30 12:14:42 +0000140 virtual int StrideY() const = 0;
141 virtual int StrideU() const = 0;
142 virtual int StrideV() const = 0;
magjed712338e2017-05-11 05:11:57 -0700143
magjed712338e2017-05-11 05:11:57 -0700144 protected:
145 ~PlanarYuvBuffer() override {}
146};
147
Emircan Uysaler901e0ff2018-06-26 12:22:38 -0700148// This interface represents 8-bit color depth formats: Type::kI420,
Sergio Garcia Murillob63536f2022-03-25 09:04:09 +0100149// Type::kI420A, Type::kI422 and Type::kI444.
Emircan Uysaler901e0ff2018-06-26 12:22:38 -0700150class PlanarYuv8Buffer : public PlanarYuvBuffer {
151 public:
152 // Returns pointer to the pixel data for a given plane. The memory is owned by
153 // the VideoFrameBuffer object and must not be freed by the caller.
154 virtual const uint8_t* DataY() const = 0;
155 virtual const uint8_t* DataU() const = 0;
156 virtual const uint8_t* DataV() const = 0;
157
158 protected:
159 ~PlanarYuv8Buffer() override {}
160};
161
Mirko Bonadei35214fc2019-09-23 14:54:28 +0200162class RTC_EXPORT I420BufferInterface : public PlanarYuv8Buffer {
magjedeaf4a1e2017-05-30 01:21:59 -0700163 public:
Emircan Uysaler574eaa42017-11-09 12:33:24 -0800164 Type type() const override;
magjedeaf4a1e2017-05-30 01:21:59 -0700165
166 int ChromaWidth() const final;
167 int ChromaHeight() const final;
168
169 rtc::scoped_refptr<I420BufferInterface> ToI420() final;
Ilya Nikolaevskiya8507e32019-05-03 11:39:26 +0200170 const I420BufferInterface* GetI420() const final;
magjedeaf4a1e2017-05-30 01:21:59 -0700171
172 protected:
173 ~I420BufferInterface() override {}
174};
175
Mirko Bonadei35214fc2019-09-23 14:54:28 +0200176class RTC_EXPORT I420ABufferInterface : public I420BufferInterface {
Emircan Uysaler574eaa42017-11-09 12:33:24 -0800177 public:
178 Type type() const final;
179 virtual const uint8_t* DataA() const = 0;
180 virtual int StrideA() const = 0;
181
182 protected:
183 ~I420ABufferInterface() override {}
184};
185
Sergio Garcia Murillob63536f2022-03-25 09:04:09 +0100186// Represents Type::kI422, 4:2:2 planar with 8 bits per pixel.
187class I422BufferInterface : public PlanarYuv8Buffer {
188 public:
189 Type type() const final;
190
191 int ChromaWidth() const final;
192 int ChromaHeight() const final;
193
194 rtc::scoped_refptr<VideoFrameBuffer> CropAndScale(int offset_x,
195 int offset_y,
196 int crop_width,
197 int crop_height,
198 int scaled_width,
199 int scaled_height) override;
200
201 protected:
202 ~I422BufferInterface() override {}
203};
204
205// Represents Type::kI444, 4:4:4 planar with 8 bits per pixel.
Emircan Uysaler901e0ff2018-06-26 12:22:38 -0700206class I444BufferInterface : public PlanarYuv8Buffer {
magjedeaf4a1e2017-05-30 01:21:59 -0700207 public:
208 Type type() const final;
209
210 int ChromaWidth() const final;
211 int ChromaHeight() const final;
212
Stefan Miticffdc6802022-02-08 07:00:16 -0800213 rtc::scoped_refptr<VideoFrameBuffer> CropAndScale(int offset_x,
214 int offset_y,
215 int crop_width,
216 int crop_height,
217 int scaled_width,
218 int scaled_height) override;
219
magjedeaf4a1e2017-05-30 01:21:59 -0700220 protected:
221 ~I444BufferInterface() override {}
222};
223
Sergio Garcia Murillo8545eba2022-06-17 11:48:14 +0200224// This interface represents 8-bit to 16-bit color depth formats: Type::kI010 or
225// Type::kI210 .
Emircan Uysaler901e0ff2018-06-26 12:22:38 -0700226class PlanarYuv16BBuffer : public PlanarYuvBuffer {
227 public:
228 // Returns pointer to the pixel data for a given plane. The memory is owned by
229 // the VideoFrameBuffer object and must not be freed by the caller.
230 virtual const uint16_t* DataY() const = 0;
231 virtual const uint16_t* DataU() const = 0;
232 virtual const uint16_t* DataV() const = 0;
233
234 protected:
235 ~PlanarYuv16BBuffer() override {}
236};
237
238// Represents Type::kI010, allocates 16 bits per pixel and fills 10 least
239// significant bits with color information.
240class I010BufferInterface : public PlanarYuv16BBuffer {
241 public:
242 Type type() const override;
243
244 int ChromaWidth() const final;
245 int ChromaHeight() const final;
246
247 protected:
248 ~I010BufferInterface() override {}
249};
250
Sergio Garcia Murillo8545eba2022-06-17 11:48:14 +0200251// Represents Type::kI210, allocates 16 bits per pixel and fills 10 least
252// significant bits with color information.
253class I210BufferInterface : public PlanarYuv16BBuffer {
254 public:
255 Type type() const override;
256
257 int ChromaWidth() const final;
258 int ChromaHeight() const final;
259
260 protected:
261 ~I210BufferInterface() override {}
262};
263
Evan Shrubsole84995432020-09-09 16:14:19 +0200264class BiplanarYuvBuffer : public VideoFrameBuffer {
265 public:
266 virtual int ChromaWidth() const = 0;
267 virtual int ChromaHeight() const = 0;
268
269 // Returns the number of steps(in terms of Data*() return type) between
270 // successive rows for a given plane.
271 virtual int StrideY() const = 0;
272 virtual int StrideUV() const = 0;
273
274 protected:
275 ~BiplanarYuvBuffer() override {}
276};
277
278class BiplanarYuv8Buffer : public BiplanarYuvBuffer {
279 public:
280 virtual const uint8_t* DataY() const = 0;
281 virtual const uint8_t* DataUV() const = 0;
282
283 protected:
284 ~BiplanarYuv8Buffer() override {}
285};
286
287// Represents Type::kNV12. NV12 is full resolution Y and half-resolution
288// interleved UV.
Evan Shrubsole0d1b0442020-10-07 18:09:56 +0200289class RTC_EXPORT NV12BufferInterface : public BiplanarYuv8Buffer {
Evan Shrubsole84995432020-09-09 16:14:19 +0200290 public:
291 Type type() const override;
292
293 int ChromaWidth() const final;
294 int ChromaHeight() const final;
295
Henrik Boströmf4129762021-03-22 10:22:54 +0100296 rtc::scoped_refptr<VideoFrameBuffer> CropAndScale(int offset_x,
297 int offset_y,
298 int crop_width,
299 int crop_height,
300 int scaled_width,
301 int scaled_height) override;
302
Evan Shrubsole84995432020-09-09 16:14:19 +0200303 protected:
304 ~NV12BufferInterface() override {}
305};
306
nisseaf916892017-01-10 07:44:26 -0800307} // namespace webrtc
308
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200309#endif // API_VIDEO_VIDEO_FRAME_BUFFER_H_