Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: media/base/video_frame.cc

Issue 12263013: media: Add support for playback of VP8 Alpha video streams (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: minor nit fixes Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/base/video_frame.h" 5 #include "media/base/video_frame.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 13 matching lines...) Expand all
24 const gfx::Size& natural_size, 24 const gfx::Size& natural_size,
25 base::TimeDelta timestamp) { 25 base::TimeDelta timestamp) {
26 DCHECK(IsValidConfig(format, coded_size, visible_rect, natural_size)); 26 DCHECK(IsValidConfig(format, coded_size, visible_rect, natural_size));
27 scoped_refptr<VideoFrame> frame(new VideoFrame( 27 scoped_refptr<VideoFrame> frame(new VideoFrame(
28 format, coded_size, visible_rect, natural_size, timestamp)); 28 format, coded_size, visible_rect, natural_size, timestamp));
29 switch (format) { 29 switch (format) {
30 case VideoFrame::RGB32: 30 case VideoFrame::RGB32:
31 frame->AllocateRGB(4u); 31 frame->AllocateRGB(4u);
32 break; 32 break;
33 case VideoFrame::YV12: 33 case VideoFrame::YV12:
34 case VideoFrame::YV12A:
34 case VideoFrame::YV16: 35 case VideoFrame::YV16:
35 frame->AllocateYUV(); 36 frame->AllocateYUV();
36 break; 37 break;
37 default: 38 default:
38 LOG(FATAL) << "Unsupported frame format: " << format; 39 LOG(FATAL) << "Unsupported frame format: " << format;
39 } 40 }
40 return frame; 41 return frame;
41 } 42 }
42 43
43 // static 44 // static
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 strides_[VideoFrame::kRGBPlane] = bytes_per_row; 157 strides_[VideoFrame::kRGBPlane] = bytes_per_row;
157 data_[VideoFrame::kRGBPlane] = reinterpret_cast<uint8*>( 158 data_[VideoFrame::kRGBPlane] = reinterpret_cast<uint8*>(
158 base::AlignedAlloc(bytes_per_row * aligned_height + kFrameSizePadding, 159 base::AlignedAlloc(bytes_per_row * aligned_height + kFrameSizePadding,
159 kFrameAddressAlignment)); 160 kFrameAddressAlignment));
160 no_longer_needed_cb_ = base::Bind(&ReleaseData, data_[VideoFrame::kRGBPlane]); 161 no_longer_needed_cb_ = base::Bind(&ReleaseData, data_[VideoFrame::kRGBPlane]);
161 DCHECK(!(reinterpret_cast<intptr_t>(data_[VideoFrame::kRGBPlane]) & 7)); 162 DCHECK(!(reinterpret_cast<intptr_t>(data_[VideoFrame::kRGBPlane]) & 7));
162 COMPILE_ASSERT(0 == VideoFrame::kRGBPlane, RGB_data_must_be_index_0); 163 COMPILE_ASSERT(0 == VideoFrame::kRGBPlane, RGB_data_must_be_index_0);
163 } 164 }
164 165
165 void VideoFrame::AllocateYUV() { 166 void VideoFrame::AllocateYUV() {
166 DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16); 167 DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 ||
168 format_ == VideoFrame::YV12A);
167 // Align Y rows at least at 16 byte boundaries. The stride for both 169 // Align Y rows at least at 16 byte boundaries. The stride for both
168 // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for 170 // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for
169 // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in 171 // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in
170 // the case of YV12 the strides are identical for the same width surface, but 172 // the case of YV12 the strides are identical for the same width surface, but
171 // the number of bytes allocated for YV12 is 1/2 the amount for U & V as 173 // the number of bytes allocated for YV12 is 1/2 the amount for U & V as
172 // YV16. We also round the height of the surface allocated to be an even 174 // YV16. We also round the height of the surface allocated to be an even
173 // number to avoid any potential of faulting by code that attempts to access 175 // number to avoid any potential of faulting by code that attempts to access
174 // the Y values of the final row, but assumes that the last row of U & V 176 // the Y values of the final row, but assumes that the last row of U & V
175 // applies to a full two rows of Y. 177 // applies to a full two rows of Y. YV12A is the same as YV12, but with an
178 // additional alpha plane that has the same size and alignment as the Y plane.
179
176 size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane), 180 size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane),
177 kFrameSizeAlignment); 181 kFrameSizeAlignment);
178 size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane), 182 size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane),
179 kFrameSizeAlignment); 183 kFrameSizeAlignment);
180 // The *2 here is because some formats (e.g. h264) allow interlaced coding, 184 // The *2 here is because some formats (e.g. h264) allow interlaced coding,
181 // and then the size needs to be a multiple of two macroblocks (vertically). 185 // and then the size needs to be a multiple of two macroblocks (vertically).
182 // See libavcodec/utils.c:avcodec_align_dimensions2(). 186 // See libavcodec/utils.c:avcodec_align_dimensions2().
183 size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2); 187 size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2);
184 size_t uv_height = format_ == VideoFrame::YV12 ? y_height / 2 : y_height; 188 size_t uv_height = (format_ == VideoFrame::YV12 ||
189 format_ == VideoFrame::YV12A) ?
190 y_height / 2 : y_height;
185 size_t y_bytes = y_height * y_stride; 191 size_t y_bytes = y_height * y_stride;
186 size_t uv_bytes = uv_height * uv_stride; 192 size_t uv_bytes = uv_height * uv_stride;
193 size_t a_bytes = format_ == VideoFrame::YV12A ? y_bytes : 0;
187 194
188 // The extra line of UV being allocated is because h264 chroma MC 195 // The extra line of UV being allocated is because h264 chroma MC
189 // overreads by one line in some cases, see libavcodec/utils.c: 196 // overreads by one line in some cases, see libavcodec/utils.c:
190 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: 197 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm:
191 // put_h264_chroma_mc4_ssse3(). 198 // put_h264_chroma_mc4_ssse3().
192 uint8* data = reinterpret_cast<uint8*>( 199 uint8* data = reinterpret_cast<uint8*>(
193 base::AlignedAlloc( 200 base::AlignedAlloc(
194 y_bytes + (uv_bytes * 2 + uv_stride) + kFrameSizePadding, 201 y_bytes + (uv_bytes * 2 + uv_stride) + a_bytes + kFrameSizePadding,
195 kFrameAddressAlignment)); 202 kFrameAddressAlignment));
196 no_longer_needed_cb_ = base::Bind(&ReleaseData, data); 203 no_longer_needed_cb_ = base::Bind(&ReleaseData, data);
197 COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0); 204 COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0);
198 data_[VideoFrame::kYPlane] = data; 205 data_[VideoFrame::kYPlane] = data;
199 data_[VideoFrame::kUPlane] = data + y_bytes; 206 data_[VideoFrame::kUPlane] = data + y_bytes;
200 data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes; 207 data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes;
201 strides_[VideoFrame::kYPlane] = y_stride; 208 strides_[VideoFrame::kYPlane] = y_stride;
202 strides_[VideoFrame::kUPlane] = uv_stride; 209 strides_[VideoFrame::kUPlane] = uv_stride;
203 strides_[VideoFrame::kVPlane] = uv_stride; 210 strides_[VideoFrame::kVPlane] = uv_stride;
211 if (format_ == YV12A) {
212 data_[VideoFrame::kAPlane] = data + y_bytes + (2 * uv_bytes);
213 strides_[VideoFrame::kAPlane] = y_stride;
214 }
204 } 215 }
205 216
206 VideoFrame::VideoFrame(VideoFrame::Format format, 217 VideoFrame::VideoFrame(VideoFrame::Format format,
207 const gfx::Size& coded_size, 218 const gfx::Size& coded_size,
208 const gfx::Rect& visible_rect, 219 const gfx::Rect& visible_rect,
209 const gfx::Size& natural_size, 220 const gfx::Size& natural_size,
210 base::TimeDelta timestamp) 221 base::TimeDelta timestamp)
211 : format_(format), 222 : format_(format),
212 coded_size_(coded_size), 223 coded_size_(coded_size),
213 visible_rect_(visible_rect), 224 visible_rect_(visible_rect),
(...skipping 12 matching lines...) Expand all
226 237
227 bool VideoFrame::IsValidPlane(size_t plane) const { 238 bool VideoFrame::IsValidPlane(size_t plane) const {
228 switch (format_) { 239 switch (format_) {
229 case RGB32: 240 case RGB32:
230 return plane == kRGBPlane; 241 return plane == kRGBPlane;
231 242
232 case YV12: 243 case YV12:
233 case YV16: 244 case YV16:
234 return plane == kYPlane || plane == kUPlane || plane == kVPlane; 245 return plane == kYPlane || plane == kUPlane || plane == kVPlane;
235 246
247 case YV12A:
248 return plane == kYPlane || plane == kUPlane || plane == kVPlane ||
249 plane == kAPlane;
250
236 case NATIVE_TEXTURE: 251 case NATIVE_TEXTURE:
237 NOTREACHED() << "NATIVE_TEXTUREs don't use plane-related methods!"; 252 NOTREACHED() << "NATIVE_TEXTUREs don't use plane-related methods!";
238 return false; 253 return false;
239 254
240 default: 255 default:
241 break; 256 break;
242 } 257 }
243 258
244 // Intentionally leave out non-production formats. 259 // Intentionally leave out non-production formats.
245 NOTREACHED() << "Unsupported video frame format: " << format_; 260 NOTREACHED() << "Unsupported video frame format: " << format_;
246 return false; 261 return false;
247 } 262 }
248 263
249 int VideoFrame::stride(size_t plane) const { 264 int VideoFrame::stride(size_t plane) const {
250 DCHECK(IsValidPlane(plane)); 265 DCHECK(IsValidPlane(plane));
251 return strides_[plane]; 266 return strides_[plane];
252 } 267 }
253 268
254 int VideoFrame::row_bytes(size_t plane) const { 269 int VideoFrame::row_bytes(size_t plane) const {
255 DCHECK(IsValidPlane(plane)); 270 DCHECK(IsValidPlane(plane));
256 int width = coded_size_.width(); 271 int width = coded_size_.width();
257 switch (format_) { 272 switch (format_) {
258 // 32bpp. 273 // 32bpp.
259 case RGB32: 274 case RGB32:
260 return width * 4; 275 return width * 4;
261 276
262 // Planar, 8bpp. 277 // Planar, 8bpp.
263 case YV12: 278 case YV12:
264 case YV16: 279 case YV16:
265 if (plane == kYPlane) 280 case YV12A:
281 if (plane == kYPlane || plane == kAPlane)
266 return width; 282 return width;
267 return RoundUp(width, 2) / 2; 283 return RoundUp(width, 2) / 2;
268 284
269 default: 285 default:
270 break; 286 break;
271 } 287 }
272 288
273 // Intentionally leave out non-production formats. 289 // Intentionally leave out non-production formats.
274 NOTREACHED() << "Unsupported video frame format: " << format_; 290 NOTREACHED() << "Unsupported video frame format: " << format_;
275 return 0; 291 return 0;
276 } 292 }
277 293
278 int VideoFrame::rows(size_t plane) const { 294 int VideoFrame::rows(size_t plane) const {
279 DCHECK(IsValidPlane(plane)); 295 DCHECK(IsValidPlane(plane));
280 int height = coded_size_.height(); 296 int height = coded_size_.height();
281 switch (format_) { 297 switch (format_) {
282 case RGB32: 298 case RGB32:
283 case YV16: 299 case YV16:
284 return height; 300 return height;
285 301
286 case YV12: 302 case YV12:
287 if (plane == kYPlane) 303 case YV12A:
304 if (plane == kYPlane || plane == kAPlane)
288 return height; 305 return height;
289 return RoundUp(height, 2) / 2; 306 return RoundUp(height, 2) / 2;
290 307
291 default: 308 default:
292 break; 309 break;
293 } 310 }
294 311
295 // Intentionally leave out non-production formats. 312 // Intentionally leave out non-production formats.
296 NOTREACHED() << "Unsupported video frame format: " << format_; 313 NOTREACHED() << "Unsupported video frame format: " << format_;
297 return 0; 314 return 0;
(...skipping 24 matching lines...) Expand all
322 break; 339 break;
323 for (int row = 0; row < rows(plane); ++row) { 340 for (int row = 0; row < rows(plane); ++row) {
324 base::MD5Update(context, base::StringPiece( 341 base::MD5Update(context, base::StringPiece(
325 reinterpret_cast<char*>(data(plane) + stride(plane) * row), 342 reinterpret_cast<char*>(data(plane) + stride(plane) * row),
326 row_bytes(plane))); 343 row_bytes(plane)));
327 } 344 }
328 } 345 }
329 } 346 }
330 347
331 } // namespace media 348 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698