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

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: rebase Created 7 years, 8 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
« no previous file with comments | « media/base/video_frame.h ('k') | media/base/video_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 14 matching lines...) Expand all
25 const gfx::Size& natural_size, 25 const gfx::Size& natural_size,
26 base::TimeDelta timestamp) { 26 base::TimeDelta timestamp) {
27 DCHECK(IsValidConfig(format, coded_size, visible_rect, natural_size)); 27 DCHECK(IsValidConfig(format, coded_size, visible_rect, natural_size));
28 scoped_refptr<VideoFrame> frame(new VideoFrame( 28 scoped_refptr<VideoFrame> frame(new VideoFrame(
29 format, coded_size, visible_rect, natural_size, timestamp)); 29 format, coded_size, visible_rect, natural_size, timestamp));
30 switch (format) { 30 switch (format) {
31 case VideoFrame::RGB32: 31 case VideoFrame::RGB32:
32 frame->AllocateRGB(4u); 32 frame->AllocateRGB(4u);
33 break; 33 break;
34 case VideoFrame::YV12: 34 case VideoFrame::YV12:
35 case VideoFrame::YV12A:
35 case VideoFrame::YV16: 36 case VideoFrame::YV16:
36 frame->AllocateYUV(); 37 frame->AllocateYUV();
37 break; 38 break;
38 default: 39 default:
39 LOG(FATAL) << "Unsupported frame format: " << format; 40 LOG(FATAL) << "Unsupported frame format: " << format;
40 } 41 }
41 return frame; 42 return frame;
42 } 43 }
43 44
44 // static 45 // static
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 case VideoFrame::NATIVE_TEXTURE: 161 case VideoFrame::NATIVE_TEXTURE:
161 #if defined(GOOGLE_TV) 162 #if defined(GOOGLE_TV)
162 case VideoFrame::HOLE: 163 case VideoFrame::HOLE:
163 #endif 164 #endif
164 return 0; 165 return 0;
165 case VideoFrame::RGB32: 166 case VideoFrame::RGB32:
166 return 1; 167 return 1;
167 case VideoFrame::YV12: 168 case VideoFrame::YV12:
168 case VideoFrame::YV16: 169 case VideoFrame::YV16:
169 return 3; 170 return 3;
171 case VideoFrame::YV12A:
172 return 4;
170 case VideoFrame::EMPTY: 173 case VideoFrame::EMPTY:
171 case VideoFrame::I420: 174 case VideoFrame::I420:
172 case VideoFrame::INVALID: 175 case VideoFrame::INVALID:
173 break; 176 break;
174 } 177 }
175 NOTREACHED() << "Unsupported video frame format: " << format; 178 NOTREACHED() << "Unsupported video frame format: " << format;
176 return 0; 179 return 0;
177 } 180 }
178 181
179 static inline size_t RoundUp(size_t value, size_t alignment) { 182 static inline size_t RoundUp(size_t value, size_t alignment) {
(...skipping 17 matching lines...) Expand all
197 strides_[VideoFrame::kRGBPlane] = bytes_per_row; 200 strides_[VideoFrame::kRGBPlane] = bytes_per_row;
198 data_[VideoFrame::kRGBPlane] = reinterpret_cast<uint8*>( 201 data_[VideoFrame::kRGBPlane] = reinterpret_cast<uint8*>(
199 base::AlignedAlloc(bytes_per_row * aligned_height + kFrameSizePadding, 202 base::AlignedAlloc(bytes_per_row * aligned_height + kFrameSizePadding,
200 kFrameAddressAlignment)); 203 kFrameAddressAlignment));
201 no_longer_needed_cb_ = base::Bind(&ReleaseData, data_[VideoFrame::kRGBPlane]); 204 no_longer_needed_cb_ = base::Bind(&ReleaseData, data_[VideoFrame::kRGBPlane]);
202 DCHECK(!(reinterpret_cast<intptr_t>(data_[VideoFrame::kRGBPlane]) & 7)); 205 DCHECK(!(reinterpret_cast<intptr_t>(data_[VideoFrame::kRGBPlane]) & 7));
203 COMPILE_ASSERT(0 == VideoFrame::kRGBPlane, RGB_data_must_be_index_0); 206 COMPILE_ASSERT(0 == VideoFrame::kRGBPlane, RGB_data_must_be_index_0);
204 } 207 }
205 208
206 void VideoFrame::AllocateYUV() { 209 void VideoFrame::AllocateYUV() {
207 DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16); 210 DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 ||
211 format_ == VideoFrame::YV12A);
208 // Align Y rows at least at 16 byte boundaries. The stride for both 212 // Align Y rows at least at 16 byte boundaries. The stride for both
209 // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for 213 // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for
210 // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in 214 // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in
211 // the case of YV12 the strides are identical for the same width surface, but 215 // the case of YV12 the strides are identical for the same width surface, but
212 // the number of bytes allocated for YV12 is 1/2 the amount for U & V as 216 // the number of bytes allocated for YV12 is 1/2 the amount for U & V as
213 // YV16. We also round the height of the surface allocated to be an even 217 // YV16. We also round the height of the surface allocated to be an even
214 // number to avoid any potential of faulting by code that attempts to access 218 // number to avoid any potential of faulting by code that attempts to access
215 // the Y values of the final row, but assumes that the last row of U & V 219 // the Y values of the final row, but assumes that the last row of U & V
216 // applies to a full two rows of Y. 220 // applies to a full two rows of Y. YV12A is the same as YV12, but with an
221 // additional alpha plane that has the same size and alignment as the Y plane.
222
217 size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane), 223 size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane),
218 kFrameSizeAlignment); 224 kFrameSizeAlignment);
219 size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane), 225 size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane),
220 kFrameSizeAlignment); 226 kFrameSizeAlignment);
221 // The *2 here is because some formats (e.g. h264) allow interlaced coding, 227 // The *2 here is because some formats (e.g. h264) allow interlaced coding,
222 // and then the size needs to be a multiple of two macroblocks (vertically). 228 // and then the size needs to be a multiple of two macroblocks (vertically).
223 // See libavcodec/utils.c:avcodec_align_dimensions2(). 229 // See libavcodec/utils.c:avcodec_align_dimensions2().
224 size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2); 230 size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2);
225 size_t uv_height = format_ == VideoFrame::YV12 ? y_height / 2 : y_height; 231 size_t uv_height = (format_ == VideoFrame::YV12 ||
232 format_ == VideoFrame::YV12A) ?
233 y_height / 2 : y_height;
226 size_t y_bytes = y_height * y_stride; 234 size_t y_bytes = y_height * y_stride;
227 size_t uv_bytes = uv_height * uv_stride; 235 size_t uv_bytes = uv_height * uv_stride;
236 size_t a_bytes = format_ == VideoFrame::YV12A ? y_bytes : 0;
228 237
229 // The extra line of UV being allocated is because h264 chroma MC 238 // The extra line of UV being allocated is because h264 chroma MC
230 // overreads by one line in some cases, see libavcodec/utils.c: 239 // overreads by one line in some cases, see libavcodec/utils.c:
231 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: 240 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm:
232 // put_h264_chroma_mc4_ssse3(). 241 // put_h264_chroma_mc4_ssse3().
233 uint8* data = reinterpret_cast<uint8*>( 242 uint8* data = reinterpret_cast<uint8*>(
234 base::AlignedAlloc( 243 base::AlignedAlloc(
235 y_bytes + (uv_bytes * 2 + uv_stride) + kFrameSizePadding, 244 y_bytes + (uv_bytes * 2 + uv_stride) + a_bytes + kFrameSizePadding,
236 kFrameAddressAlignment)); 245 kFrameAddressAlignment));
237 no_longer_needed_cb_ = base::Bind(&ReleaseData, data); 246 no_longer_needed_cb_ = base::Bind(&ReleaseData, data);
238 COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0); 247 COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0);
239 data_[VideoFrame::kYPlane] = data; 248 data_[VideoFrame::kYPlane] = data;
240 data_[VideoFrame::kUPlane] = data + y_bytes; 249 data_[VideoFrame::kUPlane] = data + y_bytes;
241 data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes; 250 data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes;
242 strides_[VideoFrame::kYPlane] = y_stride; 251 strides_[VideoFrame::kYPlane] = y_stride;
243 strides_[VideoFrame::kUPlane] = uv_stride; 252 strides_[VideoFrame::kUPlane] = uv_stride;
244 strides_[VideoFrame::kVPlane] = uv_stride; 253 strides_[VideoFrame::kVPlane] = uv_stride;
254 if (format_ == YV12A) {
255 data_[VideoFrame::kAPlane] = data + y_bytes + (2 * uv_bytes);
256 strides_[VideoFrame::kAPlane] = y_stride;
257 }
245 } 258 }
246 259
247 VideoFrame::VideoFrame(VideoFrame::Format format, 260 VideoFrame::VideoFrame(VideoFrame::Format format,
248 const gfx::Size& coded_size, 261 const gfx::Size& coded_size,
249 const gfx::Rect& visible_rect, 262 const gfx::Rect& visible_rect,
250 const gfx::Size& natural_size, 263 const gfx::Size& natural_size,
251 base::TimeDelta timestamp) 264 base::TimeDelta timestamp)
252 : format_(format), 265 : format_(format),
253 coded_size_(coded_size), 266 coded_size_(coded_size),
254 visible_rect_(visible_rect), 267 visible_rect_(visible_rect),
(...skipping 23 matching lines...) Expand all
278 DCHECK(IsValidPlane(plane)); 291 DCHECK(IsValidPlane(plane));
279 int width = coded_size_.width(); 292 int width = coded_size_.width();
280 switch (format_) { 293 switch (format_) {
281 // 32bpp. 294 // 32bpp.
282 case RGB32: 295 case RGB32:
283 return width * 4; 296 return width * 4;
284 297
285 // Planar, 8bpp. 298 // Planar, 8bpp.
286 case YV12: 299 case YV12:
287 case YV16: 300 case YV16:
288 if (plane == kYPlane) 301 case YV12A:
302 if (plane == kYPlane || plane == kAPlane)
289 return width; 303 return width;
290 return RoundUp(width, 2) / 2; 304 return RoundUp(width, 2) / 2;
291 305
292 default: 306 default:
293 break; 307 break;
294 } 308 }
295 309
296 // Intentionally leave out non-production formats. 310 // Intentionally leave out non-production formats.
297 NOTREACHED() << "Unsupported video frame format: " << format_; 311 NOTREACHED() << "Unsupported video frame format: " << format_;
298 return 0; 312 return 0;
299 } 313 }
300 314
301 int VideoFrame::rows(size_t plane) const { 315 int VideoFrame::rows(size_t plane) const {
302 DCHECK(IsValidPlane(plane)); 316 DCHECK(IsValidPlane(plane));
303 int height = coded_size_.height(); 317 int height = coded_size_.height();
304 switch (format_) { 318 switch (format_) {
305 case RGB32: 319 case RGB32:
306 case YV16: 320 case YV16:
307 return height; 321 return height;
308 322
309 case YV12: 323 case YV12:
310 if (plane == kYPlane) 324 case YV12A:
325 if (plane == kYPlane || plane == kAPlane)
311 return height; 326 return height;
312 return RoundUp(height, 2) / 2; 327 return RoundUp(height, 2) / 2;
313 328
314 default: 329 default:
315 break; 330 break;
316 } 331 }
317 332
318 // Intentionally leave out non-production formats. 333 // Intentionally leave out non-production formats.
319 NOTREACHED() << "Unsupported video frame format: " << format_; 334 NOTREACHED() << "Unsupported video frame format: " << format_;
320 return 0; 335 return 0;
(...skipping 24 matching lines...) Expand all
345 break; 360 break;
346 for (int row = 0; row < rows(plane); ++row) { 361 for (int row = 0; row < rows(plane); ++row) {
347 base::MD5Update(context, base::StringPiece( 362 base::MD5Update(context, base::StringPiece(
348 reinterpret_cast<char*>(data(plane) + stride(plane) * row), 363 reinterpret_cast<char*>(data(plane) + stride(plane) * row),
349 row_bytes(plane))); 364 row_bytes(plane)));
350 } 365 }
351 } 366 }
352 } 367 }
353 368
354 } // namespace media 369 } // namespace media
OLDNEW
« no previous file with comments | « media/base/video_frame.h ('k') | media/base/video_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698