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/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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 | 61 |
62 RTCVideoDecoder::BufferData::BufferData() {} | 62 RTCVideoDecoder::BufferData::BufferData() {} |
63 | 63 |
64 RTCVideoDecoder::BufferData::~BufferData() {} | 64 RTCVideoDecoder::BufferData::~BufferData() {} |
65 | 65 |
66 RTCVideoDecoder::RTCVideoDecoder(webrtc::VideoCodecType type, | 66 RTCVideoDecoder::RTCVideoDecoder(webrtc::VideoCodecType type, |
67 media::GpuVideoAcceleratorFactories* factories) | 67 media::GpuVideoAcceleratorFactories* factories) |
68 : vda_error_counter_(0), | 68 : vda_error_counter_(0), |
69 video_codec_type_(type), | 69 video_codec_type_(type), |
70 factories_(factories), | 70 factories_(factories), |
71 decoder_texture_target_(0), | |
72 pixel_format_(media::PIXEL_FORMAT_UNKNOWN), | |
73 next_picture_buffer_id_(0), | 71 next_picture_buffer_id_(0), |
74 state_(UNINITIALIZED), | 72 state_(UNINITIALIZED), |
75 decode_complete_callback_(nullptr), | 73 decode_complete_callback_(nullptr), |
76 num_shm_buffers_(0), | 74 num_shm_buffers_(0), |
77 next_bitstream_buffer_id_(0), | 75 next_bitstream_buffer_id_(0), |
78 reset_bitstream_buffer_id_(ID_INVALID), | 76 reset_bitstream_buffer_id_(ID_INVALID), |
79 weak_factory_(this) { | 77 weak_factory_(this) { |
80 DCHECK(!factories_->GetTaskRunner()->BelongsToCurrentThread()); | 78 DCHECK(!factories_->GetTaskRunner()->BelongsToCurrentThread()); |
81 } | 79 } |
82 | 80 |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 const gfx::Size& size, | 309 const gfx::Size& size, |
312 uint32_t texture_target) { | 310 uint32_t texture_target) { |
313 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 311 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
314 DVLOG(3) << "ProvidePictureBuffers. texture_target=" << texture_target; | 312 DVLOG(3) << "ProvidePictureBuffers. texture_target=" << texture_target; |
315 | 313 |
316 if (!vda_) | 314 if (!vda_) |
317 return; | 315 return; |
318 | 316 |
319 std::vector<uint32_t> texture_ids; | 317 std::vector<uint32_t> texture_ids; |
320 std::vector<gpu::Mailbox> texture_mailboxes; | 318 std::vector<gpu::Mailbox> texture_mailboxes; |
321 decoder_texture_target_ = texture_target; | |
322 | 319 |
323 if (format == media::PIXEL_FORMAT_UNKNOWN) | 320 if (format == media::PIXEL_FORMAT_UNKNOWN) |
324 format = media::PIXEL_FORMAT_ARGB; | 321 format = media::PIXEL_FORMAT_ARGB; |
325 | 322 |
326 if ((pixel_format_ != media::PIXEL_FORMAT_UNKNOWN) && | 323 const uint32_t texture_count = buffer_count * textures_per_buffer; |
327 (format != pixel_format_)) { | 324 if (!factories_->CreateTextures(texture_count, size, &texture_ids, |
| 325 &texture_mailboxes, texture_target)) { |
328 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 326 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); |
329 return; | 327 return; |
330 } | 328 } |
331 | |
332 pixel_format_ = format; | |
333 const uint32_t texture_count = buffer_count * textures_per_buffer; | |
334 if (!factories_->CreateTextures(texture_count, size, &texture_ids, | |
335 &texture_mailboxes, | |
336 decoder_texture_target_)) { | |
337 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | |
338 return; | |
339 } | |
340 DCHECK_EQ(texture_count, texture_ids.size()); | 329 DCHECK_EQ(texture_count, texture_ids.size()); |
341 DCHECK_EQ(texture_count, texture_mailboxes.size()); | 330 DCHECK_EQ(texture_count, texture_mailboxes.size()); |
342 | 331 |
343 std::vector<media::PictureBuffer> picture_buffers; | 332 std::vector<media::PictureBuffer> picture_buffers; |
344 for (size_t buffer_index = 0; buffer_index < buffer_count; ++buffer_index) { | 333 for (size_t buffer_index = 0; buffer_index < buffer_count; ++buffer_index) { |
345 media::PictureBuffer::TextureIds ids; | 334 media::PictureBuffer::TextureIds ids; |
346 std::vector<gpu::Mailbox> mailboxes; | 335 std::vector<gpu::Mailbox> mailboxes; |
347 for (size_t texture_index = 0; texture_index < textures_per_buffer; | 336 for (size_t texture_index = 0; texture_index < textures_per_buffer; |
348 ++texture_index) { | 337 ++texture_index) { |
349 const size_t texture_id = | 338 const size_t texture_id = |
350 texture_index + textures_per_buffer * buffer_index; | 339 texture_index + textures_per_buffer * buffer_index; |
351 ids.push_back(texture_ids[texture_id]); | 340 ids.push_back(texture_ids[texture_id]); |
352 mailboxes.push_back(texture_mailboxes[texture_id]); | 341 mailboxes.push_back(texture_mailboxes[texture_id]); |
353 } | 342 } |
354 | 343 |
355 picture_buffers.push_back( | 344 picture_buffers.push_back(media::PictureBuffer(next_picture_buffer_id_++, |
356 media::PictureBuffer(next_picture_buffer_id_++, size, ids, mailboxes)); | 345 size, ids, mailboxes, |
| 346 texture_target, format)); |
357 const bool inserted = | 347 const bool inserted = |
358 assigned_picture_buffers_ | 348 assigned_picture_buffers_ |
359 .insert(std::make_pair(picture_buffers.back().id(), | 349 .insert(std::make_pair(picture_buffers.back().id(), |
360 picture_buffers.back())) | 350 picture_buffers.back())) |
361 .second; | 351 .second; |
362 DCHECK(inserted); | 352 DCHECK(inserted); |
363 } | 353 } |
364 vda_->AssignPictureBuffers(picture_buffers); | 354 vda_->AssignPictureBuffers(picture_buffers); |
365 } | 355 } |
366 | 356 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 | 398 |
409 const media::PictureBuffer& pb = it->second; | 399 const media::PictureBuffer& pb = it->second; |
410 if (visible_rect.IsEmpty() || !gfx::Rect(pb.size()).Contains(visible_rect)) { | 400 if (visible_rect.IsEmpty() || !gfx::Rect(pb.size()).Contains(visible_rect)) { |
411 LOG(ERROR) << "Invalid picture size: " << visible_rect.ToString() | 401 LOG(ERROR) << "Invalid picture size: " << visible_rect.ToString() |
412 << " should fit in " << pb.size().ToString(); | 402 << " should fit in " << pb.size().ToString(); |
413 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 403 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); |
414 return; | 404 return; |
415 } | 405 } |
416 | 406 |
417 scoped_refptr<media::VideoFrame> frame = | 407 scoped_refptr<media::VideoFrame> frame = |
418 CreateVideoFrame(picture, pb, timestamp, visible_rect, pixel_format_); | 408 CreateVideoFrame(picture, pb, timestamp, visible_rect, pb.pixel_format()); |
419 if (!frame) { | 409 if (!frame) { |
420 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 410 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); |
421 return; | 411 return; |
422 } | 412 } |
423 bool inserted = picture_buffers_at_display_ | 413 bool inserted = picture_buffers_at_display_ |
424 .insert(std::make_pair(picture.picture_buffer_id(), | 414 .insert(std::make_pair(picture.picture_buffer_id(), |
425 pb.client_texture_ids())) | 415 pb.client_texture_ids())) |
426 .second; | 416 .second; |
427 DCHECK(inserted); | 417 DCHECK(inserted); |
428 | 418 |
(...skipping 15 matching lines...) Expand all Loading... |
444 vda_error_counter_ = 0; | 434 vda_error_counter_ = 0; |
445 } | 435 } |
446 } | 436 } |
447 | 437 |
448 scoped_refptr<media::VideoFrame> RTCVideoDecoder::CreateVideoFrame( | 438 scoped_refptr<media::VideoFrame> RTCVideoDecoder::CreateVideoFrame( |
449 const media::Picture& picture, | 439 const media::Picture& picture, |
450 const media::PictureBuffer& pb, | 440 const media::PictureBuffer& pb, |
451 uint32_t timestamp, | 441 uint32_t timestamp, |
452 const gfx::Rect& visible_rect, | 442 const gfx::Rect& visible_rect, |
453 media::VideoPixelFormat pixel_format) { | 443 media::VideoPixelFormat pixel_format) { |
454 DCHECK(decoder_texture_target_); | 444 DCHECK(pb.texture_target()); |
455 // Convert timestamp from 90KHz to ms. | 445 // Convert timestamp from 90KHz to ms. |
456 base::TimeDelta timestamp_ms = base::TimeDelta::FromInternalValue( | 446 base::TimeDelta timestamp_ms = base::TimeDelta::FromInternalValue( |
457 base::checked_cast<uint64_t>(timestamp) * 1000 / 90); | 447 base::checked_cast<uint64_t>(timestamp) * 1000 / 90); |
458 // TODO(mcasas): The incoming data may actually be in a YUV format, but may be | 448 // TODO(mcasas): The incoming data may actually be in a YUV format, but may be |
459 // labelled as ARGB. This may or may not be reported by VDA, depending on | 449 // labelled as ARGB. This may or may not be reported by VDA, depending on |
460 // whether it provides an implementation of VDA::GetOutputFormat(). | 450 // whether it provides an implementation of VDA::GetOutputFormat(). |
461 // This prevents the compositor from messing with it, since the underlying | 451 // This prevents the compositor from messing with it, since the underlying |
462 // platform can handle the former format natively. Make sure the | 452 // platform can handle the former format natively. Make sure the |
463 // correct format is used and everyone down the line understands it. | 453 // correct format is used and everyone down the line understands it. |
464 gpu::MailboxHolder holders[media::VideoFrame::kMaxPlanes]; | 454 gpu::MailboxHolder holders[media::VideoFrame::kMaxPlanes]; |
465 for (size_t i = 0; i < pb.client_texture_ids().size(); ++i) { | 455 for (size_t i = 0; i < pb.client_texture_ids().size(); ++i) { |
466 holders[i].mailbox = pb.texture_mailbox(i); | 456 holders[i].mailbox = pb.texture_mailbox(i); |
467 holders[i].texture_target = decoder_texture_target_; | 457 holders[i].texture_target = pb.texture_target(); |
468 } | 458 } |
469 scoped_refptr<media::VideoFrame> frame = | 459 scoped_refptr<media::VideoFrame> frame = |
470 media::VideoFrame::WrapNativeTextures( | 460 media::VideoFrame::WrapNativeTextures( |
471 pixel_format, holders, | 461 pixel_format, holders, |
472 media::BindToCurrentLoop( | 462 media::BindToCurrentLoop( |
473 base::Bind(&RTCVideoDecoder::ReleaseMailbox, | 463 base::Bind(&RTCVideoDecoder::ReleaseMailbox, |
474 weak_factory_.GetWeakPtr(), factories_, | 464 weak_factory_.GetWeakPtr(), factories_, |
475 picture.picture_buffer_id(), pb.client_texture_ids())), | 465 picture.picture_buffer_id(), pb.client_texture_ids())), |
476 pb.size(), visible_rect, visible_rect.size(), timestamp_ms); | 466 pb.size(), visible_rect, visible_rect.size(), timestamp_ms); |
477 if (frame && picture.allow_overlay()) { | 467 if (frame && picture.allow_overlay()) { |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 } | 893 } |
904 | 894 |
905 void RTCVideoDecoder::ClearPendingBuffers() { | 895 void RTCVideoDecoder::ClearPendingBuffers() { |
906 // Delete WebRTC input buffers. | 896 // Delete WebRTC input buffers. |
907 for (const auto& pending_buffer : pending_buffers_) | 897 for (const auto& pending_buffer : pending_buffers_) |
908 delete[] pending_buffer.first._buffer; | 898 delete[] pending_buffer.first._buffer; |
909 pending_buffers_.clear(); | 899 pending_buffers_.clear(); |
910 } | 900 } |
911 | 901 |
912 } // namespace content | 902 } // namespace content |
OLD | NEW |