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 |
91 SetState(kStopped); | |
87 media_codec_bridge_.reset(); | 92 media_codec_bridge_.reset(); |
88 } | 93 } |
89 | 94 |
90 void MediaCodecDecoder::Flush() { | 95 void MediaCodecDecoder::Flush() { |
91 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 96 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
92 | 97 |
93 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 98 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
94 | 99 |
95 DCHECK_EQ(GetState(), kStopped); | 100 DCHECK_EQ(GetState(), kStopped); |
96 | 101 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
176 MediaCodecDecoder::ConfigStatus MediaCodecDecoder::Configure() { | 181 MediaCodecDecoder::ConfigStatus MediaCodecDecoder::Configure() { |
177 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 182 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
178 | 183 |
179 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 184 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
180 | 185 |
181 if (GetState() == kError) { | 186 if (GetState() == kError) { |
182 DVLOG(0) << class_name() << "::" << __FUNCTION__ << ": wrong state kError"; | 187 DVLOG(0) << class_name() << "::" << __FUNCTION__ << ": wrong state kError"; |
183 return CONFIG_FAILURE; | 188 return CONFIG_FAILURE; |
184 } | 189 } |
185 | 190 |
191 if (needs_reconfigure_) { | |
192 DVLOG(1) << class_name() << "::" << __FUNCTION__ | |
193 << ": needs reconfigure, deleting MediaCodec"; | |
194 needs_reconfigure_ = false; | |
195 media_codec_bridge_.reset(); | |
196 | |
197 // No need to release these buffers since the MediaCodec is deleted, just | |
198 // remove their indexes from |delayed_buffers_|. | |
199 | |
200 // Shall we move |delayed_buffers_| from VideoDecoder to Decoder class? | |
wolenetz
2015/07/29 22:37:02
Seems there should be either a TODO or a CR commen
Tima Vaisburd
2015/07/30 20:28:35
Yes, but now I tend to think that having a method
wolenetz
2015/07/30 21:10:39
Acknowledged.
| |
201 ClearDelayedBuffers(false); | |
202 } | |
203 | |
186 MediaCodecDecoder::ConfigStatus result; | 204 MediaCodecDecoder::ConfigStatus result; |
187 if (media_codec_bridge_) { | 205 if (media_codec_bridge_) { |
188 DVLOG(1) << class_name() << "::" << __FUNCTION__ | 206 DVLOG(1) << class_name() << "::" << __FUNCTION__ |
189 << ": reconfiguration is not required, ignoring"; | 207 << ": reconfiguration is not required, ignoring"; |
190 result = CONFIG_OK; | 208 result = CONFIG_OK; |
191 } else { | 209 } else { |
192 result = ConfigureInternal(); | 210 result = ConfigureInternal(); |
193 | 211 |
194 #ifndef NDEBUG | 212 #ifndef NDEBUG |
195 // We check and reset |verify_next_frame_is_key_| on Decoder thread. | 213 // 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... | |
259 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 277 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
260 | 278 |
261 if (GetState() == kError) { | 279 if (GetState() == kError) { |
262 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 280 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
263 << ": wrong state kError, ignoring"; | 281 << ": wrong state kError, ignoring"; |
264 return; | 282 return; |
265 } | 283 } |
266 | 284 |
267 // After this method returns, decoder thread will not be running. | 285 // After this method returns, decoder thread will not be running. |
268 | 286 |
287 // Set [kInEmergencyStop| state to block already posted ProcessNextFrame(). | |
288 SetState(kInEmergencyStop); | |
289 | |
269 decoder_thread_.Stop(); // synchronous | 290 decoder_thread_.Stop(); // synchronous |
270 state_ = kStopped; | 291 |
292 SetState(kStopped); | |
271 | 293 |
272 // Shall we move |delayed_buffers_| from VideoDecoder to Decoder class? | 294 // Shall we move |delayed_buffers_| from VideoDecoder to Decoder class? |
wolenetz
2015/07/29 22:37:02
ditto
Tima Vaisburd
2015/07/30 20:28:35
Same as above, removed the comment in the code as
wolenetz
2015/07/30 21:10:39
Acknowledged.
| |
273 ReleaseDelayedBuffers(); | 295 ClearDelayedBuffers(true); // release prior to clearing |delayed_buffers_|. |
274 } | 296 } |
275 | 297 |
276 void MediaCodecDecoder::RequestToStop() { | 298 void MediaCodecDecoder::RequestToStop() { |
277 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 299 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
278 | 300 |
279 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 301 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
280 | 302 |
281 DecoderState state = GetState(); | 303 DecoderState state = GetState(); |
282 switch (state) { | 304 switch (state) { |
283 case kError: | 305 case kError: |
(...skipping 19 matching lines...) Expand all Loading... | |
303 } | 325 } |
304 } | 326 } |
305 | 327 |
306 void MediaCodecDecoder::OnLastFrameRendered(bool completed) { | 328 void MediaCodecDecoder::OnLastFrameRendered(bool completed) { |
307 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 329 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
308 | 330 |
309 DVLOG(1) << class_name() << "::" << __FUNCTION__ | 331 DVLOG(1) << class_name() << "::" << __FUNCTION__ |
310 << " completed:" << completed; | 332 << " completed:" << completed; |
311 | 333 |
312 decoder_thread_.Stop(); // synchronous | 334 decoder_thread_.Stop(); // synchronous |
313 state_ = kStopped; | 335 |
336 SetState(kStopped); | |
314 completed_ = completed; | 337 completed_ = completed; |
315 | 338 |
316 media_task_runner_->PostTask(FROM_HERE, stop_done_cb_); | 339 media_task_runner_->PostTask(FROM_HERE, stop_done_cb_); |
317 } | 340 } |
318 | 341 |
319 void MediaCodecDecoder::OnDemuxerDataAvailable(const DemuxerData& data) { | 342 void MediaCodecDecoder::OnDemuxerDataAvailable(const DemuxerData& data) { |
320 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 343 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
321 | 344 |
322 // If |data| contains an aborted data, the last AU will have kAborted status. | 345 // If |data| contains an aborted data, the last AU will have kAborted status. |
323 bool aborted_data = | 346 bool aborted_data = |
324 !data.access_units.empty() && | 347 !data.access_units.empty() && |
325 data.access_units.back().status == DemuxerStream::kAborted; | 348 data.access_units.back().status == DemuxerStream::kAborted; |
326 | 349 |
327 #ifndef NDEBUG | 350 #ifndef NDEBUG |
328 const char* explain_if_skipped = | 351 const char* explain_if_skipped = |
329 is_incoming_data_invalid_ ? " skipped as invalid" | 352 is_incoming_data_invalid_ ? " skipped as invalid" |
330 : (aborted_data ? " skipped as aborted" : ""); | 353 : (aborted_data ? " skipped as aborted" : ""); |
331 | 354 |
332 for (const auto& unit : data.access_units) | 355 for (const auto& unit : data.access_units) |
333 DVLOG(1) << class_name() << "::" << __FUNCTION__ << explain_if_skipped | 356 DVLOG(2) << class_name() << "::" << __FUNCTION__ << explain_if_skipped |
334 << " au: " << unit; | 357 << " au: " << unit; |
335 for (const auto& configs : data.demuxer_configs) | 358 for (const auto& configs : data.demuxer_configs) |
336 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " configs: " << configs; | 359 DVLOG(2) << class_name() << "::" << __FUNCTION__ << " configs: " << configs; |
337 #endif | 360 #endif |
338 | 361 |
339 if (!is_incoming_data_invalid_ && !aborted_data) | 362 if (!is_incoming_data_invalid_ && !aborted_data) |
340 au_queue_.PushBack(data); | 363 au_queue_.PushBack(data); |
341 | 364 |
342 is_incoming_data_invalid_ = false; | 365 is_incoming_data_invalid_ = false; |
343 is_data_request_in_progress_ = false; | 366 is_data_request_in_progress_ = false; |
344 | 367 |
345 // Do not request data if we got kAborted. There is no point to request the | 368 // Do not request data if we got kAborted. There is no point to request the |
346 // data after kAborted and before the OnDemuxerSeekDone. | 369 // data after kAborted and before the OnDemuxerSeekDone. |
347 if (state_ == kPrefetching && !aborted_data) | 370 if (GetState() == kPrefetching && !aborted_data) |
348 PrefetchNextChunk(); | 371 PrefetchNextChunk(); |
349 } | 372 } |
350 | 373 |
351 int MediaCodecDecoder::NumDelayedRenderTasks() const { | 374 int MediaCodecDecoder::NumDelayedRenderTasks() const { |
352 return 0; | 375 return 0; |
353 } | 376 } |
354 | 377 |
355 void MediaCodecDecoder::CheckLastFrame(bool eos_encountered, | 378 void MediaCodecDecoder::CheckLastFrame(bool eos_encountered, |
356 bool has_delayed_tasks) { | 379 bool has_delayed_tasks) { |
357 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); | 380 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); |
358 | 381 |
359 bool last_frame_when_stopping = GetState() == kStopping && !has_delayed_tasks; | 382 bool last_frame_when_stopping = GetState() == kStopping && !has_delayed_tasks; |
360 | 383 |
361 if (last_frame_when_stopping || eos_encountered) { | 384 if (last_frame_when_stopping || eos_encountered) { |
362 media_task_runner_->PostTask( | 385 media_task_runner_->PostTask( |
363 FROM_HERE, base::Bind(&MediaCodecDecoder::OnLastFrameRendered, | 386 FROM_HERE, base::Bind(&MediaCodecDecoder::OnLastFrameRendered, |
364 weak_factory_.GetWeakPtr(), eos_encountered)); | 387 weak_factory_.GetWeakPtr(), eos_encountered)); |
365 last_frame_posted_ = true; | 388 last_frame_posted_ = true; |
366 } | 389 } |
367 } | 390 } |
368 | 391 |
369 void MediaCodecDecoder::OnCodecError() { | 392 void MediaCodecDecoder::OnCodecError() { |
370 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 393 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
371 | 394 |
395 // Ignore codec errors from the moment surface is changed till the | |
396 // |media_codec_bridge_| is deleted. | |
397 if (needs_reconfigure_) { | |
398 DVLOG(1) << class_name() << "::" << __FUNCTION__ | |
399 << ": needs reconfigure, ignoring"; | |
400 return; | |
401 } | |
402 | |
372 SetState(kError); | 403 SetState(kError); |
373 error_cb_.Run(); | 404 error_cb_.Run(); |
374 } | 405 } |
375 | 406 |
376 void MediaCodecDecoder::RequestData() { | 407 void MediaCodecDecoder::RequestData() { |
377 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 408 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
378 | 409 |
379 // Ensure one data request at a time. | 410 // Ensure one data request at a time. |
380 if (!is_data_request_in_progress_) { | 411 if (!is_data_request_in_progress_) { |
381 is_data_request_in_progress_ = true; | 412 is_data_request_in_progress_ = true; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
427 // We can stop processing, the |au_queue_| and MediaCodec queues can freeze. | 458 // We can stop processing, the |au_queue_| and MediaCodec queues can freeze. |
428 // We only need to let finish the delayed rendering tasks. | 459 // We only need to let finish the delayed rendering tasks. |
429 return; | 460 return; |
430 } | 461 } |
431 | 462 |
432 DCHECK(state == kRunning); | 463 DCHECK(state == kRunning); |
433 | 464 |
434 if (!EnqueueInputBuffer()) | 465 if (!EnqueueInputBuffer()) |
435 return; | 466 return; |
436 | 467 |
437 bool eos_encountered = false; | 468 if (!DepleteOutputBufferQueue()) |
438 if (!DepleteOutputBufferQueue(&eos_encountered)) | |
439 return; | 469 return; |
440 | 470 |
441 if (eos_encountered) { | |
442 DVLOG(1) << class_name() << "::" << __FUNCTION__ | |
443 << " EOS dequeued, stopping frame processing"; | |
444 return; | |
445 } | |
446 | |
447 // We need a small delay if we want to stop this thread by | 471 // We need a small delay if we want to stop this thread by |
448 // decoder_thread_.Stop() reliably. | 472 // decoder_thread_.Stop() reliably. |
449 // The decoder thread message loop processes all pending | 473 // The decoder thread message loop processes all pending |
450 // (but not delayed) tasks before it can quit; without a delay | 474 // (but not delayed) tasks before it can quit; without a delay |
451 // the message loop might be forever processing the pendng tasks. | 475 // the message loop might be forever processing the pendng tasks. |
452 decoder_thread_.task_runner()->PostDelayedTask( | 476 decoder_thread_.task_runner()->PostDelayedTask( |
453 FROM_HERE, | 477 FROM_HERE, |
454 base::Bind(&MediaCodecDecoder::ProcessNextFrame, base::Unretained(this)), | 478 base::Bind(&MediaCodecDecoder::ProcessNextFrame, base::Unretained(this)), |
455 base::TimeDelta::FromMilliseconds(kNextFrameDelay)); | 479 base::TimeDelta::FromMilliseconds(kNextFrameDelay)); |
456 } | 480 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
559 media_task_runner_->PostTask(FROM_HERE, internal_error_cb_); | 583 media_task_runner_->PostTask(FROM_HERE, internal_error_cb_); |
560 return false; | 584 return false; |
561 } | 585 } |
562 | 586 |
563 // Have successfully queued input buffer, go to next access unit. | 587 // Have successfully queued input buffer, go to next access unit. |
564 au_queue_.Advance(); | 588 au_queue_.Advance(); |
565 return true; | 589 return true; |
566 } | 590 } |
567 | 591 |
568 // Returns false if there was MediaCodec error. | 592 // Returns false if there was MediaCodec error. |
569 bool MediaCodecDecoder::DepleteOutputBufferQueue(bool* eos_encountered) { | 593 bool MediaCodecDecoder::DepleteOutputBufferQueue() { |
570 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); | 594 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); |
571 | 595 |
572 DVLOG(2) << class_name() << "::" << __FUNCTION__; | 596 DVLOG(2) << class_name() << "::" << __FUNCTION__; |
573 | 597 |
574 int buffer_index = 0; | 598 int buffer_index = 0; |
575 size_t offset = 0; | 599 size_t offset = 0; |
576 size_t size = 0; | 600 size_t size = 0; |
577 base::TimeDelta pts; | 601 base::TimeDelta pts; |
578 MediaCodecStatus status; | 602 MediaCodecStatus status; |
603 bool eos_encountered = false; | |
579 | 604 |
580 base::TimeDelta timeout = | 605 base::TimeDelta timeout = |
581 base::TimeDelta::FromMilliseconds(kOutputBufferTimeout); | 606 base::TimeDelta::FromMilliseconds(kOutputBufferTimeout); |
582 | 607 |
583 // Extract all output buffers that are available. | 608 // Extract all output buffers that are available. |
584 // Usually there will be only one, but sometimes it is preceeded by | 609 // Usually there will be only one, but sometimes it is preceeded by |
585 // MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED or MEDIA_CODEC_OUTPUT_FORMAT_CHANGED. | 610 // MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED or MEDIA_CODEC_OUTPUT_FORMAT_CHANGED. |
586 do { | 611 do { |
587 status = media_codec_bridge_->DequeueOutputBuffer( | 612 status = media_codec_bridge_->DequeueOutputBuffer( |
588 timeout, &buffer_index, &offset, &size, &pts, eos_encountered, nullptr); | 613 timeout, &buffer_index, &offset, &size, &pts, &eos_encountered, |
614 nullptr); | |
589 | 615 |
590 // Reset the timeout to 0 for the subsequent DequeueOutputBuffer() calls | 616 // Reset the timeout to 0 for the subsequent DequeueOutputBuffer() calls |
591 // to quickly break the loop after we got all currently available buffers. | 617 // to quickly break the loop after we got all currently available buffers. |
592 timeout = base::TimeDelta::FromMilliseconds(0); | 618 timeout = base::TimeDelta::FromMilliseconds(0); |
593 | 619 |
594 switch (status) { | 620 switch (status) { |
595 case MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: | 621 case MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: |
596 // Output buffers are replaced in MediaCodecBridge, nothing to do. | 622 // Output buffers are replaced in MediaCodecBridge, nothing to do. |
597 break; | 623 break; |
598 | 624 |
599 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: | 625 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: |
600 DVLOG(2) << class_name() << "::" << __FUNCTION__ | 626 DVLOG(2) << class_name() << "::" << __FUNCTION__ |
601 << " MEDIA_CODEC_OUTPUT_FORMAT_CHANGED"; | 627 << " MEDIA_CODEC_OUTPUT_FORMAT_CHANGED"; |
602 OnOutputFormatChanged(); | 628 OnOutputFormatChanged(); |
603 break; | 629 break; |
604 | 630 |
605 case MEDIA_CODEC_OK: | 631 case MEDIA_CODEC_OK: |
606 // We got the decoded frame | 632 // We got the decoded frame |
607 Render(buffer_index, size, true, pts, *eos_encountered); | 633 Render(buffer_index, size, true, pts, eos_encountered); |
608 break; | 634 break; |
609 | 635 |
610 case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: | 636 case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: |
611 // Nothing to do. | 637 // Nothing to do. |
612 break; | 638 break; |
613 | 639 |
614 case MEDIA_CODEC_ERROR: | 640 case MEDIA_CODEC_ERROR: |
615 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 641 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
616 << ": MEDIA_CODEC_ERROR from DequeueOutputBuffer"; | 642 << ": MEDIA_CODEC_ERROR from DequeueOutputBuffer"; |
617 media_task_runner_->PostTask(FROM_HERE, internal_error_cb_); | 643 media_task_runner_->PostTask(FROM_HERE, internal_error_cb_); |
618 break; | 644 break; |
619 | 645 |
620 default: | 646 default: |
621 NOTREACHED(); | 647 NOTREACHED(); |
622 break; | 648 break; |
623 } | 649 } |
624 | 650 |
625 } while (status != MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER && | 651 } while (status != MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER && |
626 status != MEDIA_CODEC_ERROR && !*eos_encountered); | 652 status != MEDIA_CODEC_ERROR && !eos_encountered); |
627 | 653 |
628 return status != MEDIA_CODEC_ERROR; | 654 if (eos_encountered) { |
655 DVLOG(1) << class_name() << "::" << __FUNCTION__ | |
656 << " EOS dequeued, stopping frame processing"; | |
657 return false; | |
658 } | |
659 | |
660 if (status == MEDIA_CODEC_ERROR) { | |
661 DVLOG(1) << class_name() << "::" << __FUNCTION__ | |
662 << " MediaCodec error, stopping frame processing"; | |
663 return false; | |
664 } | |
665 | |
666 return true; | |
629 } | 667 } |
630 | 668 |
631 MediaCodecDecoder::DecoderState MediaCodecDecoder::GetState() const { | 669 MediaCodecDecoder::DecoderState MediaCodecDecoder::GetState() const { |
632 base::AutoLock lock(state_lock_); | 670 base::AutoLock lock(state_lock_); |
633 return state_; | 671 return state_; |
634 } | 672 } |
635 | 673 |
636 void MediaCodecDecoder::SetState(DecoderState state) { | 674 void MediaCodecDecoder::SetState(DecoderState state) { |
637 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " " << state; | 675 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " " << AsString(state); |
638 | 676 |
639 base::AutoLock lock(state_lock_); | 677 base::AutoLock lock(state_lock_); |
640 state_ = state; | 678 state_ = state; |
641 } | 679 } |
642 | 680 |
643 #undef RETURN_STRING | 681 #undef RETURN_STRING |
644 #define RETURN_STRING(x) \ | 682 #define RETURN_STRING(x) \ |
645 case x: \ | 683 case x: \ |
646 return #x; | 684 return #x; |
647 | 685 |
648 const char* MediaCodecDecoder::AsString(DecoderState state) { | 686 const char* MediaCodecDecoder::AsString(DecoderState state) { |
649 switch (state) { | 687 switch (state) { |
650 RETURN_STRING(kStopped); | 688 RETURN_STRING(kStopped); |
651 RETURN_STRING(kPrefetching); | 689 RETURN_STRING(kPrefetching); |
652 RETURN_STRING(kPrefetched); | 690 RETURN_STRING(kPrefetched); |
653 RETURN_STRING(kRunning); | 691 RETURN_STRING(kRunning); |
654 RETURN_STRING(kStopping); | 692 RETURN_STRING(kStopping); |
693 RETURN_STRING(kInEmergencyStop); | |
655 RETURN_STRING(kError); | 694 RETURN_STRING(kError); |
656 default: | 695 default: |
657 return "Unknown DecoderState"; | 696 return "Unknown DecoderState"; |
658 } | 697 } |
659 } | 698 } |
660 | 699 |
661 #undef RETURN_STRING | 700 #undef RETURN_STRING |
662 | 701 |
663 } // namespace media | 702 } // namespace media |
OLD | NEW |