blob: 34bb6938975f3a131bd5e06613d00bf871bf5fc8 [file] [log] [blame]
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +00001/*
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 */
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020010#include "common_video/include/video_frame_buffer.h"
perkj0489e492016-10-20 00:24:01 -070011
Patrik Höglundb5b5bce2017-11-13 10:19:58 +010012#include "api/video/i420_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 09:11:00 -080014#include "rtc_base/ref_counted_object.h"
Mirko Bonadei65432062017-12-11 09:32:13 +010015#include "third_party/libyuv/include/libyuv/convert.h"
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +000016
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +000017namespace webrtc {
18
Patrik Höglundb5b5bce2017-11-13 10:19:58 +010019namespace {
Per33544192015-04-02 12:30:51 +020020
yuweih23cc4682017-06-22 20:28:06 -070021// Template to implement a wrapped buffer for a I4??BufferInterface.
22template <typename Base>
23class WrappedYuvBuffer : public Base {
24 public:
25 WrappedYuvBuffer(int width,
26 int height,
27 const uint8_t* y_plane,
28 int y_stride,
29 const uint8_t* u_plane,
30 int u_stride,
31 const uint8_t* v_plane,
32 int v_stride,
Niels Möllerf4e3e2b2021-02-02 11:37:39 +010033 std::function<void()> no_longer_used)
yuweih23cc4682017-06-22 20:28:06 -070034 : width_(width),
35 height_(height),
36 y_plane_(y_plane),
37 u_plane_(u_plane),
38 v_plane_(v_plane),
39 y_stride_(y_stride),
40 u_stride_(u_stride),
41 v_stride_(v_stride),
42 no_longer_used_cb_(no_longer_used) {}
43
Emircan Uysaler574eaa42017-11-09 12:33:24 -080044 ~WrappedYuvBuffer() override { no_longer_used_cb_(); }
45
yuweih23cc4682017-06-22 20:28:06 -070046 int width() const override { return width_; }
47
48 int height() const override { return height_; }
49
50 const uint8_t* DataY() const override { return y_plane_; }
51
52 const uint8_t* DataU() const override { return u_plane_; }
53
54 const uint8_t* DataV() const override { return v_plane_; }
55
56 int StrideY() const override { return y_stride_; }
57
58 int StrideU() const override { return u_stride_; }
59
60 int StrideV() const override { return v_stride_; }
61
62 private:
63 friend class rtc::RefCountedObject<WrappedYuvBuffer>;
64
yuweih23cc4682017-06-22 20:28:06 -070065 const int width_;
66 const int height_;
67 const uint8_t* const y_plane_;
68 const uint8_t* const u_plane_;
69 const uint8_t* const v_plane_;
70 const int y_stride_;
71 const int u_stride_;
72 const int v_stride_;
Niels Möllerf4e3e2b2021-02-02 11:37:39 +010073 std::function<void()> no_longer_used_cb_;
yuweih23cc4682017-06-22 20:28:06 -070074};
75
Emircan Uysaler574eaa42017-11-09 12:33:24 -080076// Template to implement a wrapped buffer for a I4??BufferInterface.
77template <typename BaseWithA>
78class WrappedYuvaBuffer : public WrappedYuvBuffer<BaseWithA> {
79 public:
80 WrappedYuvaBuffer(int width,
81 int height,
82 const uint8_t* y_plane,
83 int y_stride,
84 const uint8_t* u_plane,
85 int u_stride,
86 const uint8_t* v_plane,
87 int v_stride,
88 const uint8_t* a_plane,
89 int a_stride,
Niels Möllerf4e3e2b2021-02-02 11:37:39 +010090 std::function<void()> no_longer_used)
Emircan Uysaler574eaa42017-11-09 12:33:24 -080091 : WrappedYuvBuffer<BaseWithA>(width,
92 height,
93 y_plane,
94 y_stride,
95 u_plane,
96 u_stride,
97 v_plane,
98 v_stride,
99 no_longer_used),
100 a_plane_(a_plane),
101 a_stride_(a_stride) {}
102
103 const uint8_t* DataA() const override { return a_plane_; }
104 int StrideA() const override { return a_stride_; }
105
106 private:
107 const uint8_t* const a_plane_;
108 const int a_stride_;
109};
110
Patrik Höglundb5b5bce2017-11-13 10:19:58 +0100111class I444BufferBase : public I444BufferInterface {
112 public:
113 rtc::scoped_refptr<I420BufferInterface> ToI420() final;
114};
115
116rtc::scoped_refptr<I420BufferInterface> I444BufferBase::ToI420() {
117 rtc::scoped_refptr<I420Buffer> i420_buffer =
118 I420Buffer::Create(width(), height());
119 libyuv::I444ToI420(DataY(), StrideY(), DataU(), StrideU(), DataV(), StrideV(),
120 i420_buffer->MutableDataY(), i420_buffer->StrideY(),
121 i420_buffer->MutableDataU(), i420_buffer->StrideU(),
122 i420_buffer->MutableDataV(), i420_buffer->StrideV(),
123 width(), height());
124 return i420_buffer;
125}
126
Sergio Garcia Murillob63536f2022-03-25 09:04:09 +0100127class I422BufferBase : public I422BufferInterface {
128 public:
129 rtc::scoped_refptr<I420BufferInterface> ToI420() final;
130};
131
132rtc::scoped_refptr<I420BufferInterface> I422BufferBase::ToI420() {
133 rtc::scoped_refptr<I420Buffer> i420_buffer =
134 I420Buffer::Create(width(), height());
135 libyuv::I422ToI420(DataY(), StrideY(), DataU(), StrideU(), DataV(), StrideV(),
136 i420_buffer->MutableDataY(), i420_buffer->StrideY(),
137 i420_buffer->MutableDataU(), i420_buffer->StrideU(),
138 i420_buffer->MutableDataV(), i420_buffer->StrideV(),
139 width(), height());
140 return i420_buffer;
141}
142
Emircan Uysaler901e0ff2018-06-26 12:22:38 -0700143// Template to implement a wrapped buffer for a PlanarYuv16BBuffer.
144template <typename Base>
145class WrappedYuv16BBuffer : public Base {
146 public:
147 WrappedYuv16BBuffer(int width,
148 int height,
149 const uint16_t* y_plane,
150 int y_stride,
151 const uint16_t* u_plane,
152 int u_stride,
153 const uint16_t* v_plane,
154 int v_stride,
Niels Möllerf4e3e2b2021-02-02 11:37:39 +0100155 std::function<void()> no_longer_used)
Emircan Uysaler901e0ff2018-06-26 12:22:38 -0700156 : width_(width),
157 height_(height),
158 y_plane_(y_plane),
159 u_plane_(u_plane),
160 v_plane_(v_plane),
161 y_stride_(y_stride),
162 u_stride_(u_stride),
163 v_stride_(v_stride),
164 no_longer_used_cb_(no_longer_used) {}
165
166 ~WrappedYuv16BBuffer() override { no_longer_used_cb_(); }
167
168 int width() const override { return width_; }
169
170 int height() const override { return height_; }
171
172 const uint16_t* DataY() const override { return y_plane_; }
173
174 const uint16_t* DataU() const override { return u_plane_; }
175
176 const uint16_t* DataV() const override { return v_plane_; }
177
178 int StrideY() const override { return y_stride_; }
179
180 int StrideU() const override { return u_stride_; }
181
182 int StrideV() const override { return v_stride_; }
183
184 private:
185 friend class rtc::RefCountedObject<WrappedYuv16BBuffer>;
186
187 const int width_;
188 const int height_;
189 const uint16_t* const y_plane_;
190 const uint16_t* const u_plane_;
191 const uint16_t* const v_plane_;
192 const int y_stride_;
193 const int u_stride_;
194 const int v_stride_;
Niels Möllerf4e3e2b2021-02-02 11:37:39 +0100195 std::function<void()> no_longer_used_cb_;
Emircan Uysaler901e0ff2018-06-26 12:22:38 -0700196};
197
198class I010BufferBase : public I010BufferInterface {
199 public:
200 rtc::scoped_refptr<I420BufferInterface> ToI420() final;
201};
202
203rtc::scoped_refptr<I420BufferInterface> I010BufferBase::ToI420() {
204 rtc::scoped_refptr<I420Buffer> i420_buffer =
205 I420Buffer::Create(width(), height());
206 libyuv::I010ToI420(DataY(), StrideY(), DataU(), StrideU(), DataV(), StrideV(),
207 i420_buffer->MutableDataY(), i420_buffer->StrideY(),
208 i420_buffer->MutableDataU(), i420_buffer->StrideU(),
209 i420_buffer->MutableDataV(), i420_buffer->StrideV(),
210 width(), height());
211 return i420_buffer;
212}
213
Patrik Höglundb5b5bce2017-11-13 10:19:58 +0100214} // namespace
215
yuweih23cc4682017-06-22 20:28:06 -0700216rtc::scoped_refptr<I420BufferInterface> WrapI420Buffer(
217 int width,
218 int height,
219 const uint8_t* y_plane,
220 int y_stride,
221 const uint8_t* u_plane,
222 int u_stride,
223 const uint8_t* v_plane,
224 int v_stride,
Niels Möllerf4e3e2b2021-02-02 11:37:39 +0100225 std::function<void()> no_longer_used) {
yuweih23cc4682017-06-22 20:28:06 -0700226 return rtc::scoped_refptr<I420BufferInterface>(
Tomas Gunnarssonc1d58912021-04-22 19:21:43 +0200227 rtc::make_ref_counted<WrappedYuvBuffer<I420BufferInterface>>(
yuweih23cc4682017-06-22 20:28:06 -0700228 width, height, y_plane, y_stride, u_plane, u_stride, v_plane,
229 v_stride, no_longer_used));
230}
231
Emircan Uysaler574eaa42017-11-09 12:33:24 -0800232rtc::scoped_refptr<I420ABufferInterface> WrapI420ABuffer(
233 int width,
234 int height,
235 const uint8_t* y_plane,
236 int y_stride,
237 const uint8_t* u_plane,
238 int u_stride,
239 const uint8_t* v_plane,
240 int v_stride,
241 const uint8_t* a_plane,
242 int a_stride,
Niels Möllerf4e3e2b2021-02-02 11:37:39 +0100243 std::function<void()> no_longer_used) {
Emircan Uysaler574eaa42017-11-09 12:33:24 -0800244 return rtc::scoped_refptr<I420ABufferInterface>(
Tomas Gunnarssonc1d58912021-04-22 19:21:43 +0200245 rtc::make_ref_counted<WrappedYuvaBuffer<I420ABufferInterface>>(
Emircan Uysaler574eaa42017-11-09 12:33:24 -0800246 width, height, y_plane, y_stride, u_plane, u_stride, v_plane,
247 v_stride, a_plane, a_stride, no_longer_used));
248}
249
Sergio Garcia Murillob63536f2022-03-25 09:04:09 +0100250rtc::scoped_refptr<I422BufferInterface> WrapI422Buffer(
251 int width,
252 int height,
253 const uint8_t* y_plane,
254 int y_stride,
255 const uint8_t* u_plane,
256 int u_stride,
257 const uint8_t* v_plane,
258 int v_stride,
259 std::function<void()> no_longer_used) {
260 return rtc::scoped_refptr<I422BufferBase>(
261 rtc::make_ref_counted<WrappedYuvBuffer<I422BufferBase>>(
262 width, height, y_plane, y_stride, u_plane, u_stride, v_plane,
263 v_stride, no_longer_used));
264}
265
yuweih23cc4682017-06-22 20:28:06 -0700266rtc::scoped_refptr<I444BufferInterface> WrapI444Buffer(
267 int width,
268 int height,
269 const uint8_t* y_plane,
270 int y_stride,
271 const uint8_t* u_plane,
272 int u_stride,
273 const uint8_t* v_plane,
274 int v_stride,
Niels Möllerf4e3e2b2021-02-02 11:37:39 +0100275 std::function<void()> no_longer_used) {
yuweih23cc4682017-06-22 20:28:06 -0700276 return rtc::scoped_refptr<I444BufferInterface>(
Tomas Gunnarssonc1d58912021-04-22 19:21:43 +0200277 rtc::make_ref_counted<WrappedYuvBuffer<I444BufferBase>>(
yuweih23cc4682017-06-22 20:28:06 -0700278 width, height, y_plane, y_stride, u_plane, u_stride, v_plane,
279 v_stride, no_longer_used));
280}
281
282rtc::scoped_refptr<PlanarYuvBuffer> WrapYuvBuffer(
283 VideoFrameBuffer::Type type,
284 int width,
285 int height,
286 const uint8_t* y_plane,
287 int y_stride,
288 const uint8_t* u_plane,
289 int u_stride,
290 const uint8_t* v_plane,
291 int v_stride,
Niels Möllerf4e3e2b2021-02-02 11:37:39 +0100292 std::function<void()> no_longer_used) {
yuweih23cc4682017-06-22 20:28:06 -0700293 switch (type) {
294 case VideoFrameBuffer::Type::kI420:
295 return WrapI420Buffer(width, height, y_plane, y_stride, u_plane, u_stride,
296 v_plane, v_stride, no_longer_used);
Sergio Garcia Murillob63536f2022-03-25 09:04:09 +0100297 case VideoFrameBuffer::Type::kI422:
298 return WrapI422Buffer(width, height, y_plane, y_stride, u_plane, u_stride,
299 v_plane, v_stride, no_longer_used);
yuweih23cc4682017-06-22 20:28:06 -0700300 case VideoFrameBuffer::Type::kI444:
301 return WrapI444Buffer(width, height, y_plane, y_stride, u_plane, u_stride,
302 v_plane, v_stride, no_longer_used);
303 default:
Mirko Bonadei01719fb2020-11-17 14:50:54 +0100304 RTC_CHECK_NOTREACHED();
yuweih23cc4682017-06-22 20:28:06 -0700305 }
306}
307
Emircan Uysaler901e0ff2018-06-26 12:22:38 -0700308rtc::scoped_refptr<I010BufferInterface> WrapI010Buffer(
309 int width,
310 int height,
311 const uint16_t* y_plane,
312 int y_stride,
313 const uint16_t* u_plane,
314 int u_stride,
315 const uint16_t* v_plane,
316 int v_stride,
Niels Möllerf4e3e2b2021-02-02 11:37:39 +0100317 std::function<void()> no_longer_used) {
Emircan Uysaler901e0ff2018-06-26 12:22:38 -0700318 return rtc::scoped_refptr<I010BufferInterface>(
Tomas Gunnarssonc1d58912021-04-22 19:21:43 +0200319 rtc::make_ref_counted<WrappedYuv16BBuffer<I010BufferBase>>(
Emircan Uysaler901e0ff2018-06-26 12:22:38 -0700320 width, height, y_plane, y_stride, u_plane, u_stride, v_plane,
321 v_stride, no_longer_used));
322}
323
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000324} // namespace webrtc