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

Side by Side Diff: media/base/android/media_decoder_job.cc

Issue 79283006: Let only seeks reset Android MSE stream playback completion (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address qinmin's nits from PS7 Created 7 years 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 | Annotate | Revision Log
« no previous file with comments | « media/base/android/media_decoder_job.h ('k') | media/base/android/media_source_player.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.h" 10 #include "base/message_loop/message_loop.h"
(...skipping 10 matching lines...) Expand all
21 21
22 MediaDecoderJob::MediaDecoderJob( 22 MediaDecoderJob::MediaDecoderJob(
23 const scoped_refptr<base::MessageLoopProxy>& decoder_loop, 23 const scoped_refptr<base::MessageLoopProxy>& decoder_loop,
24 MediaCodecBridge* media_codec_bridge, 24 MediaCodecBridge* media_codec_bridge,
25 const base::Closure& request_data_cb) 25 const base::Closure& request_data_cb)
26 : ui_loop_(base::MessageLoopProxy::current()), 26 : ui_loop_(base::MessageLoopProxy::current()),
27 decoder_loop_(decoder_loop), 27 decoder_loop_(decoder_loop),
28 media_codec_bridge_(media_codec_bridge), 28 media_codec_bridge_(media_codec_bridge),
29 needs_flush_(false), 29 needs_flush_(false),
30 input_eos_encountered_(false), 30 input_eos_encountered_(false),
31 output_eos_encountered_(false),
31 skip_eos_enqueue_(true), 32 skip_eos_enqueue_(true),
32 prerolling_(true), 33 prerolling_(true),
33 weak_this_(this), 34 weak_this_(this),
34 request_data_cb_(request_data_cb), 35 request_data_cb_(request_data_cb),
35 access_unit_index_(0), 36 access_unit_index_(0),
36 input_buf_index_(-1), 37 input_buf_index_(-1),
37 stop_decode_pending_(false), 38 stop_decode_pending_(false),
38 destroy_pending_(false) { 39 destroy_pending_(false) {
39 } 40 }
40 41
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 const base::TimeDelta& start_presentation_timestamp, 269 const base::TimeDelta& start_presentation_timestamp,
269 bool needs_flush, 270 bool needs_flush,
270 const MediaDecoderJob::DecoderCallback& callback) { 271 const MediaDecoderJob::DecoderCallback& callback) {
271 DVLOG(1) << __FUNCTION__; 272 DVLOG(1) << __FUNCTION__;
272 DCHECK(decoder_loop_->BelongsToCurrentThread()); 273 DCHECK(decoder_loop_->BelongsToCurrentThread());
273 TRACE_EVENT0("media", __FUNCTION__); 274 TRACE_EVENT0("media", __FUNCTION__);
274 275
275 if (needs_flush) { 276 if (needs_flush) {
276 DVLOG(1) << "DecodeInternal needs flush."; 277 DVLOG(1) << "DecodeInternal needs flush.";
277 input_eos_encountered_ = false; 278 input_eos_encountered_ = false;
279 output_eos_encountered_ = false;
278 MediaCodecStatus reset_status = media_codec_bridge_->Reset(); 280 MediaCodecStatus reset_status = media_codec_bridge_->Reset();
279 if (MEDIA_CODEC_OK != reset_status) { 281 if (MEDIA_CODEC_OK != reset_status) {
280 callback.Run(reset_status, kNoTimestamp(), 0); 282 callback.Run(reset_status, kNoTimestamp(), 0);
281 return; 283 return;
282 } 284 }
283 } 285 }
284 286
287 // Once output EOS has occurred, we should not be asked to decode again.
288 // MediaCodec has undefined behavior if similarly asked to decode after output
289 // EOS.
290 DCHECK(!output_eos_encountered_);
291
285 // For aborted access unit, just skip it and inform the player. 292 // For aborted access unit, just skip it and inform the player.
286 if (unit.status == DemuxerStream::kAborted) { 293 if (unit.status == DemuxerStream::kAborted) {
287 // TODO(qinmin): use a new enum instead of MEDIA_CODEC_STOPPED. 294 // TODO(qinmin): use a new enum instead of MEDIA_CODEC_STOPPED.
288 callback.Run(MEDIA_CODEC_STOPPED, kNoTimestamp(), 0); 295 callback.Run(MEDIA_CODEC_STOPPED, kNoTimestamp(), 0);
289 return; 296 return;
290 } 297 }
291 298
292 if (skip_eos_enqueue_) { 299 if (skip_eos_enqueue_) {
293 if (unit.end_of_stream || unit.data.empty()) { 300 if (unit.end_of_stream || unit.data.empty()) {
294 input_eos_encountered_ = true; 301 input_eos_encountered_ = true;
302 output_eos_encountered_ = true;
295 callback.Run(MEDIA_CODEC_OUTPUT_END_OF_STREAM, kNoTimestamp(), 0); 303 callback.Run(MEDIA_CODEC_OUTPUT_END_OF_STREAM, kNoTimestamp(), 0);
296 return; 304 return;
297 } 305 }
298 306
299 skip_eos_enqueue_ = false; 307 skip_eos_enqueue_ = false;
300 } 308 }
301 309
302
303 MediaCodecStatus input_status = MEDIA_CODEC_INPUT_END_OF_STREAM; 310 MediaCodecStatus input_status = MEDIA_CODEC_INPUT_END_OF_STREAM;
304 if (!input_eos_encountered_) { 311 if (!input_eos_encountered_) {
305 input_status = QueueInputBuffer(unit); 312 input_status = QueueInputBuffer(unit);
306 if (input_status == MEDIA_CODEC_INPUT_END_OF_STREAM) { 313 if (input_status == MEDIA_CODEC_INPUT_END_OF_STREAM) {
307 input_eos_encountered_ = true; 314 input_eos_encountered_ = true;
308 } else if (input_status != MEDIA_CODEC_OK) { 315 } else if (input_status != MEDIA_CODEC_OK) {
309 callback.Run(input_status, kNoTimestamp(), 0); 316 callback.Run(input_status, kNoTimestamp(), 0);
310 return; 317 return;
311 } 318 }
312 } 319 }
313 320
314 int buffer_index = 0; 321 int buffer_index = 0;
315 size_t offset = 0; 322 size_t offset = 0;
316 size_t size = 0; 323 size_t size = 0;
317 base::TimeDelta presentation_timestamp; 324 base::TimeDelta presentation_timestamp;
318 bool output_eos_encountered = false;
319 325
320 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds( 326 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(
321 kMediaCodecTimeoutInMilliseconds); 327 kMediaCodecTimeoutInMilliseconds);
322 328
323 MediaCodecStatus status = 329 MediaCodecStatus status =
324 media_codec_bridge_->DequeueOutputBuffer(timeout, 330 media_codec_bridge_->DequeueOutputBuffer(timeout,
325 &buffer_index, 331 &buffer_index,
326 &offset, 332 &offset,
327 &size, 333 &size,
328 &presentation_timestamp, 334 &presentation_timestamp,
329 &output_eos_encountered, 335 &output_eos_encountered_,
330 NULL); 336 NULL);
331 337
332 if (status != MEDIA_CODEC_OK) { 338 if (status != MEDIA_CODEC_OK) {
333 if (status == MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED && 339 if (status == MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED &&
334 !media_codec_bridge_->GetOutputBuffers()) { 340 !media_codec_bridge_->GetOutputBuffers()) {
335 status = MEDIA_CODEC_ERROR; 341 status = MEDIA_CODEC_ERROR;
336 } 342 }
337 callback.Run(status, kNoTimestamp(), 0); 343 callback.Run(status, kNoTimestamp(), 0);
338 return; 344 return;
339 } 345 }
340 346
341 // TODO(xhwang/qinmin): This logic is correct but strange. Clean it up. 347 // TODO(xhwang/qinmin): This logic is correct but strange. Clean it up.
342 if (output_eos_encountered) 348 if (output_eos_encountered_)
343 status = MEDIA_CODEC_OUTPUT_END_OF_STREAM; 349 status = MEDIA_CODEC_OUTPUT_END_OF_STREAM;
344 else if (input_status == MEDIA_CODEC_INPUT_END_OF_STREAM) 350 else if (input_status == MEDIA_CODEC_INPUT_END_OF_STREAM)
345 status = MEDIA_CODEC_INPUT_END_OF_STREAM; 351 status = MEDIA_CODEC_INPUT_END_OF_STREAM;
346 352
347 // Check whether we need to render the output. 353 // Check whether we need to render the output.
348 // TODO(qinmin): comparing most recently queued input's |unit.timestamp| with 354 // TODO(qinmin): comparing most recently queued input's |unit.timestamp| with
349 // |preroll_timestamp_| is not accurate due to data reordering and possible 355 // |preroll_timestamp_| is not accurate due to data reordering and possible
350 // input queueing without immediate dequeue when |input_status| != 356 // input queueing without immediate dequeue when |input_status| !=
351 // |MEDIA_CODEC_OK|. Need to use the |presentation_timestamp| for video, and 357 // |MEDIA_CODEC_OK|. Need to use the |presentation_timestamp| for video, and
352 // use |size| to calculate the timestamp for audio. See 358 // use |size| to calculate the timestamp for audio. See
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 // Do nothing. 429 // Do nothing.
424 break; 430 break;
425 }; 431 };
426 432
427 stop_decode_pending_ = false; 433 stop_decode_pending_ = false;
428 base::ResetAndReturn(&decode_cb_).Run(status, presentation_timestamp, 434 base::ResetAndReturn(&decode_cb_).Run(status, presentation_timestamp,
429 audio_output_bytes); 435 audio_output_bytes);
430 } 436 }
431 437
432 } // namespace media 438 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_decoder_job.h ('k') | media/base/android/media_source_player.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698