| OLD | NEW |
| 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/rtc_video_decoder.h" | 5 #include "content/renderer/media/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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 state_ = RESETTING; | 276 state_ = RESETTING; |
| 277 factories_->GetTaskRunner()->PostTask( | 277 factories_->GetTaskRunner()->PostTask( |
| 278 FROM_HERE, | 278 FROM_HERE, |
| 279 base::Bind(&RTCVideoDecoder::ResetInternal, | 279 base::Bind(&RTCVideoDecoder::ResetInternal, |
| 280 weak_factory_.GetWeakPtr())); | 280 weak_factory_.GetWeakPtr())); |
| 281 } | 281 } |
| 282 return WEBRTC_VIDEO_CODEC_OK; | 282 return WEBRTC_VIDEO_CODEC_OK; |
| 283 } | 283 } |
| 284 | 284 |
| 285 void RTCVideoDecoder::ProvidePictureBuffers(uint32_t count, | 285 void RTCVideoDecoder::ProvidePictureBuffers(uint32_t count, |
| 286 uint32_t textures_per_buffer, |
| 286 const gfx::Size& size, | 287 const gfx::Size& size, |
| 287 uint32_t texture_target) { | 288 uint32_t texture_target) { |
| 288 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 289 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 289 DVLOG(3) << "ProvidePictureBuffers. texture_target=" << texture_target; | 290 DVLOG(3) << "ProvidePictureBuffers. texture_target=" << texture_target; |
| 291 DCHECK_EQ(1u, textures_per_buffer); |
| 290 | 292 |
| 291 if (!vda_) | 293 if (!vda_) |
| 292 return; | 294 return; |
| 293 | 295 |
| 294 std::vector<uint32_t> texture_ids; | 296 std::vector<uint32_t> texture_ids; |
| 295 std::vector<gpu::Mailbox> texture_mailboxes; | 297 std::vector<gpu::Mailbox> texture_mailboxes; |
| 296 decoder_texture_target_ = texture_target; | 298 decoder_texture_target_ = texture_target; |
| 297 if (!factories_->CreateTextures(count, | 299 if (!factories_->CreateTextures(count, |
| 298 size, | 300 size, |
| 299 &texture_ids, | 301 &texture_ids, |
| 300 &texture_mailboxes, | 302 &texture_mailboxes, |
| 301 decoder_texture_target_)) { | 303 decoder_texture_target_)) { |
| 302 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 304 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); |
| 303 return; | 305 return; |
| 304 } | 306 } |
| 305 DCHECK_EQ(count, texture_ids.size()); | 307 DCHECK_EQ(count, texture_ids.size()); |
| 306 DCHECK_EQ(count, texture_mailboxes.size()); | 308 DCHECK_EQ(count, texture_mailboxes.size()); |
| 307 | 309 |
| 308 std::vector<media::PictureBuffer> picture_buffers; | 310 std::vector<media::PictureBuffer> picture_buffers; |
| 309 for (size_t i = 0; i < texture_ids.size(); ++i) { | 311 for (size_t i = 0; i < texture_ids.size(); ++i) { |
| 310 picture_buffers.push_back(media::PictureBuffer( | 312 media::PictureBuffer::TextureIds ids; |
| 311 next_picture_buffer_id_++, size, texture_ids[i], texture_mailboxes[i])); | 313 ids.push_back(texture_ids[i]); |
| 314 std::vector<gpu::Mailbox> mailboxes; |
| 315 mailboxes.push_back(texture_mailboxes[i]); |
| 316 |
| 317 picture_buffers.push_back( |
| 318 media::PictureBuffer(next_picture_buffer_id_++, size, ids, mailboxes)); |
| 312 bool inserted = assigned_picture_buffers_.insert(std::make_pair( | 319 bool inserted = assigned_picture_buffers_.insert(std::make_pair( |
| 313 picture_buffers.back().id(), picture_buffers.back())).second; | 320 picture_buffers.back().id(), picture_buffers.back())).second; |
| 314 DCHECK(inserted); | 321 DCHECK(inserted); |
| 315 } | 322 } |
| 316 vda_->AssignPictureBuffers(picture_buffers); | 323 vda_->AssignPictureBuffers(picture_buffers); |
| 317 } | 324 } |
| 318 | 325 |
| 319 void RTCVideoDecoder::DismissPictureBuffer(int32_t id) { | 326 void RTCVideoDecoder::DismissPictureBuffer(int32_t id) { |
| 320 DVLOG(3) << "DismissPictureBuffer. id=" << id; | 327 DVLOG(3) << "DismissPictureBuffer. id=" << id; |
| 321 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 328 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 322 | 329 |
| 323 std::map<int32_t, media::PictureBuffer>::iterator it = | 330 std::map<int32_t, media::PictureBuffer>::iterator it = |
| 324 assigned_picture_buffers_.find(id); | 331 assigned_picture_buffers_.find(id); |
| 325 if (it == assigned_picture_buffers_.end()) { | 332 if (it == assigned_picture_buffers_.end()) { |
| 326 NOTREACHED() << "Missing picture buffer: " << id; | 333 NOTREACHED() << "Missing picture buffer: " << id; |
| 327 return; | 334 return; |
| 328 } | 335 } |
| 329 | 336 |
| 330 media::PictureBuffer buffer_to_dismiss = it->second; | 337 media::PictureBuffer buffer_to_dismiss = it->second; |
| 331 assigned_picture_buffers_.erase(it); | 338 assigned_picture_buffers_.erase(it); |
| 332 | 339 |
| 333 if (!picture_buffers_at_display_.count(id)) { | 340 if (!picture_buffers_at_display_.count(id)) { |
| 334 // We can delete the texture immediately as it's not being displayed. | 341 // We can delete the texture immediately as it's not being displayed. |
| 335 factories_->DeleteTexture(buffer_to_dismiss.texture_id()); | 342 factories_->DeleteTexture(buffer_to_dismiss.texture_ids()[0]); |
| 336 return; | 343 return; |
| 337 } | 344 } |
| 338 // Not destroying a texture in display in |picture_buffers_at_display_|. | 345 // Not destroying a texture in display in |picture_buffers_at_display_|. |
| 339 // Postpone deletion until after it's returned to us. | 346 // Postpone deletion until after it's returned to us. |
| 340 } | 347 } |
| 341 | 348 |
| 342 void RTCVideoDecoder::PictureReady(const media::Picture& picture) { | 349 void RTCVideoDecoder::PictureReady(const media::Picture& picture) { |
| 343 DVLOG(3) << "PictureReady"; | 350 DVLOG(3) << "PictureReady"; |
| 344 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 351 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 345 | 352 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 364 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 371 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); |
| 365 return; | 372 return; |
| 366 } | 373 } |
| 367 | 374 |
| 368 scoped_refptr<media::VideoFrame> frame = | 375 scoped_refptr<media::VideoFrame> frame = |
| 369 CreateVideoFrame(picture, pb, timestamp, visible_rect); | 376 CreateVideoFrame(picture, pb, timestamp, visible_rect); |
| 370 if (!frame) { | 377 if (!frame) { |
| 371 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 378 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); |
| 372 return; | 379 return; |
| 373 } | 380 } |
| 374 bool inserted = | 381 bool inserted = picture_buffers_at_display_ |
| 375 picture_buffers_at_display_.insert(std::make_pair( | 382 .insert(std::make_pair(picture.picture_buffer_id(), |
| 376 picture.picture_buffer_id(), | 383 pb.texture_ids()[0])) |
| 377 pb.texture_id())).second; | 384 .second; |
| 378 DCHECK(inserted); | 385 DCHECK(inserted); |
| 379 | 386 |
| 380 // Create a WebRTC video frame. | 387 // Create a WebRTC video frame. |
| 381 webrtc::VideoFrame decoded_image( | 388 webrtc::VideoFrame decoded_image( |
| 382 new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(frame), timestamp, 0, | 389 new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(frame), timestamp, 0, |
| 383 webrtc::kVideoRotation_0); | 390 webrtc::kVideoRotation_0); |
| 384 | 391 |
| 385 // Invoke decode callback. WebRTC expects no callback after Release. | 392 // Invoke decode callback. WebRTC expects no callback after Release. |
| 386 { | 393 { |
| 387 base::AutoLock auto_lock(lock_); | 394 base::AutoLock auto_lock(lock_); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 401 DCHECK(decoder_texture_target_); | 408 DCHECK(decoder_texture_target_); |
| 402 // Convert timestamp from 90KHz to ms. | 409 // Convert timestamp from 90KHz to ms. |
| 403 base::TimeDelta timestamp_ms = base::TimeDelta::FromInternalValue( | 410 base::TimeDelta timestamp_ms = base::TimeDelta::FromInternalValue( |
| 404 base::checked_cast<uint64_t>(timestamp) * 1000 / 90); | 411 base::checked_cast<uint64_t>(timestamp) * 1000 / 90); |
| 405 // TODO(mcasas): The incoming data is actually a YUV format, but is labelled | 412 // TODO(mcasas): The incoming data is actually a YUV format, but is labelled |
| 406 // as ARGB. This prevents the compositor from messing with it, since the | 413 // as ARGB. This prevents the compositor from messing with it, since the |
| 407 // underlying platform can handle the former format natively. Make sure the | 414 // underlying platform can handle the former format natively. Make sure the |
| 408 // correct format is used and everyone down the line understands it. | 415 // correct format is used and everyone down the line understands it. |
| 409 scoped_refptr<media::VideoFrame> frame = media::VideoFrame::WrapNativeTexture( | 416 scoped_refptr<media::VideoFrame> frame = media::VideoFrame::WrapNativeTexture( |
| 410 media::PIXEL_FORMAT_ARGB, | 417 media::PIXEL_FORMAT_ARGB, |
| 411 gpu::MailboxHolder(pb.texture_mailbox(), gpu::SyncToken(), | 418 gpu::MailboxHolder(pb.texture_mailbox(0), gpu::SyncToken(), |
| 412 decoder_texture_target_), | 419 decoder_texture_target_), |
| 413 media::BindToCurrentLoop(base::Bind( | 420 media::BindToCurrentLoop(base::Bind( |
| 414 &RTCVideoDecoder::ReleaseMailbox, weak_factory_.GetWeakPtr(), | 421 &RTCVideoDecoder::ReleaseMailbox, weak_factory_.GetWeakPtr(), |
| 415 factories_, picture.picture_buffer_id(), pb.texture_id())), | 422 factories_, picture.picture_buffer_id(), pb.texture_ids()[0])), |
| 416 pb.size(), visible_rect, visible_rect.size(), timestamp_ms); | 423 pb.size(), visible_rect, visible_rect.size(), timestamp_ms); |
| 417 if (frame && picture.allow_overlay()) { | 424 if (frame && picture.allow_overlay()) { |
| 418 frame->metadata()->SetBoolean(media::VideoFrameMetadata::ALLOW_OVERLAY, | 425 frame->metadata()->SetBoolean(media::VideoFrameMetadata::ALLOW_OVERLAY, |
| 419 true); | 426 true); |
| 420 } | 427 } |
| 421 return frame; | 428 return frame; |
| 422 } | 429 } |
| 423 | 430 |
| 424 void RTCVideoDecoder::NotifyEndOfBitstreamBuffer(int32_t id) { | 431 void RTCVideoDecoder::NotifyEndOfBitstreamBuffer(int32_t id) { |
| 425 DVLOG(3) << "NotifyEndOfBitstreamBuffer. id=" << id; | 432 DVLOG(3) << "NotifyEndOfBitstreamBuffer. id=" << id; |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 | 693 |
| 687 void RTCVideoDecoder::DestroyTextures() { | 694 void RTCVideoDecoder::DestroyTextures() { |
| 688 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 695 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 689 | 696 |
| 690 // Not destroying PictureBuffers in |picture_buffers_at_display_| yet, since | 697 // Not destroying PictureBuffers in |picture_buffers_at_display_| yet, since |
| 691 // their textures may still be in use by the user of this RTCVideoDecoder. | 698 // their textures may still be in use by the user of this RTCVideoDecoder. |
| 692 for (const auto& picture_buffer_at_display : picture_buffers_at_display_) | 699 for (const auto& picture_buffer_at_display : picture_buffers_at_display_) |
| 693 assigned_picture_buffers_.erase(picture_buffer_at_display.first); | 700 assigned_picture_buffers_.erase(picture_buffer_at_display.first); |
| 694 | 701 |
| 695 for (const auto& assigned_picture_buffer : assigned_picture_buffers_) | 702 for (const auto& assigned_picture_buffer : assigned_picture_buffers_) |
| 696 factories_->DeleteTexture(assigned_picture_buffer.second.texture_id()); | 703 factories_->DeleteTexture(assigned_picture_buffer.second.texture_ids()[0]); |
| 697 | 704 |
| 698 assigned_picture_buffers_.clear(); | 705 assigned_picture_buffers_.clear(); |
| 699 } | 706 } |
| 700 | 707 |
| 701 void RTCVideoDecoder::DestroyVDA() { | 708 void RTCVideoDecoder::DestroyVDA() { |
| 702 DVLOG(2) << "DestroyVDA"; | 709 DVLOG(2) << "DestroyVDA"; |
| 703 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 710 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 704 if (vda_) | 711 if (vda_) |
| 705 vda_.release()->Destroy(); | 712 vda_.release()->Destroy(); |
| 706 DestroyTextures(); | 713 DestroyTextures(); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 } | 813 } |
| 807 | 814 |
| 808 void RTCVideoDecoder::ClearPendingBuffers() { | 815 void RTCVideoDecoder::ClearPendingBuffers() { |
| 809 // Delete WebRTC input buffers. | 816 // Delete WebRTC input buffers. |
| 810 for (const auto& pending_buffer : pending_buffers_) | 817 for (const auto& pending_buffer : pending_buffers_) |
| 811 delete[] pending_buffer.first._buffer; | 818 delete[] pending_buffer.first._buffer; |
| 812 pending_buffers_.clear(); | 819 pending_buffers_.clear(); |
| 813 } | 820 } |
| 814 | 821 |
| 815 } // namespace content | 822 } // namespace content |
| OLD | NEW |