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

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

Issue 22645005: media::VideoFrame::WrapExternalSharedMemory (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@git-svn
Patch Set: 87b7a18a Rebase, added TODO Created 7 years, 4 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
« no previous file with comments | « media/base/video_frame.h ('k') | media/base/video_util.cc » ('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 16 matching lines...) Expand all
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::YV12A:
36 case VideoFrame::YV16: 36 case VideoFrame::YV16:
37 case VideoFrame::I420:
37 frame->AllocateYUV(); 38 frame->AllocateYUV();
38 break; 39 break;
39 default: 40 default:
40 LOG(FATAL) << "Unsupported frame format: " << format; 41 LOG(FATAL) << "Unsupported frame format: " << format;
41 } 42 }
42 return frame; 43 return frame;
43 } 44 }
44 45
45 // static 46 // static
46 std::string VideoFrame::FormatToString(VideoFrame::Format format) { 47 std::string VideoFrame::FormatToString(VideoFrame::Format format) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 return frame; 111 return frame;
111 } 112 }
112 113
113 void VideoFrame::ReadPixelsFromNativeTexture(const SkBitmap& pixels) { 114 void VideoFrame::ReadPixelsFromNativeTexture(const SkBitmap& pixels) {
114 DCHECK_EQ(format_, NATIVE_TEXTURE); 115 DCHECK_EQ(format_, NATIVE_TEXTURE);
115 if (!read_pixels_cb_.is_null()) 116 if (!read_pixels_cb_.is_null())
116 read_pixels_cb_.Run(pixels); 117 read_pixels_cb_.Run(pixels);
117 } 118 }
118 119
119 // static 120 // static
121 scoped_refptr<VideoFrame> VideoFrame::WrapExternalSharedMemory(
122 Format format,
123 const gfx::Size& coded_size,
124 const gfx::Rect& visible_rect,
125 const gfx::Size& natural_size,
126 uint8* data,
127 base::SharedMemoryHandle handle,
128 base::TimeDelta timestamp,
129 const base::Closure& no_longer_needed_cb) {
130 switch (format) {
131 case I420: {
132 scoped_refptr<VideoFrame> frame(new VideoFrame(
133 format, coded_size, visible_rect, natural_size, timestamp));
134 frame->shared_memory_handle_ = handle;
135 frame->strides_[kYPlane] = coded_size.width();
136 frame->strides_[kUPlane] = coded_size.width() / 2;
137 frame->strides_[kVPlane] = coded_size.width() / 2;
138 frame->data_[kYPlane] = data;
139 frame->data_[kUPlane] = data + coded_size.GetArea();
140 frame->data_[kVPlane] = data + (coded_size.GetArea() * 5 / 4);
141 frame->no_longer_needed_cb_ = no_longer_needed_cb;
142 return frame;
143 }
144 default:
145 NOTIMPLEMENTED();
146 return NULL;
147 }
148 }
149
150 // static
120 scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData( 151 scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData(
121 Format format, 152 Format format,
122 const gfx::Size& coded_size, 153 const gfx::Size& coded_size,
123 const gfx::Rect& visible_rect, 154 const gfx::Rect& visible_rect,
124 const gfx::Size& natural_size, 155 const gfx::Size& natural_size,
125 int32 y_stride, int32 u_stride, int32 v_stride, 156 int32 y_stride,
126 uint8* y_data, uint8* u_data, uint8* v_data, 157 int32 u_stride,
158 int32 v_stride,
159 uint8* y_data,
160 uint8* u_data,
161 uint8* v_data,
127 base::TimeDelta timestamp, 162 base::TimeDelta timestamp,
128 base::SharedMemoryHandle shm_handle,
129 const base::Closure& no_longer_needed_cb) { 163 const base::Closure& no_longer_needed_cb) {
130 DCHECK(format == YV12 || format == YV16 || format == I420) << format; 164 DCHECK(format == YV12 || format == YV16 || format == I420) << format;
131 scoped_refptr<VideoFrame> frame(new VideoFrame( 165 scoped_refptr<VideoFrame> frame(new VideoFrame(
132 format, coded_size, visible_rect, natural_size, timestamp)); 166 format, coded_size, visible_rect, natural_size, timestamp));
133 frame->shared_memory_handle_ = shm_handle;
134 frame->strides_[kYPlane] = y_stride; 167 frame->strides_[kYPlane] = y_stride;
135 frame->strides_[kUPlane] = u_stride; 168 frame->strides_[kUPlane] = u_stride;
136 frame->strides_[kVPlane] = v_stride; 169 frame->strides_[kVPlane] = v_stride;
137 frame->data_[kYPlane] = y_data; 170 frame->data_[kYPlane] = y_data;
138 frame->data_[kUPlane] = u_data; 171 frame->data_[kUPlane] = u_data;
139 frame->data_[kVPlane] = v_data; 172 frame->data_[kVPlane] = v_data;
140 frame->no_longer_needed_cb_ = no_longer_needed_cb; 173 frame->no_longer_needed_cb_ = no_longer_needed_cb;
141 return frame; 174 return frame;
142 } 175 }
143 176
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 switch (format) { 224 switch (format) {
192 case VideoFrame::NATIVE_TEXTURE: 225 case VideoFrame::NATIVE_TEXTURE:
193 #if defined(GOOGLE_TV) 226 #if defined(GOOGLE_TV)
194 case VideoFrame::HOLE: 227 case VideoFrame::HOLE:
195 #endif 228 #endif
196 return 0; 229 return 0;
197 case VideoFrame::RGB32: 230 case VideoFrame::RGB32:
198 return 1; 231 return 1;
199 case VideoFrame::YV12: 232 case VideoFrame::YV12:
200 case VideoFrame::YV16: 233 case VideoFrame::YV16:
234 case VideoFrame::I420:
201 return 3; 235 return 3;
202 case VideoFrame::YV12A: 236 case VideoFrame::YV12A:
203 return 4; 237 return 4;
204 case VideoFrame::EMPTY: 238 case VideoFrame::EMPTY:
205 case VideoFrame::I420:
206 case VideoFrame::INVALID: 239 case VideoFrame::INVALID:
207 break; 240 break;
208 } 241 }
209 NOTREACHED() << "Unsupported video frame format: " << format; 242 NOTREACHED() << "Unsupported video frame format: " << format;
210 return 0; 243 return 0;
211 } 244 }
212 245
213 static inline size_t RoundUp(size_t value, size_t alignment) { 246 static inline size_t RoundUp(size_t value, size_t alignment) {
214 // Check that |alignment| is a power of 2. 247 // Check that |alignment| is a power of 2.
215 DCHECK((alignment + (alignment - 1)) == (alignment | (alignment - 1))); 248 DCHECK((alignment + (alignment - 1)) == (alignment | (alignment - 1)));
(...skipping 16 matching lines...) Expand all
232 data_[VideoFrame::kRGBPlane] = reinterpret_cast<uint8*>( 265 data_[VideoFrame::kRGBPlane] = reinterpret_cast<uint8*>(
233 base::AlignedAlloc(bytes_per_row * aligned_height + kFrameSizePadding, 266 base::AlignedAlloc(bytes_per_row * aligned_height + kFrameSizePadding,
234 kFrameAddressAlignment)); 267 kFrameAddressAlignment));
235 no_longer_needed_cb_ = base::Bind(&ReleaseData, data_[VideoFrame::kRGBPlane]); 268 no_longer_needed_cb_ = base::Bind(&ReleaseData, data_[VideoFrame::kRGBPlane]);
236 DCHECK(!(reinterpret_cast<intptr_t>(data_[VideoFrame::kRGBPlane]) & 7)); 269 DCHECK(!(reinterpret_cast<intptr_t>(data_[VideoFrame::kRGBPlane]) & 7));
237 COMPILE_ASSERT(0 == VideoFrame::kRGBPlane, RGB_data_must_be_index_0); 270 COMPILE_ASSERT(0 == VideoFrame::kRGBPlane, RGB_data_must_be_index_0);
238 } 271 }
239 272
240 void VideoFrame::AllocateYUV() { 273 void VideoFrame::AllocateYUV() {
241 DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 || 274 DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 ||
242 format_ == VideoFrame::YV12A); 275 format_ == VideoFrame::YV12A || format_ == VideoFrame::I420);
243 // Align Y rows at least at 16 byte boundaries. The stride for both 276 // Align Y rows at least at 16 byte boundaries. The stride for both
244 // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for 277 // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for
245 // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in 278 // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in
246 // the case of YV12 the strides are identical for the same width surface, but 279 // the case of YV12 the strides are identical for the same width surface, but
247 // the number of bytes allocated for YV12 is 1/2 the amount for U & V as 280 // the number of bytes allocated for YV12 is 1/2 the amount for U & V as
248 // YV16. We also round the height of the surface allocated to be an even 281 // YV16. We also round the height of the surface allocated to be an even
249 // number to avoid any potential of faulting by code that attempts to access 282 // number to avoid any potential of faulting by code that attempts to access
250 // the Y values of the final row, but assumes that the last row of U & V 283 // the Y values of the final row, but assumes that the last row of U & V
251 // applies to a full two rows of Y. YV12A is the same as YV12, but with an 284 // applies to a full two rows of Y. YV12A is the same as YV12, but with an
252 // additional alpha plane that has the same size and alignment as the Y plane. 285 // additional alpha plane that has the same size and alignment as the Y plane.
253 286
254 size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane), 287 size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane),
255 kFrameSizeAlignment); 288 kFrameSizeAlignment);
256 size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane), 289 size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane),
257 kFrameSizeAlignment); 290 kFrameSizeAlignment);
258 // The *2 here is because some formats (e.g. h264) allow interlaced coding, 291 // The *2 here is because some formats (e.g. h264) allow interlaced coding,
259 // and then the size needs to be a multiple of two macroblocks (vertically). 292 // and then the size needs to be a multiple of two macroblocks (vertically).
260 // See libavcodec/utils.c:avcodec_align_dimensions2(). 293 // See libavcodec/utils.c:avcodec_align_dimensions2().
261 size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2); 294 size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2);
262 size_t uv_height = (format_ == VideoFrame::YV12 || 295 size_t uv_height =
263 format_ == VideoFrame::YV12A) ? 296 (format_ == VideoFrame::YV12 || format_ == VideoFrame::YV12A ||
264 y_height / 2 : y_height; 297 format_ == VideoFrame::I420)
298 ? y_height / 2
299 : y_height;
265 size_t y_bytes = y_height * y_stride; 300 size_t y_bytes = y_height * y_stride;
266 size_t uv_bytes = uv_height * uv_stride; 301 size_t uv_bytes = uv_height * uv_stride;
267 size_t a_bytes = format_ == VideoFrame::YV12A ? y_bytes : 0; 302 size_t a_bytes = format_ == VideoFrame::YV12A ? y_bytes : 0;
268 303
269 // The extra line of UV being allocated is because h264 chroma MC 304 // The extra line of UV being allocated is because h264 chroma MC
270 // overreads by one line in some cases, see libavcodec/utils.c: 305 // overreads by one line in some cases, see libavcodec/utils.c:
271 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: 306 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm:
272 // put_h264_chroma_mc4_ssse3(). 307 // put_h264_chroma_mc4_ssse3().
273 uint8* data = reinterpret_cast<uint8*>( 308 uint8* data = reinterpret_cast<uint8*>(
274 base::AlignedAlloc( 309 base::AlignedAlloc(
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 355
321 int VideoFrame::row_bytes(size_t plane) const { 356 int VideoFrame::row_bytes(size_t plane) const {
322 DCHECK(IsValidPlane(plane)); 357 DCHECK(IsValidPlane(plane));
323 int width = coded_size_.width(); 358 int width = coded_size_.width();
324 switch (format_) { 359 switch (format_) {
325 // 32bpp. 360 // 32bpp.
326 case RGB32: 361 case RGB32:
327 return width * 4; 362 return width * 4;
328 363
329 // Planar, 8bpp. 364 // Planar, 8bpp.
365 case YV12A:
366 if (plane == kAPlane)
367 return width;
368 // Fallthrough.
330 case YV12: 369 case YV12:
331 case YV16: 370 case YV16:
332 case YV12A: 371 case I420:
333 if (plane == kYPlane || plane == kAPlane) 372 if (plane == kYPlane)
334 return width; 373 return width;
335 return RoundUp(width, 2) / 2; 374 return RoundUp(width, 2) / 2;
336 375
337 default: 376 default:
338 break; 377 break;
339 } 378 }
340 379
341 // Intentionally leave out non-production formats. 380 // Intentionally leave out non-production formats.
342 NOTREACHED() << "Unsupported video frame format: " << format_; 381 NOTREACHED() << "Unsupported video frame format: " << format_;
343 return 0; 382 return 0;
344 } 383 }
345 384
346 int VideoFrame::rows(size_t plane) const { 385 int VideoFrame::rows(size_t plane) const {
347 DCHECK(IsValidPlane(plane)); 386 DCHECK(IsValidPlane(plane));
348 int height = coded_size_.height(); 387 int height = coded_size_.height();
349 switch (format_) { 388 switch (format_) {
350 case RGB32: 389 case RGB32:
351 case YV16: 390 case YV16:
352 return height; 391 return height;
353 392
393 case YV12A:
394 if (plane == kAPlane)
395 return height;
396 // Fallthrough.
354 case YV12: 397 case YV12:
355 case YV12A: 398 case I420:
356 if (plane == kYPlane || plane == kAPlane) 399 if (plane == kYPlane)
357 return height; 400 return height;
358 return RoundUp(height, 2) / 2; 401 return RoundUp(height, 2) / 2;
359 402
360 default: 403 default:
361 break; 404 break;
362 } 405 }
363 406
364 // Intentionally leave out non-production formats. 407 // Intentionally leave out non-production formats.
365 NOTREACHED() << "Unsupported video frame format: " << format_; 408 NOTREACHED() << "Unsupported video frame format: " << format_;
366 return 0; 409 return 0;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 : mailbox_(mailbox), 452 : mailbox_(mailbox),
410 sync_point_(sync_point), 453 sync_point_(sync_point),
411 release_callback_(release_callback) {} 454 release_callback_(release_callback) {}
412 455
413 VideoFrame::MailboxHolder::~MailboxHolder() { 456 VideoFrame::MailboxHolder::~MailboxHolder() {
414 if (!release_callback_.is_null()) 457 if (!release_callback_.is_null())
415 release_callback_.Run(sync_point_); 458 release_callback_.Run(sync_point_);
416 } 459 }
417 460
418 } // namespace media 461 } // namespace media
OLDNEW
« no previous file with comments | « media/base/video_frame.h ('k') | media/base/video_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698