Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/common/gpu/media/android_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/android_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 11 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
| 12 #include "content/common/gpu/gpu_channel.h" | 12 #include "content/common/gpu/gpu_channel.h" |
| 13 #include "content/common/gpu/media/avda_return_on_failure.h" | 13 #include "content/common/gpu/media/avda_return_on_failure.h" |
| 14 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 14 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 15 #include "media/base/bind_to_current_loop.h" | |
| 15 #include "media/base/bitstream_buffer.h" | 16 #include "media/base/bitstream_buffer.h" |
| 16 #include "media/base/limits.h" | 17 #include "media/base/limits.h" |
| 17 #include "media/base/timestamp_constants.h" | 18 #include "media/base/timestamp_constants.h" |
| 18 #include "media/base/video_decoder_config.h" | 19 #include "media/base/video_decoder_config.h" |
| 19 #include "media/video/picture.h" | 20 #include "media/video/picture.h" |
| 20 #include "ui/gl/android/scoped_java_surface.h" | 21 #include "ui/gl/android/scoped_java_surface.h" |
| 21 #include "ui/gl/android/surface_texture.h" | 22 #include "ui/gl/android/surface_texture.h" |
| 22 #include "ui/gl/gl_bindings.h" | 23 #include "ui/gl/gl_bindings.h" |
| 23 | 24 |
| 24 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 25 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 const base::Callback<bool(void)>& make_context_current, | 80 const base::Callback<bool(void)>& make_context_current, |
| 80 scoped_ptr<BackingStrategy> strategy) | 81 scoped_ptr<BackingStrategy> strategy) |
| 81 : client_(NULL), | 82 : client_(NULL), |
| 82 make_context_current_(make_context_current), | 83 make_context_current_(make_context_current), |
| 83 codec_(media::kCodecH264), | 84 codec_(media::kCodecH264), |
| 84 is_encrypted_(false), | 85 is_encrypted_(false), |
| 85 state_(NO_ERROR), | 86 state_(NO_ERROR), |
| 86 picturebuffers_requested_(false), | 87 picturebuffers_requested_(false), |
| 87 gl_decoder_(decoder), | 88 gl_decoder_(decoder), |
| 88 strategy_(strategy.Pass()), | 89 strategy_(strategy.Pass()), |
| 90 cdm_registration_id_(0), | |
| 89 weak_this_factory_(this) {} | 91 weak_this_factory_(this) {} |
| 90 | 92 |
| 91 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 93 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| 92 DCHECK(thread_checker_.CalledOnValidThread()); | 94 DCHECK(thread_checker_.CalledOnValidThread()); |
| 95 | |
| 96 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | |
| 97 if (cdm_) { | |
| 98 DCHECK(cdm_registration_id_); | |
| 99 static_cast<media::MediaDrmBridge*>(cdm_.get()) | |
| 100 ->UnregisterPlayer(cdm_registration_id_); | |
| 101 } | |
| 102 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | |
| 93 } | 103 } |
| 94 | 104 |
| 95 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, | 105 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, |
| 96 Client* client) { | 106 Client* client) { |
| 97 DCHECK(!media_codec_); | 107 DCHECK(!media_codec_); |
| 98 DCHECK(thread_checker_.CalledOnValidThread()); | 108 DCHECK(thread_checker_.CalledOnValidThread()); |
| 99 TRACE_EVENT0("media", "AVDA::Initialize"); | 109 TRACE_EVENT0("media", "AVDA::Initialize"); |
| 100 | 110 |
| 101 DVLOG(1) << __FUNCTION__ << ": profile:" << config.profile | 111 DVLOG(1) << __FUNCTION__ << ": profile:" << config.profile |
| 102 << " is_encrypted:" << config.is_encrypted; | 112 << " is_encrypted:" << config.is_encrypted; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 131 return false; | 141 return false; |
| 132 } | 142 } |
| 133 | 143 |
| 134 if (!gl_decoder_) { | 144 if (!gl_decoder_) { |
| 135 LOG(ERROR) << "Failed to get gles2 decoder instance."; | 145 LOG(ERROR) << "Failed to get gles2 decoder instance."; |
| 136 return false; | 146 return false; |
| 137 } | 147 } |
| 138 | 148 |
| 139 strategy_->Initialize(this); | 149 strategy_->Initialize(this); |
| 140 | 150 |
| 141 surface_texture_ = strategy_->CreateSurfaceTexture(); | 151 surface_texture_ = strategy_->CreateSurfaceTexture(); |
|
liberato (no reviews please)
2015/12/04 16:20:11
how does this fit with |needs_protected_surface|?
Tima Vaisburd
2015/12/04 20:12:01
Can the protected surface be deferred in the subse
liberato (no reviews please)
2015/12/04 21:40:13
sure, i didn't mean that protected surfaces have t
| |
| 142 | 152 |
| 143 if (!ConfigureMediaCodec()) { | 153 // For encrypted streams we postpone configuration until MediaCrypto is |
|
liberato (no reviews please)
2015/12/04 16:20:11
all of this would become a call to FinishInitializ
| |
| 144 LOG(ERROR) << "Failed to create MediaCodec instance."; | 154 // available. |
| 145 return false; | 155 if (is_encrypted_) |
| 146 } | 156 return true; |
| 147 | 157 |
| 148 return true; | 158 return ConfigureMediaCodec(); |
| 149 } | 159 } |
| 150 | 160 |
| 151 void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) { | 161 void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) { |
|
xhwang
2015/12/04 20:22:03
This should only be called after Initialize(), oth
liberato (no reviews please)
2015/12/04 21:40:13
maybe additional values for |state_| are useful he
Tima Vaisburd
2015/12/04 22:54:51
Yes, I agree. For now I DCHECKed client_, I'll try
| |
| 152 DVLOG(2) << __FUNCTION__ << ": " << cdm_id; | 162 DVLOG(2) << __FUNCTION__ << ": " << cdm_id; |
| 153 | 163 |
| 154 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 164 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 155 // TODO(timav): Implement CDM setting here. See http://crbug.com/542417 | 165 using media::MediaDrmBridge; |
| 156 scoped_refptr<media::MediaKeys> cdm = media::MojoCdmService::GetCdm(cdm_id); | 166 |
| 157 DCHECK(cdm); | 167 if (cdm_) { |
| 158 #endif | 168 NOTREACHED() << "We do not support resetting CDM."; |
| 169 NotifyCdmAttached(false); | |
| 170 return; | |
| 171 } | |
| 172 | |
| 173 cdm_ = media::MojoCdmService::GetCdm(cdm_id); | |
| 174 DCHECK(cdm_); | |
| 175 | |
| 176 // On Android platform the MediaKeys fill be its subclass MediaDrmBridge. | |
|
liberato (no reviews please)
2015/12/04 16:20:11
s/fill/will
Tima Vaisburd
2015/12/04 20:12:01
Done.
| |
| 177 MediaDrmBridge* drm_bridge = static_cast<MediaDrmBridge*>(cdm_.get()); | |
| 178 | |
| 179 // Register CDM callbacks. The callbacks registered will be posted back to | |
| 180 // this thread via BindToCurrentLoop. | |
| 181 | |
| 182 // Since |this| holds a reference to the |cdm_|, by the time the CDM is | |
| 183 // destructed, UnregisterPlayer() must have been called and |this| has been | |
| 184 // destructed as well. So the |cdm_unset_cb| will never have a chance to be | |
| 185 // called. | |
| 186 // TODO(xhwang): Remove |cdm_unset_cb| after it's not used on all platforms. | |
| 187 cdm_registration_id_ = drm_bridge->RegisterPlayer( | |
| 188 media::BindToCurrentLoop( | |
| 189 base::Bind(&AndroidVideoDecodeAccelerator::OnCdmKeyAdded, | |
| 190 weak_this_factory_.GetWeakPtr())), | |
| 191 base::Bind(&base::DoNothing)); | |
| 192 | |
| 193 drm_bridge->SetMediaCryptoReadyCB(media::BindToCurrentLoop( | |
| 194 base::Bind(&AndroidVideoDecodeAccelerator::OnCdmMediaCryptoReady, | |
| 195 weak_this_factory_.GetWeakPtr()))); | |
| 196 | |
| 197 // Postpone NotifyCdmAttached() call till we create the MediaCodec after | |
| 198 // OnCdmMediaCryptoReady(). | |
| 199 | |
| 200 #else | |
| 159 | 201 |
| 160 NOTIMPLEMENTED(); | 202 NOTIMPLEMENTED(); |
| 161 NotifyCdmAttached(false); | 203 NotifyCdmAttached(false); |
| 204 | |
| 205 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | |
| 162 } | 206 } |
| 163 | 207 |
| 164 void AndroidVideoDecodeAccelerator::DoIOTask() { | 208 void AndroidVideoDecodeAccelerator::DoIOTask() { |
| 165 DCHECK(thread_checker_.CalledOnValidThread()); | 209 DCHECK(thread_checker_.CalledOnValidThread()); |
| 166 TRACE_EVENT0("media", "AVDA::DoIOTask"); | 210 TRACE_EVENT0("media", "AVDA::DoIOTask"); |
| 167 if (state_ == ERROR) { | 211 if (state_ == ERROR) { |
| 168 return; | 212 return; |
| 169 } | 213 } |
| 170 | 214 |
|
liberato (no reviews please)
2015/12/04 16:20:11
might want to check for |media_codec_| here, since
Tima Vaisburd
2015/12/04 20:12:01
Please explain how. I've assumed that initializati
liberato (no reviews please)
2015/12/04 21:40:13
yeah, i suppose you're right. |init_cb_| doesn't
| |
| 171 QueueInput(); | 215 QueueInput(); |
| 172 while (DequeueOutput()) | 216 while (DequeueOutput()) |
| 173 ; | 217 ; |
| 174 } | 218 } |
| 175 | 219 |
| 176 void AndroidVideoDecodeAccelerator::QueueInput() { | 220 void AndroidVideoDecodeAccelerator::QueueInput() { |
| 177 DCHECK(thread_checker_.CalledOnValidThread()); | 221 DCHECK(thread_checker_.CalledOnValidThread()); |
| 178 TRACE_EVENT0("media", "AVDA::QueueInput"); | 222 TRACE_EVENT0("media", "AVDA::QueueInput"); |
| 179 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance) | 223 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance) |
| 180 return; | 224 return; |
| 181 if (pending_bitstream_buffers_.empty()) | 225 if (pending_bitstream_buffers_.empty()) |
| 182 return; | 226 return; |
| 183 | 227 |
| 184 int input_buf_index = 0; | 228 int input_buf_index = 0; |
| 185 media::MediaCodecStatus status = | 229 media::MediaCodecStatus status = |
| 186 media_codec_->DequeueInputBuffer(NoWaitTimeOut(), &input_buf_index); | 230 media_codec_->DequeueInputBuffer(NoWaitTimeOut(), &input_buf_index); |
| 187 if (status != media::MEDIA_CODEC_OK) { | 231 if (status != media::MEDIA_CODEC_OK) { |
| 188 DCHECK(status == media::MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER || | 232 DCHECK(status == media::MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER || |
| 189 status == media::MEDIA_CODEC_ERROR); | 233 status == media::MEDIA_CODEC_ERROR); |
| 190 return; | 234 return; |
| 191 } | 235 } |
| 192 | 236 |
| 193 base::Time queued_time = pending_bitstream_buffers_.front().second; | 237 base::Time queued_time = pending_bitstream_buffers_.front().second; |
| 194 UMA_HISTOGRAM_TIMES("Media.AVDA.InputQueueTime", | 238 UMA_HISTOGRAM_TIMES("Media.AVDA.InputQueueTime", |
| 195 base::Time::Now() - queued_time); | 239 base::Time::Now() - queued_time); |
| 196 media::BitstreamBuffer bitstream_buffer = | 240 media::BitstreamBuffer bitstream_buffer = |
| 197 pending_bitstream_buffers_.front().first; | 241 pending_bitstream_buffers_.front().first; |
| 198 pending_bitstream_buffers_.pop(); | |
| 199 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", | |
| 200 pending_bitstream_buffers_.size()); | |
| 201 | 242 |
| 202 if (bitstream_buffer.id() == -1) { | 243 if (bitstream_buffer.id() == -1) { |
| 244 pending_bitstream_buffers_.pop(); | |
| 245 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", | |
| 246 pending_bitstream_buffers_.size()); | |
| 247 | |
| 203 media_codec_->QueueEOS(input_buf_index); | 248 media_codec_->QueueEOS(input_buf_index); |
| 204 return; | 249 return; |
| 205 } | 250 } |
| 206 | 251 |
| 207 scoped_ptr<base::SharedMemory> shm( | 252 scoped_ptr<base::SharedMemory> shm( |
| 208 new base::SharedMemory(bitstream_buffer.handle(), true)); | 253 new base::SharedMemory(bitstream_buffer.handle(), true)); |
| 209 RETURN_ON_FAILURE(this, shm->Map(bitstream_buffer.size()), | 254 RETURN_ON_FAILURE(this, shm->Map(bitstream_buffer.size()), |
| 210 "Failed to SharedMemory::Map()", UNREADABLE_INPUT); | 255 "Failed to SharedMemory::Map()", UNREADABLE_INPUT); |
| 211 | 256 |
| 212 const base::TimeDelta presentation_timestamp = | 257 const base::TimeDelta presentation_timestamp = |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 235 } else { | 280 } else { |
| 236 status = media_codec_->QueueSecureInputBuffer( | 281 status = media_codec_->QueueSecureInputBuffer( |
| 237 input_buf_index, memory, bitstream_buffer.size(), key_id, iv, | 282 input_buf_index, memory, bitstream_buffer.size(), key_id, iv, |
| 238 subsamples, presentation_timestamp); | 283 subsamples, presentation_timestamp); |
| 239 } | 284 } |
| 240 | 285 |
| 241 DVLOG(2) << __FUNCTION__ | 286 DVLOG(2) << __FUNCTION__ |
| 242 << ": QueueInputBuffer: pts:" << presentation_timestamp | 287 << ": QueueInputBuffer: pts:" << presentation_timestamp |
| 243 << " status:" << status; | 288 << " status:" << status; |
| 244 | 289 |
| 290 if (status == media::MEDIA_CODEC_NO_KEY) | |
| 291 return; // keep trying to enqueue the front pending buffer | |
|
xhwang
2015/12/04 20:22:03
This is an important event. Add a log here.
Tima Vaisburd
2015/12/04 22:54:51
The log line above already prints the status, unle
xhwang
2015/12/04 23:24:09
We need a log with higher level for unexpected eve
Tima Vaisburd
2015/12/05 01:35:25
Done, but it would be better to have states and ha
| |
| 292 | |
| 293 pending_bitstream_buffers_.pop(); | |
| 294 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", | |
| 295 pending_bitstream_buffers_.size()); | |
| 296 | |
| 245 RETURN_ON_FAILURE(this, status == media::MEDIA_CODEC_OK, | 297 RETURN_ON_FAILURE(this, status == media::MEDIA_CODEC_OK, |
| 246 "Failed to QueueInputBuffer: " << status, PLATFORM_FAILURE); | 298 "Failed to QueueInputBuffer: " << status, PLATFORM_FAILURE); |
| 247 | 299 |
| 248 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output | 300 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output |
| 249 // will be returned from the bitstream buffer. However, MediaCodec API is | 301 // will be returned from the bitstream buffer. However, MediaCodec API is |
| 250 // not enough to guarantee it. | 302 // not enough to guarantee it. |
| 251 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to | 303 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to |
| 252 // keep getting more bitstreams from the client, and throttle them by using | 304 // keep getting more bitstreams from the client, and throttle them by using |
| 253 // |bitstreams_notified_in_advance_|. | 305 // |bitstreams_notified_in_advance_|. |
| 254 // TODO(dwkang): check if there is a way to remove this workaround. | 306 // TODO(dwkang): check if there is a way to remove this workaround. |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); | 550 Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); |
| 499 } | 551 } |
| 500 | 552 |
| 501 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() { | 553 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() { |
| 502 DCHECK(thread_checker_.CalledOnValidThread()); | 554 DCHECK(thread_checker_.CalledOnValidThread()); |
| 503 DCHECK(surface_texture_.get()); | 555 DCHECK(surface_texture_.get()); |
| 504 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec"); | 556 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec"); |
| 505 | 557 |
| 506 gfx::ScopedJavaSurface surface(surface_texture_.get()); | 558 gfx::ScopedJavaSurface surface(surface_texture_.get()); |
| 507 | 559 |
| 560 jobject media_crypto = media_crypto_ ? media_crypto_->obj() : nullptr; | |
| 561 | |
| 508 // Pass a dummy 320x240 canvas size and let the codec signal the real size | 562 // Pass a dummy 320x240 canvas size and let the codec signal the real size |
| 509 // when it's known from the bitstream. | 563 // when it's known from the bitstream. |
| 510 media_codec_.reset(media::VideoCodecBridge::CreateDecoder( | 564 media_codec_.reset(media::VideoCodecBridge::CreateDecoder( |
| 511 codec_, false, gfx::Size(320, 240), surface.j_surface().obj(), NULL)); | 565 codec_, false, gfx::Size(320, 240), surface.j_surface().obj(), |
| 566 media_crypto)); | |
| 512 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); | 567 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); |
| 513 if (!media_codec_) | 568 if (!media_codec_) { |
| 569 LOG(ERROR) << "Failed to create MediaCodec instance."; | |
| 514 return false; | 570 return false; |
| 571 } | |
| 515 | 572 |
| 516 io_timer_.Start(FROM_HERE, | 573 io_timer_.Start(FROM_HERE, |
| 517 DecodePollDelay(), | 574 DecodePollDelay(), |
| 518 this, | 575 this, |
| 519 &AndroidVideoDecodeAccelerator::DoIOTask); | 576 &AndroidVideoDecodeAccelerator::DoIOTask); |
| 520 return true; | 577 return true; |
| 521 } | 578 } |
| 522 | 579 |
| 523 void AndroidVideoDecodeAccelerator::Reset() { | 580 void AndroidVideoDecodeAccelerator::Reset() { |
| 524 DCHECK(thread_checker_.CalledOnValidThread()); | 581 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 599 | 656 |
| 600 void AndroidVideoDecodeAccelerator::PostError( | 657 void AndroidVideoDecodeAccelerator::PostError( |
| 601 const ::tracked_objects::Location& from_here, | 658 const ::tracked_objects::Location& from_here, |
| 602 media::VideoDecodeAccelerator::Error error) { | 659 media::VideoDecodeAccelerator::Error error) { |
| 603 base::MessageLoop::current()->PostTask( | 660 base::MessageLoop::current()->PostTask( |
| 604 from_here, base::Bind(&AndroidVideoDecodeAccelerator::NotifyError, | 661 from_here, base::Bind(&AndroidVideoDecodeAccelerator::NotifyError, |
| 605 weak_this_factory_.GetWeakPtr(), error)); | 662 weak_this_factory_.GetWeakPtr(), error)); |
| 606 state_ = ERROR; | 663 state_ = ERROR; |
| 607 } | 664 } |
| 608 | 665 |
| 666 void AndroidVideoDecodeAccelerator::OnCdmMediaCryptoReady( | |
| 667 media::MediaDrmBridge::JavaObjectPtr media_crypto, | |
| 668 bool needs_protected_surface) { | |
| 669 DVLOG(1) << __FUNCTION__; | |
| 670 | |
| 671 DCHECK(media_crypto); | |
|
xhwang
2015/12/04 20:22:03
With my CL, |media_crypto| can actually be null if
Tima Vaisburd
2015/12/04 22:54:51
Done.
| |
| 672 DCHECK(!media_crypto->is_null()); | |
|
liberato (no reviews please)
2015/12/04 16:20:11
DCHECK(!media_codec)
Tima Vaisburd
2015/12/04 20:12:01
I added this DCHECK, but ConfigureMediaCodec() doe
liberato (no reviews please)
2015/12/04 21:40:13
it depends if we've sent in any buffers.
| |
| 673 | |
| 674 media_crypto_ = media_crypto.Pass(); | |
| 675 | |
| 676 // Configure here instead of in Initialize() | |
| 677 const bool success = ConfigureMediaCodec(); | |
| 678 NotifyCdmAttached(success); | |
|
liberato (no reviews please)
2015/12/04 16:20:11
outside the scope of this CL, but NotifyInitializa
Tima Vaisburd
2015/12/04 20:12:01
I heard that there is a work on Version 2 which wi
liberato (no reviews please)
2015/12/04 21:40:13
yes, that's why i think it's outside the scope of
| |
| 679 } | |
| 680 | |
| 681 void AndroidVideoDecodeAccelerator::OnCdmKeyAdded() { | |
| 682 DVLOG(1) << __FUNCTION__; | |
|
xhwang
2015/12/04 20:22:03
NOTIMPLEMENTED()
Also add a TODO to finish this p
Tima Vaisburd
2015/12/04 22:54:51
Since in this CL we do not try to stop the decodin
xhwang
2015/12/04 23:24:09
I don't fully understand how this works. What's th
Tima Vaisburd
2015/12/05 01:35:25
Added some comments, please take a look.
| |
| 683 } | |
| 684 | |
| 609 void AndroidVideoDecodeAccelerator::NotifyCdmAttached(bool success) { | 685 void AndroidVideoDecodeAccelerator::NotifyCdmAttached(bool success) { |
| 610 client_->NotifyCdmAttached(success); | 686 client_->NotifyCdmAttached(success); |
| 611 } | 687 } |
| 612 | 688 |
| 613 void AndroidVideoDecodeAccelerator::NotifyPictureReady( | 689 void AndroidVideoDecodeAccelerator::NotifyPictureReady( |
| 614 const media::Picture& picture) { | 690 const media::Picture& picture) { |
| 615 client_->PictureReady(picture); | 691 client_->PictureReady(picture); |
| 616 } | 692 } |
| 617 | 693 |
| 618 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( | 694 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 // software fallback for H264 on Android anyway. | 742 // software fallback for H264 on Android anyway. |
| 667 profile.max_resolution.SetSize(3840, 2160); | 743 profile.max_resolution.SetSize(3840, 2160); |
| 668 profiles.push_back(profile); | 744 profiles.push_back(profile); |
| 669 } | 745 } |
| 670 #endif | 746 #endif |
| 671 | 747 |
| 672 return profiles; | 748 return profiles; |
| 673 } | 749 } |
| 674 | 750 |
| 675 } // namespace content | 751 } // namespace content |
| OLD | NEW |