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

Side by Side Diff: content/renderer/media/gpu/rtc_video_decoder.cc

Issue 2832863002: Merge 59: Handle multiple textures per buffer in RTCVideoDecoder (Closed)
Patch Set: Created 3 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/renderer/media/gpu/rtc_video_decoder.h" 5 #include "content/renderer/media/gpu/rtc_video_decoder.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 } 298 }
299 if (next_bitstream_buffer_id_ != 0) 299 if (next_bitstream_buffer_id_ != 0)
300 reset_bitstream_buffer_id_ = next_bitstream_buffer_id_ - 1; 300 reset_bitstream_buffer_id_ = next_bitstream_buffer_id_ - 1;
301 else 301 else
302 reset_bitstream_buffer_id_ = ID_LAST; 302 reset_bitstream_buffer_id_ = ID_LAST;
303 frame_size_.SetSize(0, 0); 303 frame_size_.SetSize(0, 0);
304 Reset_Locked(); 304 Reset_Locked();
305 return WEBRTC_VIDEO_CODEC_OK; 305 return WEBRTC_VIDEO_CODEC_OK;
306 } 306 }
307 307
308 void RTCVideoDecoder::ProvidePictureBuffers(uint32_t count, 308 void RTCVideoDecoder::ProvidePictureBuffers(uint32_t buffer_count,
309 media::VideoPixelFormat format, 309 media::VideoPixelFormat format,
310 uint32_t textures_per_buffer, 310 uint32_t textures_per_buffer,
311 const gfx::Size& size, 311 const gfx::Size& size,
312 uint32_t texture_target) { 312 uint32_t texture_target) {
313 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 313 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
314 DVLOG(3) << "ProvidePictureBuffers. texture_target=" << texture_target; 314 DVLOG(3) << "ProvidePictureBuffers. texture_target=" << texture_target;
315 DCHECK_EQ(1u, textures_per_buffer);
316 315
317 if (!vda_) 316 if (!vda_)
318 return; 317 return;
319 318
320 std::vector<uint32_t> texture_ids; 319 std::vector<uint32_t> texture_ids;
321 std::vector<gpu::Mailbox> texture_mailboxes; 320 std::vector<gpu::Mailbox> texture_mailboxes;
322 decoder_texture_target_ = texture_target; 321 decoder_texture_target_ = texture_target;
323 322
324 if (format == media::PIXEL_FORMAT_UNKNOWN) 323 if (format == media::PIXEL_FORMAT_UNKNOWN)
325 format = media::PIXEL_FORMAT_ARGB; 324 format = media::PIXEL_FORMAT_ARGB;
326 325
327 if ((pixel_format_ != media::PIXEL_FORMAT_UNKNOWN) && 326 if ((pixel_format_ != media::PIXEL_FORMAT_UNKNOWN) &&
328 (format != pixel_format_)) { 327 (format != pixel_format_)) {
329 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 328 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
330 return; 329 return;
331 } 330 }
332 331
333 pixel_format_ = format; 332 pixel_format_ = format;
334 if (!factories_->CreateTextures(count, 333 const uint32_t texture_count = buffer_count * textures_per_buffer;
335 size, 334 if (!factories_->CreateTextures(texture_count, size, &texture_ids,
336 &texture_ids,
337 &texture_mailboxes, 335 &texture_mailboxes,
338 decoder_texture_target_)) { 336 decoder_texture_target_)) {
339 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 337 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
340 return; 338 return;
341 } 339 }
342 DCHECK_EQ(count, texture_ids.size()); 340 DCHECK_EQ(texture_count, texture_ids.size());
343 DCHECK_EQ(count, texture_mailboxes.size()); 341 DCHECK_EQ(texture_count, texture_mailboxes.size());
344 342
345 std::vector<media::PictureBuffer> picture_buffers; 343 std::vector<media::PictureBuffer> picture_buffers;
346 for (size_t i = 0; i < texture_ids.size(); ++i) { 344 for (size_t buffer_index = 0; buffer_index < buffer_count; ++buffer_index) {
347 media::PictureBuffer::TextureIds ids; 345 media::PictureBuffer::TextureIds ids;
348 ids.push_back(texture_ids[i]);
349 std::vector<gpu::Mailbox> mailboxes; 346 std::vector<gpu::Mailbox> mailboxes;
350 mailboxes.push_back(texture_mailboxes[i]); 347 for (size_t texture_index = 0; texture_index < textures_per_buffer;
348 ++texture_index) {
349 const size_t texture_id =
350 texture_index + textures_per_buffer * buffer_index;
351 ids.push_back(texture_ids[texture_id]);
352 mailboxes.push_back(texture_mailboxes[texture_id]);
353 }
351 354
352 picture_buffers.push_back( 355 picture_buffers.push_back(
353 media::PictureBuffer(next_picture_buffer_id_++, size, ids, mailboxes)); 356 media::PictureBuffer(next_picture_buffer_id_++, size, ids, mailboxes));
354 bool inserted = assigned_picture_buffers_.insert(std::make_pair( 357 const bool inserted =
355 picture_buffers.back().id(), picture_buffers.back())).second; 358 assigned_picture_buffers_
359 .insert(std::make_pair(picture_buffers.back().id(),
360 picture_buffers.back()))
361 .second;
356 DCHECK(inserted); 362 DCHECK(inserted);
357 } 363 }
358 vda_->AssignPictureBuffers(picture_buffers); 364 vda_->AssignPictureBuffers(picture_buffers);
359 } 365 }
360 366
361 void RTCVideoDecoder::DismissPictureBuffer(int32_t id) { 367 void RTCVideoDecoder::DismissPictureBuffer(int32_t id) {
362 DVLOG(3) << "DismissPictureBuffer. id=" << id; 368 DVLOG(3) << "DismissPictureBuffer. id=" << id;
363 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 369 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
364 370
365 std::map<int32_t, media::PictureBuffer>::iterator it = 371 std::map<int32_t, media::PictureBuffer>::iterator it =
366 assigned_picture_buffers_.find(id); 372 assigned_picture_buffers_.find(id);
367 if (it == assigned_picture_buffers_.end()) { 373 if (it == assigned_picture_buffers_.end()) {
368 NOTREACHED() << "Missing picture buffer: " << id; 374 NOTREACHED() << "Missing picture buffer: " << id;
369 return; 375 return;
370 } 376 }
371 377
372 media::PictureBuffer buffer_to_dismiss = it->second; 378 media::PictureBuffer buffer_to_dismiss = it->second;
373 assigned_picture_buffers_.erase(it); 379 assigned_picture_buffers_.erase(it);
374 380
375 if (!picture_buffers_at_display_.count(id)) { 381 if (!picture_buffers_at_display_.count(id)) {
376 // We can delete the texture immediately as it's not being displayed. 382 // We can delete the texture immediately as it's not being displayed.
377 factories_->DeleteTexture(buffer_to_dismiss.client_texture_ids()[0]); 383 for (const auto& id : buffer_to_dismiss.client_texture_ids())
384 factories_->DeleteTexture(id);
378 return; 385 return;
379 } 386 }
380 // Not destroying a texture in display in |picture_buffers_at_display_|. 387 // Not destroying a texture in display in |picture_buffers_at_display_|.
381 // Postpone deletion until after it's returned to us. 388 // Postpone deletion until after it's returned to us.
382 } 389 }
383 390
384 void RTCVideoDecoder::PictureReady(const media::Picture& picture) { 391 void RTCVideoDecoder::PictureReady(const media::Picture& picture) {
385 DVLOG(3) << "PictureReady"; 392 DVLOG(3) << "PictureReady";
386 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 393 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
387 394
(...skipping 20 matching lines...) Expand all
408 } 415 }
409 416
410 scoped_refptr<media::VideoFrame> frame = 417 scoped_refptr<media::VideoFrame> frame =
411 CreateVideoFrame(picture, pb, timestamp, visible_rect, pixel_format_); 418 CreateVideoFrame(picture, pb, timestamp, visible_rect, pixel_format_);
412 if (!frame) { 419 if (!frame) {
413 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 420 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
414 return; 421 return;
415 } 422 }
416 bool inserted = picture_buffers_at_display_ 423 bool inserted = picture_buffers_at_display_
417 .insert(std::make_pair(picture.picture_buffer_id(), 424 .insert(std::make_pair(picture.picture_buffer_id(),
418 pb.client_texture_ids()[0])) 425 pb.client_texture_ids()))
419 .second; 426 .second;
420 DCHECK(inserted); 427 DCHECK(inserted);
421 428
422 // Create a WebRTC video frame. 429 // Create a WebRTC video frame.
423 webrtc::VideoFrame decoded_image( 430 webrtc::VideoFrame decoded_image(
424 new rtc::RefCountedObject<WebRtcVideoFrameAdapter>( 431 new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(
425 frame, WebRtcVideoFrameAdapter::CopyTextureFrameCallback()), 432 frame, WebRtcVideoFrameAdapter::CopyTextureFrameCallback()),
426 timestamp, 0, webrtc::kVideoRotation_0); 433 timestamp, 0, webrtc::kVideoRotation_0);
427 434
428 // Invoke decode callback. WebRTC expects no callback after Release. 435 // Invoke decode callback. WebRTC expects no callback after Release.
(...skipping 18 matching lines...) Expand all
447 DCHECK(decoder_texture_target_); 454 DCHECK(decoder_texture_target_);
448 // Convert timestamp from 90KHz to ms. 455 // Convert timestamp from 90KHz to ms.
449 base::TimeDelta timestamp_ms = base::TimeDelta::FromInternalValue( 456 base::TimeDelta timestamp_ms = base::TimeDelta::FromInternalValue(
450 base::checked_cast<uint64_t>(timestamp) * 1000 / 90); 457 base::checked_cast<uint64_t>(timestamp) * 1000 / 90);
451 // TODO(mcasas): The incoming data may actually be in a YUV format, but may be 458 // TODO(mcasas): The incoming data may actually be in a YUV format, but may be
452 // labelled as ARGB. This may or may not be reported by VDA, depending on 459 // labelled as ARGB. This may or may not be reported by VDA, depending on
453 // whether it provides an implementation of VDA::GetOutputFormat(). 460 // whether it provides an implementation of VDA::GetOutputFormat().
454 // This prevents the compositor from messing with it, since the underlying 461 // This prevents the compositor from messing with it, since the underlying
455 // platform can handle the former format natively. Make sure the 462 // platform can handle the former format natively. Make sure the
456 // correct format is used and everyone down the line understands it. 463 // correct format is used and everyone down the line understands it.
457 gpu::MailboxHolder holders[media::VideoFrame::kMaxPlanes] = { 464 gpu::MailboxHolder holders[media::VideoFrame::kMaxPlanes];
458 gpu::MailboxHolder(pb.texture_mailbox(0), gpu::SyncToken(), 465 for (size_t i = 0; i < pb.client_texture_ids().size(); ++i) {
459 decoder_texture_target_)}; 466 holders[i].mailbox = pb.texture_mailbox(i);
467 holders[i].texture_target = decoder_texture_target_;
468 }
460 scoped_refptr<media::VideoFrame> frame = 469 scoped_refptr<media::VideoFrame> frame =
461 media::VideoFrame::WrapNativeTextures( 470 media::VideoFrame::WrapNativeTextures(
462 pixel_format, holders, 471 pixel_format, holders,
463 media::BindToCurrentLoop(base::Bind( 472 media::BindToCurrentLoop(
464 &RTCVideoDecoder::ReleaseMailbox, weak_factory_.GetWeakPtr(), 473 base::Bind(&RTCVideoDecoder::ReleaseMailbox,
465 factories_, picture.picture_buffer_id(), 474 weak_factory_.GetWeakPtr(), factories_,
466 pb.client_texture_ids()[0])), 475 picture.picture_buffer_id(), pb.client_texture_ids())),
467 pb.size(), visible_rect, visible_rect.size(), timestamp_ms); 476 pb.size(), visible_rect, visible_rect.size(), timestamp_ms);
468 if (frame && picture.allow_overlay()) { 477 if (frame && picture.allow_overlay()) {
469 frame->metadata()->SetBoolean(media::VideoFrameMetadata::ALLOW_OVERLAY, 478 frame->metadata()->SetBoolean(media::VideoFrameMetadata::ALLOW_OVERLAY,
470 true); 479 true);
471 } 480 }
472 return frame; 481 return frame;
473 } 482 }
474 483
475 void RTCVideoDecoder::NotifyEndOfBitstreamBuffer(int32_t id) { 484 void RTCVideoDecoder::NotifyEndOfBitstreamBuffer(int32_t id) {
476 DVLOG(3) << "NotifyEndOfBitstreamBuffer. id=" << id; 485 DVLOG(3) << "NotifyEndOfBitstreamBuffer. id=" << id;
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 state_ = INITIALIZED; 688 state_ = INITIALIZED;
680 } 689 }
681 } 690 }
682 } 691 }
683 692
684 // static 693 // static
685 void RTCVideoDecoder::ReleaseMailbox( 694 void RTCVideoDecoder::ReleaseMailbox(
686 base::WeakPtr<RTCVideoDecoder> decoder, 695 base::WeakPtr<RTCVideoDecoder> decoder,
687 media::GpuVideoAcceleratorFactories* factories, 696 media::GpuVideoAcceleratorFactories* factories,
688 int64_t picture_buffer_id, 697 int64_t picture_buffer_id,
689 uint32_t texture_id, 698 const media::PictureBuffer::TextureIds& texture_ids,
690 const gpu::SyncToken& release_sync_token) { 699 const gpu::SyncToken& release_sync_token) {
691 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread()); 700 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread());
692 factories->WaitSyncToken(release_sync_token); 701 factories->WaitSyncToken(release_sync_token);
693 702
694 if (decoder) { 703 if (decoder) {
695 decoder->ReusePictureBuffer(picture_buffer_id); 704 decoder->ReusePictureBuffer(picture_buffer_id);
696 return; 705 return;
697 } 706 }
698 // It's the last chance to delete the texture after display, 707 // It's the last chance to delete the texture after display,
699 // because RTCVideoDecoder was destructed. 708 // because RTCVideoDecoder was destructed.
700 factories->DeleteTexture(texture_id); 709 for (const auto& id : texture_ids)
710 factories->DeleteTexture(id);
701 } 711 }
702 712
703 void RTCVideoDecoder::ReusePictureBuffer(int64_t picture_buffer_id) { 713 void RTCVideoDecoder::ReusePictureBuffer(int64_t picture_buffer_id) {
704 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 714 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
705 DVLOG(3) << "ReusePictureBuffer. id=" << picture_buffer_id; 715 DVLOG(3) << "ReusePictureBuffer. id=" << picture_buffer_id;
706 716
707 DCHECK(!picture_buffers_at_display_.empty()); 717 DCHECK(!picture_buffers_at_display_.empty());
708 PictureBufferTextureMap::iterator display_iterator = 718 PictureBufferTextureMap::iterator display_iterator =
709 picture_buffers_at_display_.find(picture_buffer_id); 719 picture_buffers_at_display_.find(picture_buffer_id);
710 uint32_t texture_id = display_iterator->second; 720 const auto texture_ids = display_iterator->second;
711 DCHECK(display_iterator != picture_buffers_at_display_.end()); 721 DCHECK(display_iterator != picture_buffers_at_display_.end());
712 picture_buffers_at_display_.erase(display_iterator); 722 picture_buffers_at_display_.erase(display_iterator);
713 723
714 if (!assigned_picture_buffers_.count(picture_buffer_id)) { 724 if (!assigned_picture_buffers_.count(picture_buffer_id)) {
715 // This picture was dismissed while in display, so we postponed deletion. 725 // This picture was dismissed while in display, so we postponed deletion.
716 factories_->DeleteTexture(texture_id); 726 for (const auto& id : texture_ids)
727 factories_->DeleteTexture(id);
717 return; 728 return;
718 } 729 }
719 730
720 // DestroyVDA() might already have been called. 731 // DestroyVDA() might already have been called.
721 if (vda_) 732 if (vda_)
722 vda_->ReusePictureBuffer(picture_buffer_id); 733 vda_->ReusePictureBuffer(picture_buffer_id);
723 } 734 }
724 735
725 bool RTCVideoDecoder::IsProfileSupported(media::VideoCodecProfile profile) { 736 bool RTCVideoDecoder::IsProfileSupported(media::VideoCodecProfile profile) {
726 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 737 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 } 769 }
759 770
760 void RTCVideoDecoder::DestroyTextures() { 771 void RTCVideoDecoder::DestroyTextures() {
761 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 772 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
762 773
763 // Not destroying PictureBuffers in |picture_buffers_at_display_| yet, since 774 // Not destroying PictureBuffers in |picture_buffers_at_display_| yet, since
764 // their textures may still be in use by the user of this RTCVideoDecoder. 775 // their textures may still be in use by the user of this RTCVideoDecoder.
765 for (const auto& picture_buffer_at_display : picture_buffers_at_display_) 776 for (const auto& picture_buffer_at_display : picture_buffers_at_display_)
766 assigned_picture_buffers_.erase(picture_buffer_at_display.first); 777 assigned_picture_buffers_.erase(picture_buffer_at_display.first);
767 778
768 for (const auto& assigned_picture_buffer : assigned_picture_buffers_) 779 for (const auto& assigned_picture_buffer : assigned_picture_buffers_) {
769 factories_->DeleteTexture( 780 for (const auto& id : assigned_picture_buffer.second.client_texture_ids())
770 assigned_picture_buffer.second.client_texture_ids()[0]); 781 factories_->DeleteTexture(id);
782 }
771 783
772 assigned_picture_buffers_.clear(); 784 assigned_picture_buffers_.clear();
773 } 785 }
774 786
775 void RTCVideoDecoder::DestroyVDA() { 787 void RTCVideoDecoder::DestroyVDA() {
776 DVLOG(2) << "DestroyVDA"; 788 DVLOG(2) << "DestroyVDA";
777 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 789 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
778 if (vda_) 790 if (vda_)
779 vda_.release()->Destroy(); 791 vda_.release()->Destroy();
780 DestroyTextures(); 792 DestroyTextures();
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 } 903 }
892 904
893 void RTCVideoDecoder::ClearPendingBuffers() { 905 void RTCVideoDecoder::ClearPendingBuffers() {
894 // Delete WebRTC input buffers. 906 // Delete WebRTC input buffers.
895 for (const auto& pending_buffer : pending_buffers_) 907 for (const auto& pending_buffer : pending_buffers_)
896 delete[] pending_buffer.first._buffer; 908 delete[] pending_buffer.first._buffer;
897 pending_buffers_.clear(); 909 pending_buffers_.clear();
898 } 910 }
899 911
900 } // namespace content 912 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/gpu/rtc_video_decoder.h ('k') | content/renderer/media/gpu/rtc_video_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698