OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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_codec_decoder.h" | 5 #include "media/base/android/media_codec_decoder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 | 33 |
34 MediaCodecDecoder::MediaCodecDecoder( | 34 MediaCodecDecoder::MediaCodecDecoder( |
35 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, | 35 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, |
36 const base::Closure& external_request_data_cb, | 36 const base::Closure& external_request_data_cb, |
37 const base::Closure& starvation_cb, | 37 const base::Closure& starvation_cb, |
38 const base::Closure& stop_done_cb, | 38 const base::Closure& stop_done_cb, |
39 const base::Closure& error_cb, | 39 const base::Closure& error_cb, |
40 const char* decoder_thread_name) | 40 const char* decoder_thread_name) |
41 : media_task_runner_(media_task_runner), | 41 : media_task_runner_(media_task_runner), |
42 decoder_thread_(decoder_thread_name), | 42 decoder_thread_(decoder_thread_name), |
| 43 needs_reconfigure_(false), |
43 external_request_data_cb_(external_request_data_cb), | 44 external_request_data_cb_(external_request_data_cb), |
44 starvation_cb_(starvation_cb), | 45 starvation_cb_(starvation_cb), |
45 stop_done_cb_(stop_done_cb), | 46 stop_done_cb_(stop_done_cb), |
46 error_cb_(error_cb), | 47 error_cb_(error_cb), |
47 state_(kStopped), | 48 state_(kStopped), |
48 eos_enqueued_(false), | 49 eos_enqueued_(false), |
49 completed_(false), | 50 completed_(false), |
50 last_frame_posted_(false), | 51 last_frame_posted_(false), |
51 is_data_request_in_progress_(false), | 52 is_data_request_in_progress_(false), |
52 is_incoming_data_invalid_(false), | 53 is_incoming_data_invalid_(false), |
(...skipping 22 matching lines...) Expand all Loading... |
75 | 76 |
76 const char* MediaCodecDecoder::class_name() const { | 77 const char* MediaCodecDecoder::class_name() const { |
77 return "Decoder"; | 78 return "Decoder"; |
78 } | 79 } |
79 | 80 |
80 void MediaCodecDecoder::ReleaseDecoderResources() { | 81 void MediaCodecDecoder::ReleaseDecoderResources() { |
81 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 82 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
82 | 83 |
83 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 84 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
84 | 85 |
| 86 // Set [kInEmergencyStop| state to block already posted ProcessNextFrame(). |
| 87 SetState(kInEmergencyStop); |
| 88 |
85 decoder_thread_.Stop(); // synchronous | 89 decoder_thread_.Stop(); // synchronous |
86 state_ = kStopped; | 90 state_ = kStopped; |
87 media_codec_bridge_.reset(); | 91 media_codec_bridge_.reset(); |
88 } | 92 } |
89 | 93 |
90 void MediaCodecDecoder::Flush() { | 94 void MediaCodecDecoder::Flush() { |
91 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 95 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
92 | 96 |
93 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 97 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
94 | 98 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 183 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
180 | 184 |
181 if (GetState() == kError) { | 185 if (GetState() == kError) { |
182 DVLOG(0) << class_name() << "::" << __FUNCTION__ << ": wrong state kError"; | 186 DVLOG(0) << class_name() << "::" << __FUNCTION__ << ": wrong state kError"; |
183 return CONFIG_FAILURE; | 187 return CONFIG_FAILURE; |
184 } | 188 } |
185 | 189 |
186 // Here I assume that OnDemuxerConfigsAvailable won't come | 190 // Here I assume that OnDemuxerConfigsAvailable won't come |
187 // in the middle of demuxer data. | 191 // in the middle of demuxer data. |
188 | 192 |
| 193 if (needs_reconfigure_) { |
| 194 DVLOG(1) << class_name() << "::" << __FUNCTION__ |
| 195 << ": needs reconfigure, deleting MediaCodec"; |
| 196 needs_reconfigure_ = false; |
| 197 media_codec_bridge_.reset(); |
| 198 |
| 199 // Shall we move |delayed_buffers_| from VideoDecoder to Decoder class? |
| 200 ClearDelayedBuffers(); |
| 201 } |
| 202 |
189 MediaCodecDecoder::ConfigStatus result; | 203 MediaCodecDecoder::ConfigStatus result; |
190 if (media_codec_bridge_) { | 204 if (media_codec_bridge_) { |
191 DVLOG(1) << class_name() << "::" << __FUNCTION__ | 205 DVLOG(1) << class_name() << "::" << __FUNCTION__ |
192 << ": reconfiguration is not required, ignoring"; | 206 << ": reconfiguration is not required, ignoring"; |
193 result = CONFIG_OK; | 207 result = CONFIG_OK; |
194 } else { | 208 } else { |
195 result = ConfigureInternal(); | 209 result = ConfigureInternal(); |
196 | 210 |
197 #ifndef NDEBUG | 211 #ifndef NDEBUG |
198 // We check and reset |verify_next_frame_is_key_| on Decoder thread. | 212 // We check and reset |verify_next_frame_is_key_| on Decoder thread. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 276 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
263 | 277 |
264 if (GetState() == kError) { | 278 if (GetState() == kError) { |
265 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 279 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
266 << ": wrong state kError, ignoring"; | 280 << ": wrong state kError, ignoring"; |
267 return; | 281 return; |
268 } | 282 } |
269 | 283 |
270 // After this method returns, decoder thread will not be running. | 284 // After this method returns, decoder thread will not be running. |
271 | 285 |
| 286 // Set [kInEmergencyStop| state to block already posted ProcessNextFrame(). |
| 287 SetState(kInEmergencyStop); |
| 288 |
272 decoder_thread_.Stop(); // synchronous | 289 decoder_thread_.Stop(); // synchronous |
273 state_ = kStopped; | 290 state_ = kStopped; |
274 | 291 |
275 // Shall we move |delayed_buffers_| from VideoDecoder to Decoder class? | 292 // Shall we move |delayed_buffers_| from VideoDecoder to Decoder class? |
276 ReleaseDelayedBuffers(); | 293 ReleaseDelayedBuffers(); |
277 } | 294 } |
278 | 295 |
279 void MediaCodecDecoder::RequestToStop() { | 296 void MediaCodecDecoder::RequestToStop() { |
280 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 297 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
281 | 298 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 bool aborted_data = | 343 bool aborted_data = |
327 !data.access_units.empty() && | 344 !data.access_units.empty() && |
328 data.access_units.back().status == DemuxerStream::kAborted; | 345 data.access_units.back().status == DemuxerStream::kAborted; |
329 | 346 |
330 #ifndef NDEBUG | 347 #ifndef NDEBUG |
331 const char* explain_if_skipped = | 348 const char* explain_if_skipped = |
332 is_incoming_data_invalid_ ? " skipped as invalid" | 349 is_incoming_data_invalid_ ? " skipped as invalid" |
333 : (aborted_data ? " skipped as aborted" : ""); | 350 : (aborted_data ? " skipped as aborted" : ""); |
334 | 351 |
335 for (const auto& unit : data.access_units) | 352 for (const auto& unit : data.access_units) |
336 DVLOG(1) << class_name() << "::" << __FUNCTION__ << explain_if_skipped | 353 DVLOG(2) << class_name() << "::" << __FUNCTION__ << explain_if_skipped |
337 << " au: " << unit; | 354 << " au: " << unit; |
338 for (const auto& configs : data.demuxer_configs) | 355 for (const auto& configs : data.demuxer_configs) |
339 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " configs: " << configs; | 356 DVLOG(2) << class_name() << "::" << __FUNCTION__ << " configs: " << configs; |
340 #endif | 357 #endif |
341 | 358 |
342 if (!is_incoming_data_invalid_ && !aborted_data) | 359 if (!is_incoming_data_invalid_ && !aborted_data) |
343 au_queue_.PushBack(data); | 360 au_queue_.PushBack(data); |
344 | 361 |
345 is_incoming_data_invalid_ = false; | 362 is_incoming_data_invalid_ = false; |
346 is_data_request_in_progress_ = false; | 363 is_data_request_in_progress_ = false; |
347 | 364 |
348 // Do not request data if we got kAborted. There is no point to request the | 365 // Do not request data if we got kAborted. There is no point to request the |
349 // data after kAborted and before the OnDemuxerSeekDone. | 366 // data after kAborted and before the OnDemuxerSeekDone. |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 | 647 |
631 return status != MEDIA_CODEC_ERROR; | 648 return status != MEDIA_CODEC_ERROR; |
632 } | 649 } |
633 | 650 |
634 MediaCodecDecoder::DecoderState MediaCodecDecoder::GetState() const { | 651 MediaCodecDecoder::DecoderState MediaCodecDecoder::GetState() const { |
635 base::AutoLock lock(state_lock_); | 652 base::AutoLock lock(state_lock_); |
636 return state_; | 653 return state_; |
637 } | 654 } |
638 | 655 |
639 void MediaCodecDecoder::SetState(DecoderState state) { | 656 void MediaCodecDecoder::SetState(DecoderState state) { |
640 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " " << state; | 657 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " " << AsString(state); |
641 | 658 |
642 base::AutoLock lock(state_lock_); | 659 base::AutoLock lock(state_lock_); |
643 state_ = state; | 660 state_ = state; |
644 } | 661 } |
645 | 662 |
646 #undef RETURN_STRING | 663 #undef RETURN_STRING |
647 #define RETURN_STRING(x) \ | 664 #define RETURN_STRING(x) \ |
648 case x: \ | 665 case x: \ |
649 return #x; | 666 return #x; |
650 | 667 |
651 const char* MediaCodecDecoder::AsString(DecoderState state) { | 668 const char* MediaCodecDecoder::AsString(DecoderState state) { |
652 switch (state) { | 669 switch (state) { |
653 RETURN_STRING(kStopped); | 670 RETURN_STRING(kStopped); |
654 RETURN_STRING(kPrefetching); | 671 RETURN_STRING(kPrefetching); |
655 RETURN_STRING(kPrefetched); | 672 RETURN_STRING(kPrefetched); |
656 RETURN_STRING(kRunning); | 673 RETURN_STRING(kRunning); |
657 RETURN_STRING(kStopping); | 674 RETURN_STRING(kStopping); |
| 675 RETURN_STRING(kInEmergencyStop); |
658 RETURN_STRING(kError); | 676 RETURN_STRING(kError); |
659 default: | 677 default: |
660 return "Unknown DecoderState"; | 678 return "Unknown DecoderState"; |
661 } | 679 } |
662 } | 680 } |
663 | 681 |
664 #undef RETURN_STRING | 682 #undef RETURN_STRING |
665 | 683 |
666 } // namespace media | 684 } // namespace media |
OLD | NEW |