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

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: addressing comments on patchset 2 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 a
178 // following alpha plane that is aligned and sized in the same manner as the
Tom Finegan 2013/02/25 22:56:06 How about: YV12A is the same as YV12, but with a
vignesh 2013/02/25 23:33:14 Done.
179 // Y plane.
180
176 size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane), 181 size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane),
177 kFrameSizeAlignment); 182 kFrameSizeAlignment);
178 size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane), 183 size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane),
179 kFrameSizeAlignment); 184 kFrameSizeAlignment);
180 // The *2 here is because some formats (e.g. h264) allow interlaced coding, 185 // 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). 186 // and then the size needs to be a multiple of two macroblocks (vertically).
182 // See libavcodec/utils.c:avcodec_align_dimensions2(). 187 // See libavcodec/utils.c:avcodec_align_dimensions2().
183 size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2); 188 size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2);
184 size_t uv_height = format_ == VideoFrame::YV12 ? y_height / 2 : y_height; 189 size_t uv_height = (format_ == VideoFrame::YV12 ||
190 format_ == VideoFrame::YV12A) ?
191 y_height / 2 : y_height;
185 size_t y_bytes = y_height * y_stride; 192 size_t y_bytes = y_height * y_stride;
186 size_t uv_bytes = uv_height * uv_stride; 193 size_t uv_bytes = uv_height * uv_stride;
194 size_t a_bytes = format_ == VideoFrame::YV12A ? y_bytes : 0;
187 195
188 // The extra line of UV being allocated is because h264 chroma MC 196 // The extra line of UV being allocated is because h264 chroma MC
189 // overreads by one line in some cases, see libavcodec/utils.c: 197 // overreads by one line in some cases, see libavcodec/utils.c:
190 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: 198 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm:
191 // put_h264_chroma_mc4_ssse3(). 199 // put_h264_chroma_mc4_ssse3().
192 uint8* data = reinterpret_cast<uint8*>( 200 uint8* data = reinterpret_cast<uint8*>(
193 base::AlignedAlloc( 201 base::AlignedAlloc(
194 y_bytes + (uv_bytes * 2 + uv_stride) + kFrameSizePadding, 202 y_bytes + (uv_bytes * 2 + uv_stride) + a_bytes + kFrameSizePadding,
195 kFrameAddressAlignment)); 203 kFrameAddressAlignment));
196 no_longer_needed_cb_ = base::Bind(&ReleaseData, data); 204 no_longer_needed_cb_ = base::Bind(&ReleaseData, data);
197 COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0); 205 COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0);
198 data_[VideoFrame::kYPlane] = data; 206 data_[VideoFrame::kYPlane] = data;
199 data_[VideoFrame::kUPlane] = data + y_bytes; 207 data_[VideoFrame::kUPlane] = data + y_bytes;
200 data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes; 208 data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes;
201 strides_[VideoFrame::kYPlane] = y_stride; 209 strides_[VideoFrame::kYPlane] = y_stride;
202 strides_[VideoFrame::kUPlane] = uv_stride; 210 strides_[VideoFrame::kUPlane] = uv_stride;
203 strides_[VideoFrame::kVPlane] = uv_stride; 211 strides_[VideoFrame::kVPlane] = uv_stride;
212 if (format_ == YV12A) {
213 data_[VideoFrame::kAPlane] = data + y_bytes + (2 * uv_bytes);
214 strides_[VideoFrame::kAPlane] = y_stride;
215 }
204 } 216 }
205 217
206 VideoFrame::VideoFrame(VideoFrame::Format format, 218 VideoFrame::VideoFrame(VideoFrame::Format format,
207 const gfx::Size& coded_size, 219 const gfx::Size& coded_size,
208 const gfx::Rect& visible_rect, 220 const gfx::Rect& visible_rect,
209 const gfx::Size& natural_size, 221 const gfx::Size& natural_size,
210 base::TimeDelta timestamp) 222 base::TimeDelta timestamp)
211 : format_(format), 223 : format_(format),
212 coded_size_(coded_size), 224 coded_size_(coded_size),
213 visible_rect_(visible_rect), 225 visible_rect_(visible_rect),
(...skipping 12 matching lines...) Expand all
226 238
227 bool VideoFrame::IsValidPlane(size_t plane) const { 239 bool VideoFrame::IsValidPlane(size_t plane) const {
228 switch (format_) { 240 switch (format_) {
229 case RGB32: 241 case RGB32:
230 return plane == kRGBPlane; 242 return plane == kRGBPlane;
231 243
232 case YV12: 244 case YV12:
233 case YV16: 245 case YV16:
234 return plane == kYPlane || plane == kUPlane || plane == kVPlane; 246 return plane == kYPlane || plane == kUPlane || plane == kVPlane;
235 247
248 case YV12A:
249 return plane == kYPlane || plane == kUPlane || plane == kVPlane ||
250 plane == kAPlane;
Tom Finegan 2013/02/25 22:56:06 Fix indent.
vignesh 2013/02/25 23:33:14 Done.
251
236 case NATIVE_TEXTURE: 252 case NATIVE_TEXTURE:
237 NOTREACHED() << "NATIVE_TEXTUREs don't use plane-related methods!"; 253 NOTREACHED() << "NATIVE_TEXTUREs don't use plane-related methods!";
238 return false; 254 return false;
239 255
240 default: 256 default:
241 break; 257 break;
242 } 258 }
243 259
244 // Intentionally leave out non-production formats. 260 // Intentionally leave out non-production formats.
245 NOTREACHED() << "Unsupported video frame format: " << format_; 261 NOTREACHED() << "Unsupported video frame format: " << format_;
246 return false; 262 return false;
247 } 263 }
248 264
249 int VideoFrame::stride(size_t plane) const { 265 int VideoFrame::stride(size_t plane) const {
250 DCHECK(IsValidPlane(plane)); 266 DCHECK(IsValidPlane(plane));
251 return strides_[plane]; 267 return strides_[plane];
252 } 268 }
253 269
254 int VideoFrame::row_bytes(size_t plane) const { 270 int VideoFrame::row_bytes(size_t plane) const {
255 DCHECK(IsValidPlane(plane)); 271 DCHECK(IsValidPlane(plane));
256 int width = coded_size_.width(); 272 int width = coded_size_.width();
257 switch (format_) { 273 switch (format_) {
258 // 32bpp. 274 // 32bpp.
259 case RGB32: 275 case RGB32:
260 return width * 4; 276 return width * 4;
261 277
262 // Planar, 8bpp. 278 // Planar, 8bpp.
263 case YV12: 279 case YV12:
264 case YV16: 280 case YV16:
265 if (plane == kYPlane) 281 case YV12A:
282 if (plane == kYPlane || plane == kAPlane)
266 return width; 283 return width;
267 return RoundUp(width, 2) / 2; 284 return RoundUp(width, 2) / 2;
268 285
269 default: 286 default:
270 break; 287 break;
271 } 288 }
272 289
273 // Intentionally leave out non-production formats. 290 // Intentionally leave out non-production formats.
274 NOTREACHED() << "Unsupported video frame format: " << format_; 291 NOTREACHED() << "Unsupported video frame format: " << format_;
275 return 0; 292 return 0;
276 } 293 }
277 294
278 int VideoFrame::rows(size_t plane) const { 295 int VideoFrame::rows(size_t plane) const {
279 DCHECK(IsValidPlane(plane)); 296 DCHECK(IsValidPlane(plane));
280 int height = coded_size_.height(); 297 int height = coded_size_.height();
281 switch (format_) { 298 switch (format_) {
282 case RGB32: 299 case RGB32:
283 case YV16: 300 case YV16:
284 return height; 301 return height;
285 302
286 case YV12: 303 case YV12:
287 if (plane == kYPlane) 304 case YV12A:
305 if (plane == kYPlane || plane == kAPlane)
288 return height; 306 return height;
289 return RoundUp(height, 2) / 2; 307 return RoundUp(height, 2) / 2;
290 308
291 default: 309 default:
292 break; 310 break;
293 } 311 }
294 312
295 // Intentionally leave out non-production formats. 313 // Intentionally leave out non-production formats.
296 NOTREACHED() << "Unsupported video frame format: " << format_; 314 NOTREACHED() << "Unsupported video frame format: " << format_;
297 return 0; 315 return 0;
(...skipping 24 matching lines...) Expand all
322 break; 340 break;
323 for (int row = 0; row < rows(plane); ++row) { 341 for (int row = 0; row < rows(plane); ++row) {
324 base::MD5Update(context, base::StringPiece( 342 base::MD5Update(context, base::StringPiece(
325 reinterpret_cast<char*>(data(plane) + stride(plane) * row), 343 reinterpret_cast<char*>(data(plane) + stride(plane) * row),
326 row_bytes(plane))); 344 row_bytes(plane)));
327 } 345 }
328 } 346 }
329 } 347 }
330 348
331 } // namespace media 349 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698