blob: 908c97272d829e0f90b7caf7ea901bee181c2afe [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öm308d1632015-06-02 15:04:23 +020097TextureBuffer::TextureBuffer(void* native_handle,
98 int width,
99 int height,
100 const rtc::Callback0<void>& no_longer_used)
101 : native_handle_(native_handle),
102 width_(width),
103 height_(height),
104 no_longer_used_cb_(no_longer_used) {
Per9b3f56e2015-04-09 13:44:16 +0200105 DCHECK(native_handle != nullptr);
Pere41d7742015-04-07 17:20:48 +0200106 DCHECK_GT(width, 0);
107 DCHECK_GT(height, 0);
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000108}
109
Peter Boström308d1632015-06-02 15:04:23 +0200110TextureBuffer::~TextureBuffer() {
111 no_longer_used_cb_();
112}
113
114int TextureBuffer::width() const {
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000115 return width_;
116}
117
Peter Boström308d1632015-06-02 15:04:23 +0200118int TextureBuffer::height() const {
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000119 return height_;
120}
121
Peter Boström308d1632015-06-02 15:04:23 +0200122const uint8_t* TextureBuffer::data(PlaneType type) const {
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000123 RTC_NOTREACHED(); // Should not be called.
124 return nullptr;
125}
126
Peter Boström308d1632015-06-02 15:04:23 +0200127uint8_t* TextureBuffer::data(PlaneType type) {
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000128 RTC_NOTREACHED(); // Should not be called.
129 return nullptr;
130}
131
Peter Boström308d1632015-06-02 15:04:23 +0200132int TextureBuffer::stride(PlaneType type) const {
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000133 RTC_NOTREACHED(); // Should not be called.
134 return 0;
135}
136
Peter Boström308d1632015-06-02 15:04:23 +0200137void* TextureBuffer::native_handle() const {
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000138 return native_handle_;
139}
140
Peter Boström308d1632015-06-02 15:04:23 +0200141
Per33544192015-04-02 12:30:51 +0200142WrappedI420Buffer::WrappedI420Buffer(int desired_width,
143 int desired_height,
144 int width,
145 int height,
146 const uint8_t* y_plane,
147 int y_stride,
148 const uint8_t* u_plane,
149 int u_stride,
150 const uint8_t* v_plane,
151 int v_stride,
152 const rtc::Callback0<void>& no_longer_used)
153 : width_(desired_width),
154 height_(desired_height),
155 y_plane_(y_plane),
156 u_plane_(u_plane),
157 v_plane_(v_plane),
158 y_stride_(y_stride),
159 u_stride_(u_stride),
160 v_stride_(v_stride),
161 no_longer_used_cb_(no_longer_used) {
162 CHECK(width >= desired_width && height >= desired_height);
163
164 // Center crop to |desired_width| x |desired_height|.
165 // Make sure offset is even so that u/v plane becomes aligned.
166 const int offset_x = ((width - desired_width) / 2) & ~1;
167 const int offset_y = ((height - desired_height) / 2) & ~1;
168 y_plane_ += y_stride_ * offset_y + offset_x;
169 u_plane_ += u_stride_ * (offset_y / 2) + (offset_x / 2);
170 v_plane_ += v_stride_ * (offset_y / 2) + (offset_x / 2);
171}
172
173WrappedI420Buffer::~WrappedI420Buffer() {
174 no_longer_used_cb_();
175}
176
177
178int WrappedI420Buffer::width() const {
179 return width_;
180}
181
182int WrappedI420Buffer::height() const {
183 return height_;
184}
185
186const uint8_t* WrappedI420Buffer::data(PlaneType type) const {
187 switch (type) {
188 case kYPlane:
189 return y_plane_;
190 case kUPlane:
191 return u_plane_;
192 case kVPlane:
193 return v_plane_;
194 default:
195 RTC_NOTREACHED();
196 return nullptr;
197 }
198}
199
200uint8_t* WrappedI420Buffer::data(PlaneType type) {
201 RTC_NOTREACHED();
202 return nullptr;
203}
204
205int WrappedI420Buffer::stride(PlaneType type) const {
206 switch (type) {
207 case kYPlane:
208 return y_stride_;
209 case kUPlane:
210 return u_stride_;
211 case kVPlane:
212 return v_stride_;
213 default:
214 RTC_NOTREACHED();
215 return 0;
216 }
217}
218
Per9b3f56e2015-04-09 13:44:16 +0200219void* WrappedI420Buffer::native_handle() const {
Per33544192015-04-02 12:30:51 +0200220 return nullptr;
221}
222
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000223} // namespace webrtc