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

Side by Side Diff: media/filters/gpu_video_decoder.cc

Issue 14199002: Send hardware video frames with mailboxes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Ifdefed 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
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/filters/gpu_video_decoder.h" 5 #include "media/filters/gpu_video_decoder.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/cpu.h" 9 #include "base/cpu.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 const gfx::Size& size, 361 const gfx::Size& size,
362 uint32 texture_target) { 362 uint32 texture_target) {
363 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 363 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
364 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 364 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
365 &GpuVideoDecoder::ProvidePictureBuffers, this, count, size, 365 &GpuVideoDecoder::ProvidePictureBuffers, this, count, size,
366 texture_target)); 366 texture_target));
367 return; 367 return;
368 } 368 }
369 369
370 std::vector<uint32> texture_ids; 370 std::vector<uint32> texture_ids;
371 std::vector<gpu::Mailbox> texture_mailboxes;
371 decoder_texture_target_ = texture_target; 372 decoder_texture_target_ = texture_target;
372 if (!factories_->CreateTextures( 373 if (!factories_->CreateTextures(count,
373 count, size, &texture_ids, decoder_texture_target_)) { 374 size,
375 &texture_ids,
376 &texture_mailboxes,
377 decoder_texture_target_)) {
374 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 378 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
375 return; 379 return;
376 } 380 }
377 381
378 if (!vda_.get()) 382 if (!vda_.get())
379 return; 383 return;
380 384
381 CHECK_EQ(available_pictures_, -1); 385 CHECK_EQ(available_pictures_, -1);
382 available_pictures_ = count; 386 available_pictures_ = count;
383 387
384 std::vector<PictureBuffer> picture_buffers; 388 std::vector<PictureBuffer> picture_buffers;
385 for (size_t i = 0; i < texture_ids.size(); ++i) { 389 for (size_t i = 0; i < texture_ids.size(); ++i) {
386 picture_buffers.push_back(PictureBuffer( 390 picture_buffers.push_back(PictureBuffer(
387 next_picture_buffer_id_++, size, texture_ids[i])); 391 next_picture_buffer_id_++, size, texture_ids[i], texture_mailboxes[i]));
388 bool inserted = picture_buffers_in_decoder_.insert(std::make_pair( 392 bool inserted = picture_buffers_in_decoder_.insert(std::make_pair(
389 picture_buffers.back().id(), picture_buffers.back())).second; 393 picture_buffers.back().id(), picture_buffers.back())).second;
390 DCHECK(inserted); 394 DCHECK(inserted);
391 } 395 }
392 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 396 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
393 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_, 397 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_,
394 picture_buffers)); 398 picture_buffers));
395 } 399 }
396 400
397 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { 401 void GpuVideoDecoder::DismissPictureBuffer(int32 id) {
(...skipping 27 matching lines...) Expand all
425 } 429 }
426 const PictureBuffer& pb = it->second; 430 const PictureBuffer& pb = it->second;
427 431
428 // Update frame's timestamp. 432 // Update frame's timestamp.
429 base::TimeDelta timestamp; 433 base::TimeDelta timestamp;
430 gfx::Rect visible_rect; 434 gfx::Rect visible_rect;
431 gfx::Size natural_size; 435 gfx::Size natural_size;
432 GetBufferData(picture.bitstream_buffer_id(), &timestamp, &visible_rect, 436 GetBufferData(picture.bitstream_buffer_id(), &timestamp, &visible_rect,
433 &natural_size); 437 &natural_size);
434 DCHECK(decoder_texture_target_); 438 DCHECK(decoder_texture_target_);
439
440 #ifdef VIDEO_FRAME_MAILBOX
441 uint32 sync_point = factories_->ProduceTextureToMailbox(
442 pb.texture_mailbox(), pb.texture_id());
443 #endif
444
435 scoped_refptr<VideoFrame> frame( 445 scoped_refptr<VideoFrame> frame(
436 VideoFrame::WrapNativeTexture( 446 VideoFrame::WrapNativeTexture(
437 pb.texture_id(), decoder_texture_target_, pb.size(), visible_rect, 447 #ifdef VIDEO_FRAME_MAILBOX
448 pb.texture_mailbox(), sync_point,
449 #else
450 pb.texture_id(),
451 #endif
452 decoder_texture_target_,
453 pb.size(), visible_rect,
438 natural_size, timestamp, 454 natural_size, timestamp,
439 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(), 455 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(),
440 decoder_texture_target_, 456 decoder_texture_target_,
441 gfx::Size(visible_rect.width(), visible_rect.height())), 457 gfx::Size(visible_rect.width(), visible_rect.height())),
442 base::Bind(&GpuVideoDecoder::ReusePictureBuffer, this, 458 base::Bind(&GpuVideoDecoder::ReusePictureBuffer, this,
443 picture.picture_buffer_id()))); 459 picture.picture_buffer_id()),
460 base::Closure()));
444 CHECK_GT(available_pictures_, 0); 461 CHECK_GT(available_pictures_, 0);
445 available_pictures_--; 462 available_pictures_--;
446 463
447 EnqueueFrameAndTriggerFrameDelivery(frame); 464 EnqueueFrameAndTriggerFrameDelivery(frame);
448 } 465 }
449 466
450 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( 467 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery(
451 const scoped_refptr<VideoFrame>& frame) { 468 const scoped_refptr<VideoFrame>& frame) {
452 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 469 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
453 470
454 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the 471 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the
455 // floor and return. 472 // floor and return.
456 if (!pending_reset_cb_.is_null()) 473 if (!pending_reset_cb_.is_null())
457 return; 474 return;
458 475
459 if (frame) 476 if (frame)
460 ready_video_frames_.push_back(frame); 477 ready_video_frames_.push_back(frame);
461 else 478 else
462 DCHECK(!ready_video_frames_.empty()); 479 DCHECK(!ready_video_frames_.empty());
463 480
464 if (pending_read_cb_.is_null()) 481 if (pending_read_cb_.is_null())
465 return; 482 return;
466 483
467 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front()); 484 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front());
468 ready_video_frames_.pop_front(); 485 ready_video_frames_.pop_front();
469 } 486 }
470 487
471 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { 488 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id,
489 uint32 sync_point) {
472 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 490 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
473 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 491 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
474 &GpuVideoDecoder::ReusePictureBuffer, this, picture_buffer_id)); 492 &GpuVideoDecoder::ReusePictureBuffer,
493 this,
494 picture_buffer_id,
495 sync_point));
475 return; 496 return;
476 } 497 }
477 CHECK_GE(available_pictures_, 0); 498 CHECK_GE(available_pictures_, 0);
478 available_pictures_++; 499 available_pictures_++;
479 500
480 if (!vda_.get()) 501 if (!vda_.get())
481 return; 502 return;
503
504 std::map<int32, PictureBuffer>::iterator it =
505 picture_buffers_in_decoder_.find(picture_buffer_id);
506 if (it == picture_buffers_in_decoder_.end()) {
507 NOTREACHED() << "Missing picture buffer: " << picture_buffer_id;
508 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
509 return;
510 }
511 #ifdef VIDEO_FRAME_MAILBOX
512 const PictureBuffer& pb = it->second;
513 factories_->ConsumeMailboxToTexture(pb.texture_mailbox(),
514 pb.texture_id(),
515 sync_point);
516 #endif
517
482 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 518 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
483 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_, 519 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_,
484 picture_buffer_id)); 520 picture_buffer_id));
485 } 521 }
486 522
487 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { 523 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) {
488 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 524 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
489 if (available_shm_segments_.empty() || 525 if (available_shm_segments_.empty() ||
490 available_shm_segments_.back()->size < min_size) { 526 available_shm_segments_.back()->size < min_size) {
491 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); 527 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 649
614 error_occured_ = true; 650 error_occured_ = true;
615 651
616 if (!pending_read_cb_.is_null()) { 652 if (!pending_read_cb_.is_null()) {
617 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); 653 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL);
618 return; 654 return;
619 } 655 }
620 } 656 }
621 657
622 } // namespace media 658 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698