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

Side by Side Diff: media/video/gpu_memory_buffer_video_frame_pool.cc

Issue 1304843005: Deal with AllocateGpuMemoryBuffer returning null. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address reveman's nits. Created 5 years, 3 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/video/gpu_memory_buffer_video_frame_pool.h" 5 #include "media/video/gpu_memory_buffer_video_frame_pool.h"
6 6
7 #include <GLES2/gl2.h> 7 #include <GLES2/gl2.h>
8 #include <GLES2/gl2ext.h> 8 #include <GLES2/gl2ext.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 void CopyRowsToI420Buffer(int first_row, 219 void CopyRowsToI420Buffer(int first_row,
220 int rows, 220 int rows,
221 int bytes_per_row, 221 int bytes_per_row,
222 const uint8* source, 222 const uint8* source,
223 int source_stride, 223 int source_stride,
224 uint8* output, 224 uint8* output,
225 int dest_stride, 225 int dest_stride,
226 const base::Closure& done) { 226 const base::Closure& done) {
227 TRACE_EVENT2("media", "CopyRowsToI420Buffer", "bytes_per_row", bytes_per_row, 227 TRACE_EVENT2("media", "CopyRowsToI420Buffer", "bytes_per_row", bytes_per_row,
228 "rows", rows); 228 "rows", rows);
229 DCHECK_NE(dest_stride, 0); 229 if (output) {
230 DCHECK_LE(bytes_per_row, std::abs(dest_stride)); 230 DCHECK_NE(dest_stride, 0);
231 DCHECK_LE(bytes_per_row, source_stride); 231 DCHECK_LE(bytes_per_row, std::abs(dest_stride));
232 for (int row = first_row; row < first_row + rows; ++row) { 232 DCHECK_LE(bytes_per_row, source_stride);
233 memcpy(output + dest_stride * row, source + source_stride * row, 233 for (int row = first_row; row < first_row + rows; ++row) {
234 bytes_per_row); 234 memcpy(output + dest_stride * row, source + source_stride * row,
235 bytes_per_row);
236 }
235 } 237 }
236 done.Run(); 238 done.Run();
237 } 239 }
238 240
239 void CopyRowsToNV12Buffer(int first_row, 241 void CopyRowsToNV12Buffer(int first_row,
240 int rows, 242 int rows,
241 int bytes_per_row, 243 int bytes_per_row,
242 const scoped_refptr<VideoFrame>& source_frame, 244 const scoped_refptr<VideoFrame>& source_frame,
243 uint8* dest_y, 245 uint8* dest_y,
244 int dest_stride_y, 246 int dest_stride_y,
245 uint8* dest_uv, 247 uint8* dest_uv,
246 int dest_stride_uv, 248 int dest_stride_uv,
247 const base::Closure& done) { 249 const base::Closure& done) {
248 TRACE_EVENT2("media", "CopyRowsToNV12Buffer", "bytes_per_row", bytes_per_row, 250 TRACE_EVENT2("media", "CopyRowsToNV12Buffer", "bytes_per_row", bytes_per_row,
249 "rows", rows); 251 "rows", rows);
250 DCHECK_NE(dest_stride_y, 0); 252 if (dest_y && dest_uv) {
251 DCHECK_NE(dest_stride_uv, 0); 253 DCHECK_NE(dest_stride_y, 0);
252 DCHECK_LE(bytes_per_row, std::abs(dest_stride_y)); 254 DCHECK_NE(dest_stride_uv, 0);
253 DCHECK_LE(bytes_per_row, std::abs(dest_stride_uv)); 255 DCHECK_LE(bytes_per_row, std::abs(dest_stride_y));
254 DCHECK_EQ(0, first_row % 2); 256 DCHECK_LE(bytes_per_row, std::abs(dest_stride_uv));
255 libyuv::I420ToNV12( 257 DCHECK_EQ(0, first_row % 2);
256 source_frame->data(VideoFrame::kYPlane) + 258
257 first_row * source_frame->stride(VideoFrame::kYPlane), 259 libyuv::I420ToNV12(
258 source_frame->stride(VideoFrame::kYPlane), 260 source_frame->data(VideoFrame::kYPlane) +
259 source_frame->data(VideoFrame::kUPlane) + 261 first_row * source_frame->stride(VideoFrame::kYPlane),
260 first_row / 2 * source_frame->stride(VideoFrame::kUPlane), 262 source_frame->stride(VideoFrame::kYPlane),
261 source_frame->stride(VideoFrame::kUPlane), 263 source_frame->data(VideoFrame::kUPlane) +
262 source_frame->data(VideoFrame::kVPlane) + 264 first_row / 2 * source_frame->stride(VideoFrame::kUPlane),
263 first_row / 2 * source_frame->stride(VideoFrame::kVPlane), 265 source_frame->stride(VideoFrame::kUPlane),
264 source_frame->stride(VideoFrame::kVPlane), 266 source_frame->data(VideoFrame::kVPlane) +
265 dest_y + first_row * dest_stride_y, dest_stride_y, 267 first_row / 2 * source_frame->stride(VideoFrame::kVPlane),
266 dest_uv + first_row / 2 * dest_stride_uv, dest_stride_uv, 268 source_frame->stride(VideoFrame::kVPlane),
267 bytes_per_row, rows); 269 dest_y + first_row * dest_stride_y, dest_stride_y,
270 dest_uv + first_row / 2 * dest_stride_uv, dest_stride_uv, bytes_per_row,
271 rows);
272 }
268 done.Run(); 273 done.Run();
269 } 274 }
270 275
271 void CopyRowsToUYVYBuffer(int first_row, 276 void CopyRowsToUYVYBuffer(int first_row,
272 int rows, 277 int rows,
273 int width, 278 int width,
274 const scoped_refptr<VideoFrame>& source_frame, 279 const scoped_refptr<VideoFrame>& source_frame,
275 uint8* output, 280 uint8* output,
276 int dest_stride, 281 int dest_stride,
277 const base::Closure& done) { 282 const base::Closure& done) {
278 TRACE_EVENT2("media", "CopyRowsToUYVYBuffer", "bytes_per_row", width * 2, 283 TRACE_EVENT2("media", "CopyRowsToUYVYBuffer", "bytes_per_row", width * 2,
279 "rows", rows); 284 "rows", rows);
280 DCHECK_NE(dest_stride, 0); 285 if (output) {
281 DCHECK_LE(width, std::abs(dest_stride / 2)); 286 DCHECK_NE(dest_stride, 0);
282 DCHECK_EQ(0, first_row % 2); 287 DCHECK_LE(width, std::abs(dest_stride / 2));
283 libyuv::I420ToUYVY( 288 DCHECK_EQ(0, first_row % 2);
284 source_frame->data(VideoFrame::kYPlane) + 289 libyuv::I420ToUYVY(
285 first_row * source_frame->stride(VideoFrame::kYPlane), 290 source_frame->data(VideoFrame::kYPlane) +
286 source_frame->stride(VideoFrame::kYPlane), 291 first_row * source_frame->stride(VideoFrame::kYPlane),
287 source_frame->data(VideoFrame::kUPlane) + 292 source_frame->stride(VideoFrame::kYPlane),
288 first_row / 2 * source_frame->stride(VideoFrame::kUPlane), 293 source_frame->data(VideoFrame::kUPlane) +
289 source_frame->stride(VideoFrame::kUPlane), 294 first_row / 2 * source_frame->stride(VideoFrame::kUPlane),
290 source_frame->data(VideoFrame::kVPlane) + 295 source_frame->stride(VideoFrame::kUPlane),
291 first_row / 2 * source_frame->stride(VideoFrame::kVPlane), 296 source_frame->data(VideoFrame::kVPlane) +
292 source_frame->stride(VideoFrame::kVPlane), 297 first_row / 2 * source_frame->stride(VideoFrame::kVPlane),
293 output + first_row * dest_stride, dest_stride, width, rows); 298 source_frame->stride(VideoFrame::kVPlane),
299 output + first_row * dest_stride, dest_stride, width, rows);
300 }
294 done.Run(); 301 done.Run();
295 } 302 }
296 303
297 } // unnamed namespace 304 } // unnamed namespace
298 305
299 // Creates a VideoFrame backed by native textures starting from a software 306 // Creates a VideoFrame backed by native textures starting from a software
300 // VideoFrame. 307 // VideoFrame.
301 // The data contained in |video_frame| is copied into the VideoFrame passed to 308 // The data contained in |video_frame| is copied into the VideoFrame passed to
302 // |frame_ready_cb|. 309 // |frame_ready_cb|.
303 // This has to be called on the thread where |media_task_runner_| is current. 310 // This has to be called on the thread where |media_task_runner_| is current.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 frame_ready_cb.Run(video_frame); 348 frame_ready_cb.Run(video_frame);
342 return; 349 return;
343 } 350 }
344 351
345 DCHECK(video_frame->visible_rect().origin().IsOrigin()); 352 DCHECK(video_frame->visible_rect().origin().IsOrigin());
346 const gfx::Size size = video_frame->visible_rect().size(); 353 const gfx::Size size = video_frame->visible_rect().size();
347 354
348 // Acquire resources. Incompatible ones will be dropped from the pool. 355 // Acquire resources. Incompatible ones will be dropped from the pool.
349 FrameResources* frame_resources = 356 FrameResources* frame_resources =
350 GetOrCreateFrameResources(size, output_format_); 357 GetOrCreateFrameResources(size, output_format_);
351 if (!frame_resources) { 358 if (!frame_resources) {
DaleCurtis 2015/09/13 18:48:47 I don't understand how this crashed before? Should
Daniele Castagna 2015/09/13 19:31:06 What I think was happening before is the frame_res
352 frame_ready_cb.Run(video_frame); 359 frame_ready_cb.Run(video_frame);
353 return; 360 return;
354 } 361 }
355 362
356 worker_task_runner_->PostTask( 363 worker_task_runner_->PostTask(
357 FROM_HERE, base::Bind(&PoolImpl::CopyVideoFrameToGpuMemoryBuffers, this, 364 FROM_HERE, base::Bind(&PoolImpl::CopyVideoFrameToGpuMemoryBuffers, this,
358 video_frame, frame_resources, frame_ready_cb)); 365 video_frame, frame_resources, frame_ready_cb));
359 } 366 }
360 367
361 void GpuMemoryBufferVideoFramePool::PoolImpl::OnCopiesDone( 368 void GpuMemoryBufferVideoFramePool::PoolImpl::OnCopiesDone(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 } 401 }
395 base::Closure copies_done = 402 base::Closure copies_done =
396 base::Bind(&PoolImpl::OnCopiesDone, this, video_frame, frame_resources, 403 base::Bind(&PoolImpl::OnCopiesDone, this, video_frame, frame_resources,
397 frame_ready_cb); 404 frame_ready_cb);
398 base::Closure barrier = base::BarrierClosure(copies, copies_done); 405 base::Closure barrier = base::BarrierClosure(copies, copies_done);
399 406
400 // Post all the async tasks. 407 // Post all the async tasks.
401 for (size_t i = 0; i < num_planes; i += planes_per_copy) { 408 for (size_t i = 0; i < num_planes; i += planes_per_copy) {
402 gfx::GpuMemoryBuffer* buffer = 409 gfx::GpuMemoryBuffer* buffer =
403 frame_resources->plane_resources[i].gpu_memory_buffer.get(); 410 frame_resources->plane_resources[i].gpu_memory_buffer.get();
404 DCHECK(buffer); 411 uint8* dest_buffers[VideoFrame::kMaxPlanes] = {0};
405 DCHECK_EQ(planes_per_copy, 412 int dest_strides[VideoFrame::kMaxPlanes] = {0};
406 gfx::NumberOfPlanesForBufferFormat(buffer->GetFormat())); 413 if (buffer) {
407 uint8* dest_buffers[VideoFrame::kMaxPlanes]; 414 DCHECK_EQ(planes_per_copy,
408 int dest_strides[VideoFrame::kMaxPlanes]; 415 gfx::NumberOfPlanesForBufferFormat(buffer->GetFormat()));
409 bool rv = buffer->Map(reinterpret_cast<void**>(dest_buffers)); 416 bool rv = buffer->Map(reinterpret_cast<void**>(dest_buffers));
410 DCHECK(rv); 417 DCHECK(rv);
411 buffer->GetStride(dest_strides); 418 buffer->GetStride(dest_strides);
419 }
412 420
413 const int rows = VideoFrame::Rows(i, output_format_, size.height()); 421 const int rows = VideoFrame::Rows(i, output_format_, size.height());
414 const int rows_per_copy = RowsPerCopy(i, output_format_, size.width()); 422 const int rows_per_copy = RowsPerCopy(i, output_format_, size.width());
415 423
416 for (int row = 0; row < rows; row += rows_per_copy) { 424 for (int row = 0; row < rows; row += rows_per_copy) {
417 const int rows_to_copy = std::min(rows_per_copy, rows - row); 425 const int rows_to_copy = std::min(rows_per_copy, rows - row);
418 switch (output_format_) { 426 switch (output_format_) {
419 case PIXEL_FORMAT_I420: { 427 case PIXEL_FORMAT_I420: {
420 const int bytes_per_row = 428 const int bytes_per_row =
421 VideoFrame::RowBytes(i, output_format_, size.width()); 429 VideoFrame::RowBytes(i, output_format_, size.width());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 return; 468 return;
461 } 469 }
462 470
463 const size_t num_planes = VideoFrame::NumPlanes(output_format_); 471 const size_t num_planes = VideoFrame::NumPlanes(output_format_);
464 const size_t planes_per_copy = PlanesPerCopy(output_format_); 472 const size_t planes_per_copy = PlanesPerCopy(output_format_);
465 const gfx::Size size = video_frame->visible_rect().size(); 473 const gfx::Size size = video_frame->visible_rect().size();
466 gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes]; 474 gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes];
467 // Set up the planes creating the mailboxes needed to refer to the textures. 475 // Set up the planes creating the mailboxes needed to refer to the textures.
468 for (size_t i = 0; i < num_planes; i += planes_per_copy) { 476 for (size_t i = 0; i < num_planes; i += planes_per_copy) {
469 PlaneResource& plane_resource = frame_resources->plane_resources[i]; 477 PlaneResource& plane_resource = frame_resources->plane_resources[i];
470 DCHECK(plane_resource.gpu_memory_buffer);
471 // Bind the texture and create or rebind the image. 478 // Bind the texture and create or rebind the image.
472 gles2->BindTexture(texture_target_, plane_resource.texture_id); 479 gles2->BindTexture(texture_target_, plane_resource.texture_id);
473 480
474 if (!plane_resource.image_id) { 481 if (plane_resource.gpu_memory_buffer && !plane_resource.image_id) {
475 const size_t width = VideoFrame::Columns(i, output_format_, size.width()); 482 const size_t width = VideoFrame::Columns(i, output_format_, size.width());
476 const size_t height = VideoFrame::Rows(i, output_format_, size.height()); 483 const size_t height = VideoFrame::Rows(i, output_format_, size.height());
477 plane_resource.image_id = gles2->CreateImageCHROMIUM( 484 plane_resource.image_id = gles2->CreateImageCHROMIUM(
478 plane_resource.gpu_memory_buffer->AsClientBuffer(), width, height, 485 plane_resource.gpu_memory_buffer->AsClientBuffer(), width, height,
479 ImageInternalFormat(output_format_, i)); 486 ImageInternalFormat(output_format_, i));
480 } else { 487 } else if (plane_resource.image_id) {
481 gles2->ReleaseTexImage2DCHROMIUM(texture_target_, 488 gles2->ReleaseTexImage2DCHROMIUM(texture_target_,
482 plane_resource.image_id); 489 plane_resource.image_id);
483 } 490 }
484 gles2->BindTexImage2DCHROMIUM(texture_target_, plane_resource.image_id); 491 if (plane_resource.image_id)
492 gles2->BindTexImage2DCHROMIUM(texture_target_, plane_resource.image_id);
485 mailbox_holders[i] = 493 mailbox_holders[i] =
486 gpu::MailboxHolder(plane_resource.mailbox, texture_target_, 0); 494 gpu::MailboxHolder(plane_resource.mailbox, texture_target_, 0);
487 } 495 }
488 496
489 // Insert a sync_point, this is needed to make sure that the textures the 497 // Insert a sync_point, this is needed to make sure that the textures the
490 // mailboxes refer to will be used only after all the previous commands posted 498 // mailboxes refer to will be used only after all the previous commands posted
491 // in the command buffer have been processed. 499 // in the command buffer have been processed.
492 unsigned sync_point = gles2->InsertSyncPointCHROMIUM(); 500 unsigned sync_point = gles2->InsertSyncPointCHROMIUM();
493 for (size_t i = 0; i < num_planes; i += planes_per_copy) 501 for (size_t i = 0; i < num_planes; i += planes_per_copy)
494 mailbox_holders[i].sync_point = sync_point; 502 mailbox_holders[i].sync_point = sync_point;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 } 652 }
645 653
646 void GpuMemoryBufferVideoFramePool::MaybeCreateHardwareFrame( 654 void GpuMemoryBufferVideoFramePool::MaybeCreateHardwareFrame(
647 const scoped_refptr<VideoFrame>& video_frame, 655 const scoped_refptr<VideoFrame>& video_frame,
648 const FrameReadyCB& frame_ready_cb) { 656 const FrameReadyCB& frame_ready_cb) {
649 DCHECK(video_frame); 657 DCHECK(video_frame);
650 pool_impl_->CreateHardwareFrame(video_frame, frame_ready_cb); 658 pool_impl_->CreateHardwareFrame(video_frame, frame_ready_cb);
651 } 659 }
652 660
653 } // namespace media 661 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698