Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(597)

Side by Side Diff: media/filters/android/media_codec_audio_decoder.cc

Issue 1834303005: Refactor audio and video decoder status into common file. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/filters/android/media_codec_audio_decoder.h" 5 #include "media/filters/android/media_codec_audio_decoder.h"
6 6
7 #include "base/android/build_info.h" 7 #include "base/android/build_info.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 MediaCodecAudioDecoder::~MediaCodecAudioDecoder() { 79 MediaCodecAudioDecoder::~MediaCodecAudioDecoder() {
80 DVLOG(1) << __FUNCTION__; 80 DVLOG(1) << __FUNCTION__;
81 81
82 media_codec_.reset(); 82 media_codec_.reset();
83 83
84 if (media_drm_bridge_cdm_context_) { 84 if (media_drm_bridge_cdm_context_) {
85 DCHECK(cdm_registration_id_); 85 DCHECK(cdm_registration_id_);
86 media_drm_bridge_cdm_context_->UnregisterPlayer(cdm_registration_id_); 86 media_drm_bridge_cdm_context_->UnregisterPlayer(cdm_registration_id_);
87 } 87 }
88 88
89 ClearInputQueue(kAborted); 89 ClearInputQueue(DecodeStatus::ABORTED);
90 } 90 }
91 91
92 std::string MediaCodecAudioDecoder::GetDisplayName() const { 92 std::string MediaCodecAudioDecoder::GetDisplayName() const {
93 return "MediaCodecAudioDecoder"; 93 return "MediaCodecAudioDecoder";
94 } 94 }
95 95
96 void MediaCodecAudioDecoder::Initialize(const AudioDecoderConfig& config, 96 void MediaCodecAudioDecoder::Initialize(const AudioDecoderConfig& config,
97 CdmContext* cdm_context, 97 CdmContext* cdm_context,
98 const InitCB& init_cb, 98 const InitCB& init_cb,
99 const OutputCB& output_cb) { 99 const OutputCB& output_cb) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 bound_init_cb.Run(true); 141 bound_init_cb.Run(true);
142 } 142 }
143 143
144 void MediaCodecAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, 144 void MediaCodecAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
145 const DecodeCB& decode_cb) { 145 const DecodeCB& decode_cb) {
146 DecodeCB bound_decode_cb = BindToCurrentLoop(decode_cb); 146 DecodeCB bound_decode_cb = BindToCurrentLoop(decode_cb);
147 147
148 if (!buffer->end_of_stream() && buffer->timestamp() == kNoTimestamp()) { 148 if (!buffer->end_of_stream() && buffer->timestamp() == kNoTimestamp()) {
149 DVLOG(2) << __FUNCTION__ << " " << buffer->AsHumanReadableString() 149 DVLOG(2) << __FUNCTION__ << " " << buffer->AsHumanReadableString()
150 << ": no timestamp, skipping this buffer"; 150 << ": no timestamp, skipping this buffer";
151 bound_decode_cb.Run(kDecodeError); 151 bound_decode_cb.Run(DecodeStatus::DECODE_ERROR);
152 return; 152 return;
153 } 153 }
154 154
155 if (state_ == STATE_ERROR) { 155 if (state_ == STATE_ERROR) {
156 // We get here if an error happens in DequeueOutput() or Reset(). 156 // We get here if an error happens in DequeueOutput() or Reset().
157 DVLOG(2) << __FUNCTION__ << " " << buffer->AsHumanReadableString() 157 DVLOG(2) << __FUNCTION__ << " " << buffer->AsHumanReadableString()
158 << ": Error state, returning decode error for all buffers"; 158 << ": Error state, returning decode error for all buffers";
159 ClearInputQueue(kDecodeError); 159 ClearInputQueue(DecodeStatus::DECODE_ERROR);
160 bound_decode_cb.Run(kDecodeError); 160 bound_decode_cb.Run(DecodeStatus::DECODE_ERROR);
161 return; 161 return;
162 } 162 }
163 163
164 DVLOG(2) << __FUNCTION__ << " " << buffer->AsHumanReadableString(); 164 DVLOG(2) << __FUNCTION__ << " " << buffer->AsHumanReadableString();
165 165
166 DCHECK_EQ(state_, STATE_READY) << " unexpected state " << AsString(state_); 166 DCHECK_EQ(state_, STATE_READY) << " unexpected state " << AsString(state_);
167 167
168 // AudioDecoder requires that "Only one decode may be in flight at any given 168 // AudioDecoder requires that "Only one decode may be in flight at any given
169 // time". 169 // time".
170 DCHECK(input_queue_.empty()); 170 DCHECK(input_queue_.empty());
171 171
172 input_queue_.push_back(std::make_pair(buffer, bound_decode_cb)); 172 input_queue_.push_back(std::make_pair(buffer, bound_decode_cb));
173 173
174 DoIOTask(); 174 DoIOTask();
175 } 175 }
176 176
177 void MediaCodecAudioDecoder::Reset(const base::Closure& closure) { 177 void MediaCodecAudioDecoder::Reset(const base::Closure& closure) {
178 DVLOG(1) << __FUNCTION__; 178 DVLOG(1) << __FUNCTION__;
179 179
180 io_timer_.Stop(); 180 io_timer_.Stop();
181 181
182 ClearInputQueue(kAborted); 182 ClearInputQueue(DecodeStatus::ABORTED);
183 183
184 // Flush if we can, otherwise completely recreate and reconfigure the codec. 184 // Flush if we can, otherwise completely recreate and reconfigure the codec.
185 // Prior to JellyBean-MR2, flush() had several bugs (b/8125974, b/8347958) so 185 // Prior to JellyBean-MR2, flush() had several bugs (b/8125974, b/8347958) so
186 // we have to completely destroy and recreate the codec there. 186 // we have to completely destroy and recreate the codec there.
187 bool success = false; 187 bool success = false;
188 if (state_ != STATE_ERROR && state_ != STATE_DRAINED && 188 if (state_ != STATE_ERROR && state_ != STATE_DRAINED &&
189 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) { 189 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) {
190 // media_codec_->Reset() calls MediaCodec.flush(). 190 // media_codec_->Reset() calls MediaCodec.flush().
191 success = (media_codec_->Reset() == MEDIA_CODEC_OK); 191 success = (media_codec_->Reset() == MEDIA_CODEC_OK);
192 } 192 }
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 311
312 if (state_ == STATE_WAITING_FOR_KEY || state_ == STATE_DRAINING || 312 if (state_ == STATE_WAITING_FOR_KEY || state_ == STATE_DRAINING ||
313 state_ == STATE_DRAINED) 313 state_ == STATE_DRAINED)
314 return false; 314 return false;
315 315
316 // DequeueInputBuffer() may set STATE_ERROR. 316 // DequeueInputBuffer() may set STATE_ERROR.
317 InputBufferInfo input_info = DequeueInputBuffer(); 317 InputBufferInfo input_info = DequeueInputBuffer();
318 318
319 if (input_info.buf_index == kInvalidBufferIndex) { 319 if (input_info.buf_index == kInvalidBufferIndex) {
320 if (state_ == STATE_ERROR) 320 if (state_ == STATE_ERROR)
321 ClearInputQueue(kDecodeError); 321 ClearInputQueue(DecodeStatus::DECODE_ERROR);
322 322
323 return false; 323 return false;
324 } 324 }
325 325
326 // EnqueueInputBuffer() may set STATE_DRAINING, STATE_WAITING_FOR_KEY or 326 // EnqueueInputBuffer() may set STATE_DRAINING, STATE_WAITING_FOR_KEY or
327 // STATE_ERROR. 327 // STATE_ERROR.
328 bool did_work = EnqueueInputBuffer(input_info); 328 bool did_work = EnqueueInputBuffer(input_info);
329 329
330 switch (state_) { 330 switch (state_) {
331 case STATE_READY: { 331 case STATE_READY: {
332 const DecodeCB& decode_cb = input_queue_.front().second; 332 const DecodeCB& decode_cb = input_queue_.front().second;
333 decode_cb.Run(kOk); 333 decode_cb.Run(DecodeStatus::OK);
334 input_queue_.pop_front(); 334 input_queue_.pop_front();
335 } break; 335 } break;
336 336
337 case STATE_DRAINING: 337 case STATE_DRAINING:
338 // After queueing EOS we need to flush decoder, i.e. receive this EOS at 338 // After queueing EOS we need to flush decoder, i.e. receive this EOS at
339 // the output, and then call corresponding decoder_cb. 339 // the output, and then call corresponding decoder_cb.
340 // Keep the EOS buffer in the input queue. 340 // Keep the EOS buffer in the input queue.
341 break; 341 break;
342 342
343 case STATE_WAITING_FOR_KEY: 343 case STATE_WAITING_FOR_KEY:
344 // Keep trying to enqueue the same input buffer. 344 // Keep trying to enqueue the same input buffer.
345 // The buffer is owned by us (not the MediaCodec) and is filled with data. 345 // The buffer is owned by us (not the MediaCodec) and is filled with data.
346 break; 346 break;
347 347
348 case STATE_ERROR: 348 case STATE_ERROR:
349 ClearInputQueue(kDecodeError); 349 ClearInputQueue(DecodeStatus::DECODE_ERROR);
350 break; 350 break;
351 351
352 default: 352 default:
353 NOTREACHED() << ": internal error, unexpected state " << AsString(state_); 353 NOTREACHED() << ": internal error, unexpected state " << AsString(state_);
354 SetState(STATE_ERROR); 354 SetState(STATE_ERROR);
355 ClearInputQueue(kDecodeError); 355 ClearInputQueue(DecodeStatus::DECODE_ERROR);
356 did_work = false; 356 did_work = false;
357 break; 357 break;
358 } 358 }
359 359
360 return did_work; 360 return did_work;
361 } 361 }
362 362
363 MediaCodecAudioDecoder::InputBufferInfo 363 MediaCodecAudioDecoder::InputBufferInfo
364 MediaCodecAudioDecoder::DequeueInputBuffer() { 364 MediaCodecAudioDecoder::DequeueInputBuffer() {
365 DVLOG(2) << __FUNCTION__; 365 DVLOG(2) << __FUNCTION__;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 break; 461 break;
462 462
463 default: 463 default:
464 NOTREACHED() << "Unknown Queue(Secure)InputBuffer status " << status; 464 NOTREACHED() << "Unknown Queue(Secure)InputBuffer status " << status;
465 SetState(STATE_ERROR); 465 SetState(STATE_ERROR);
466 break; 466 break;
467 } 467 }
468 return did_work; 468 return did_work;
469 } 469 }
470 470
471 void MediaCodecAudioDecoder::ClearInputQueue(Status decode_status) { 471 void MediaCodecAudioDecoder::ClearInputQueue(DecodeStatus decode_status) {
472 DVLOG(2) << __FUNCTION__; 472 DVLOG(2) << __FUNCTION__;
473 473
474 for (const auto& entry : input_queue_) 474 for (const auto& entry : input_queue_)
475 entry.second.Run(decode_status); 475 entry.second.Run(decode_status);
476 476
477 input_queue_.clear(); 477 input_queue_.clear();
478 } 478 }
479 479
480 bool MediaCodecAudioDecoder::DequeueOutput() { 480 bool MediaCodecAudioDecoder::DequeueOutput() {
481 DVLOG(2) << __FUNCTION__; 481 DVLOG(2) << __FUNCTION__;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 570
571 DCHECK_EQ(state_, STATE_DRAINING); 571 DCHECK_EQ(state_, STATE_DRAINING);
572 572
573 media_codec_->ReleaseOutputBuffer(out.buf_index, false); 573 media_codec_->ReleaseOutputBuffer(out.buf_index, false);
574 574
575 // Report the end of decoding for EOS DecoderBuffer. 575 // Report the end of decoding for EOS DecoderBuffer.
576 DCHECK(!input_queue_.empty()); 576 DCHECK(!input_queue_.empty());
577 DCHECK(input_queue_.front().first->end_of_stream()); 577 DCHECK(input_queue_.front().first->end_of_stream());
578 578
579 const DecodeCB& decode_cb = input_queue_.front().second; 579 const DecodeCB& decode_cb = input_queue_.front().second;
580 decode_cb.Run(kOk); 580 decode_cb.Run(DecodeStatus::OK);
581 581
582 // Remove the EOS buffer from the input queue. 582 // Remove the EOS buffer from the input queue.
583 input_queue_.pop_front(); 583 input_queue_.pop_front();
584 584
585 // Set state STATE_DRAINED after we have received EOS frame at the output. 585 // Set state STATE_DRAINED after we have received EOS frame at the output.
586 // media_decoder_job.cc says: once output EOS has occurred, we should 586 // media_decoder_job.cc says: once output EOS has occurred, we should
587 // not be asked to decode again. 587 // not be asked to decode again.
588 SetState(STATE_DRAINED); 588 SetState(STATE_DRAINED);
589 } 589 }
590 590
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 RETURN_STRING(STATE_DRAINED); 668 RETURN_STRING(STATE_DRAINED);
669 RETURN_STRING(STATE_ERROR); 669 RETURN_STRING(STATE_ERROR);
670 } 670 }
671 NOTREACHED() << "Unknown state " << state; 671 NOTREACHED() << "Unknown state " << state;
672 return nullptr; 672 return nullptr;
673 } 673 }
674 674
675 #undef RETURN_STRING 675 #undef RETURN_STRING
676 676
677 } // namespace media 677 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/android/media_codec_audio_decoder.h ('k') | media/filters/audio_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698