blob: 2cf427ce42de2c853a356f8fd2a4cdda1f0b3aa7 [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 */
10
11#include "webrtc/common_video/interface/video_frame_buffer.h"
12
Per9b3f56e2015-04-09 13:44:16 +020013#include "webrtc/base/bind.h"
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +000014#include "webrtc/base/checks.h"
15
16// Aligning pointer to 64 bytes for improved performance, e.g. use SIMD.
17static const int kBufferAlignment = 64;
18
19namespace webrtc {
20
21VideoFrameBuffer::~VideoFrameBuffer() {}
22
23I420Buffer::I420Buffer(int width, int height)
24 : I420Buffer(width, height, width, (width + 1) / 2, (width + 1) / 2) {
25}
26
27I420Buffer::I420Buffer(int width,
28 int height,
29 int stride_y,
30 int stride_u,
31 int stride_v)
32 : width_(width),
33 height_(height),
34 stride_y_(stride_y),
35 stride_u_(stride_u),
36 stride_v_(stride_v),
37 data_(static_cast<uint8_t*>(AlignedMalloc(
38 stride_y * height + (stride_u + stride_v) * ((height + 1) / 2),
39 kBufferAlignment))) {
40 DCHECK_GT(width, 0);
41 DCHECK_GT(height, 0);
42 DCHECK_GE(stride_y, width);
43 DCHECK_GE(stride_u, (width + 1) / 2);
44 DCHECK_GE(stride_v, (width + 1) / 2);
45}
46
47I420Buffer::~I420Buffer() {
48}
49
50int I420Buffer::width() const {
51 return width_;
52}
53
54int I420Buffer::height() const {
55 return height_;
56}
57
58const uint8_t* I420Buffer::data(PlaneType type) const {
59 switch (type) {
60 case kYPlane:
61 return data_.get();
62 case kUPlane:
63 return data_.get() + stride_y_ * height_;
64 case kVPlane:
65 return data_.get() + stride_y_ * height_ +
66 stride_u_ * ((height_ + 1) / 2);
67 default:
68 RTC_NOTREACHED();
69 return nullptr;
70 }
71}
72
73uint8_t* I420Buffer::data(PlaneType type) {
74 DCHECK(HasOneRef());
75 return const_cast<uint8_t*>(
76 static_cast<const VideoFrameBuffer*>(this)->data(type));
77}
78
79int I420Buffer::stride(PlaneType type) const {
80 switch (type) {
81 case kYPlane:
82 return stride_y_;
83 case kUPlane:
84 return stride_u_;
85 case kVPlane:
86 return stride_v_;
87 default:
88 RTC_NOTREACHED();
89 return 0;
90 }
91}
92
Per9b3f56e2015-04-09 13:44:16 +020093void* I420Buffer::native_handle() const {
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +000094 return nullptr;
95}
96
Peter Boströmeb66e802015-06-05 11:08:03 +020097rtc::scoped_refptr<VideoFrameBuffer> I420Buffer::NativeToI420Buffer() {
98 RTC_NOTREACHED();
99 return nullptr;
100}
101
102NativeHandleBuffer::NativeHandleBuffer(void* native_handle,
103 int width,
104 int height)
105 : native_handle_(native_handle), width_(width), height_(height) {
Per9b3f56e2015-04-09 13:44:16 +0200106 DCHECK(native_handle != nullptr);
Pere41d7742015-04-07 17:20:48 +0200107 DCHECK_GT(width, 0);
108 DCHECK_GT(height, 0);
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000109}
110
Peter Boströmeb66e802015-06-05 11:08:03 +0200111int NativeHandleBuffer::width() const {
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000112 return width_;
113}
114
Peter Boströmeb66e802015-06-05 11:08:03 +0200115int NativeHandleBuffer::height() const {
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000116 return height_;
117}
118
Peter Boströmeb66e802015-06-05 11:08:03 +0200119const uint8_t* NativeHandleBuffer::data(PlaneType type) const {
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000120 RTC_NOTREACHED(); // Should not be called.
121 return nullptr;
122}
123
Peter Boströmeb66e802015-06-05 11:08:03 +0200124uint8_t* NativeHandleBuffer::data(PlaneType type) {
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000125 RTC_NOTREACHED(); // Should not be called.
126 return nullptr;
127}
128
Peter Boströmeb66e802015-06-05 11:08:03 +0200129int NativeHandleBuffer::stride(PlaneType type) const {
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000130 RTC_NOTREACHED(); // Should not be called.
131 return 0;
132}
133
Peter Boströmeb66e802015-06-05 11:08:03 +0200134void* NativeHandleBuffer::native_handle() const {
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000135 return native_handle_;
136}
137
Per33544192015-04-02 12:30:51 +0200138WrappedI420Buffer::WrappedI420Buffer(int desired_width,
139 int desired_height,
140 int width,
141 int height,
142 const uint8_t* y_plane,
143 int y_stride,
144 const uint8_t* u_plane,
145 int u_stride,
146 const uint8_t* v_plane,
147 int v_stride,
148 const rtc::Callback0<void>& no_longer_used)
149 : width_(desired_width),
150 height_(desired_height),
151 y_plane_(y_plane),
152 u_plane_(u_plane),
153 v_plane_(v_plane),
154 y_stride_(y_stride),
155 u_stride_(u_stride),
156 v_stride_(v_stride),
157 no_longer_used_cb_(no_longer_used) {
158 CHECK(width >= desired_width && height >= desired_height);
159
160 // Center crop to |desired_width| x |desired_height|.
161 // Make sure offset is even so that u/v plane becomes aligned.
162 const int offset_x = ((width - desired_width) / 2) & ~1;
163 const int offset_y = ((height - desired_height) / 2) & ~1;
164 y_plane_ += y_stride_ * offset_y + offset_x;
165 u_plane_ += u_stride_ * (offset_y / 2) + (offset_x / 2);
166 v_plane_ += v_stride_ * (offset_y / 2) + (offset_x / 2);
167}
168
169WrappedI420Buffer::~WrappedI420Buffer() {
170 no_longer_used_cb_();
171}
172
173
174int WrappedI420Buffer::width() const {
175 return width_;
176}
177
178int WrappedI420Buffer::height() const {
179 return height_;
180}
181
182const uint8_t* WrappedI420Buffer::data(PlaneType type) const {
183 switch (type) {
184 case kYPlane:
185 return y_plane_;
186 case kUPlane:
187 return u_plane_;
188 case kVPlane:
189 return v_plane_;
190 default:
191 RTC_NOTREACHED();
192 return nullptr;
193 }
194}
195
196uint8_t* WrappedI420Buffer::data(PlaneType type) {
197 RTC_NOTREACHED();
198 return nullptr;
199}
200
201int WrappedI420Buffer::stride(PlaneType type) const {
202 switch (type) {
203 case kYPlane:
204 return y_stride_;
205 case kUPlane:
206 return u_stride_;
207 case kVPlane:
208 return v_stride_;
209 default:
210 RTC_NOTREACHED();
211 return 0;
212 }
213}
214
Per9b3f56e2015-04-09 13:44:16 +0200215void* WrappedI420Buffer::native_handle() const {
Per33544192015-04-02 12:30:51 +0200216 return nullptr;
217}
218
Peter Boströmeb66e802015-06-05 11:08:03 +0200219rtc::scoped_refptr<VideoFrameBuffer> WrappedI420Buffer::NativeToI420Buffer() {
220 RTC_NOTREACHED();
221 return nullptr;
222}
223
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000224} // namespace webrtc