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 "media/base/android/media_decoder_job.h" | 5 #include "media/base/android/media_decoder_job.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/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 // Since the decoder job is not decoding data, we can safely destroy | 195 // Since the decoder job is not decoding data, we can safely destroy |
196 // |media_codec_bridge_|. | 196 // |media_codec_bridge_|. |
197 ReleaseMediaCodecBridge(); | 197 ReleaseMediaCodecBridge(); |
198 return; | 198 return; |
199 } | 199 } |
200 | 200 |
201 // Release |media_codec_bridge_| once decoding is completed. | 201 // Release |media_codec_bridge_| once decoding is completed. |
202 release_resources_pending_ = true; | 202 release_resources_pending_ = true; |
203 } | 203 } |
204 | 204 |
205 bool MediaDecoderJob::SetDemuxerConfigs(const DemuxerConfigs& configs) { | |
206 bool config_changed = AreDemuxerConfigsChanged(configs); | |
207 if (config_changed) | |
208 UpdateDemuxerConfigs(configs); | |
209 return config_changed; | |
210 } | |
211 | |
212 base::android::ScopedJavaLocalRef<jobject> MediaDecoderJob::GetMediaCrypto() { | 205 base::android::ScopedJavaLocalRef<jobject> MediaDecoderJob::GetMediaCrypto() { |
213 base::android::ScopedJavaLocalRef<jobject> media_crypto; | 206 base::android::ScopedJavaLocalRef<jobject> media_crypto; |
214 if (drm_bridge_) | 207 if (drm_bridge_) |
215 media_crypto = drm_bridge_->GetMediaCrypto(); | 208 media_crypto = drm_bridge_->GetMediaCrypto(); |
216 return media_crypto; | 209 return media_crypto; |
217 } | 210 } |
218 | 211 |
219 void MediaDecoderJob::Release() { | 212 void MediaDecoderJob::Release() { |
220 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 213 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
221 DVLOG(1) << __FUNCTION__; | 214 DVLOG(1) << __FUNCTION__; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 base::TimeDelta start_presentation_timestamp) { | 320 base::TimeDelta start_presentation_timestamp) { |
328 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 321 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
329 DCHECK(!decode_cb_.is_null()); | 322 DCHECK(!decode_cb_.is_null()); |
330 | 323 |
331 RequestCurrentChunkIfEmpty(); | 324 RequestCurrentChunkIfEmpty(); |
332 const AccessUnit& access_unit = CurrentAccessUnit(); | 325 const AccessUnit& access_unit = CurrentAccessUnit(); |
333 if (CurrentAccessUnit().status == DemuxerStream::kConfigChanged) { | 326 if (CurrentAccessUnit().status == DemuxerStream::kConfigChanged) { |
334 int index = CurrentReceivedDataChunkIndex(); | 327 int index = CurrentReceivedDataChunkIndex(); |
335 const DemuxerConfigs& configs = received_data_[index].demuxer_configs[0]; | 328 const DemuxerConfigs& configs = received_data_[index].demuxer_configs[0]; |
336 bool reconfigure_needed = IsCodecReconfigureNeeded(configs); | 329 bool reconfigure_needed = IsCodecReconfigureNeeded(configs); |
337 // TODO(qinmin): |config_changed_cb_| should be run after draining finishes. | 330 SetDemuxerConfigs(configs); |
338 // http://crbug.com/381975. | |
339 if (SetDemuxerConfigs(configs)) | |
340 config_changed_cb_.Run(); | |
341 if (!drain_decoder_) { | 331 if (!drain_decoder_) { |
342 // If we haven't decoded any data yet, just skip the current access unit | 332 // If we haven't decoded any data yet, just skip the current access unit |
343 // and request the MediaCodec to be recreated on next Decode(). | 333 // and request the MediaCodec to be recreated on next Decode(). |
344 if (skip_eos_enqueue_ || !reconfigure_needed) { | 334 if (skip_eos_enqueue_ || !reconfigure_needed) { |
345 need_to_reconfig_decoder_job_ = | 335 need_to_reconfig_decoder_job_ = |
346 need_to_reconfig_decoder_job_ || reconfigure_needed; | 336 need_to_reconfig_decoder_job_ || reconfigure_needed; |
| 337 // Report MEDIA_CODEC_OK status so decoder will continue decoding and |
| 338 // MEDIA_CODEC_OUTPUT_FORMAT_CHANGED status will come later. |
347 ui_task_runner_->PostTask(FROM_HERE, base::Bind( | 339 ui_task_runner_->PostTask(FROM_HERE, base::Bind( |
348 &MediaDecoderJob::OnDecodeCompleted, base::Unretained(this), | 340 &MediaDecoderJob::OnDecodeCompleted, base::Unretained(this), |
349 MEDIA_CODEC_OUTPUT_FORMAT_CHANGED, kNoTimestamp(), kNoTimestamp())); | 341 MEDIA_CODEC_OK, kNoTimestamp(), kNoTimestamp())); |
350 return; | 342 return; |
351 } | 343 } |
352 // Start draining the decoder so that all the remaining frames are | 344 // Start draining the decoder so that all the remaining frames are |
353 // rendered. | 345 // rendered. |
354 drain_decoder_ = true; | 346 drain_decoder_ = true; |
355 } | 347 } |
356 } | 348 } |
357 | 349 |
358 DCHECK(!(needs_flush_ && drain_decoder_)); | 350 DCHECK(!(needs_flush_ && drain_decoder_)); |
359 decoder_task_runner_->PostTask(FROM_HERE, base::Bind( | 351 decoder_task_runner_->PostTask(FROM_HERE, base::Bind( |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 case MEDIA_CODEC_ERROR: | 527 case MEDIA_CODEC_ERROR: |
536 // Do nothing. | 528 // Do nothing. |
537 break; | 529 break; |
538 }; | 530 }; |
539 | 531 |
540 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM && drain_decoder_) { | 532 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM && drain_decoder_) { |
541 OnDecoderDrained(); | 533 OnDecoderDrained(); |
542 status = MEDIA_CODEC_OK; | 534 status = MEDIA_CODEC_OK; |
543 } | 535 } |
544 | 536 |
| 537 if (status == MEDIA_CODEC_OUTPUT_FORMAT_CHANGED && UpdateOutputFormat()) |
| 538 config_changed_cb_.Run(); |
| 539 |
545 if (release_resources_pending_) { | 540 if (release_resources_pending_) { |
546 ReleaseMediaCodecBridge(); | 541 ReleaseMediaCodecBridge(); |
547 release_resources_pending_ = false; | 542 release_resources_pending_ = false; |
548 if (drain_decoder_) | 543 if (drain_decoder_) |
549 OnDecoderDrained(); | 544 OnDecoderDrained(); |
550 } | 545 } |
551 | 546 |
552 stop_decode_pending_ = false; | 547 stop_decode_pending_ = false; |
553 base::ResetAndReturn(&decode_cb_).Run( | 548 base::ResetAndReturn(&decode_cb_).Run( |
554 status, current_presentation_timestamp, max_presentation_timestamp); | 549 status, current_presentation_timestamp, max_presentation_timestamp); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 return CreateMediaCodecBridgeInternal(); | 631 return CreateMediaCodecBridgeInternal(); |
637 } | 632 } |
638 | 633 |
639 bool MediaDecoderJob::IsCodecReconfigureNeeded( | 634 bool MediaDecoderJob::IsCodecReconfigureNeeded( |
640 const DemuxerConfigs& configs) const { | 635 const DemuxerConfigs& configs) const { |
641 if (!AreDemuxerConfigsChanged(configs)) | 636 if (!AreDemuxerConfigsChanged(configs)) |
642 return false; | 637 return false; |
643 return true; | 638 return true; |
644 } | 639 } |
645 | 640 |
| 641 bool MediaDecoderJob::UpdateOutputFormat() { |
| 642 return false; |
| 643 } |
| 644 |
646 void MediaDecoderJob::ReleaseMediaCodecBridge() { | 645 void MediaDecoderJob::ReleaseMediaCodecBridge() { |
647 if (!media_codec_bridge_) | 646 if (!media_codec_bridge_) |
648 return; | 647 return; |
649 | 648 |
650 media_codec_bridge_.reset(); | 649 media_codec_bridge_.reset(); |
651 input_buf_index_ = -1; | 650 input_buf_index_ = -1; |
652 } | 651 } |
653 | 652 |
654 } // namespace media | 653 } // namespace media |
OLD | NEW |