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

Unified Diff: media/base/android/media_decoder_job.cc

Issue 2283493003: Delete browser MSE implementation. (Closed)
Patch Set: Actually delete MSP. Cleanse references. Remove AudioTrack usage. Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: media/base/android/media_decoder_job.cc
diff --git a/media/base/android/media_decoder_job.cc b/media/base/android/media_decoder_job.cc
deleted file mode 100644
index efbbea8f47b6afd69cc92b8cf90860a7a9d418bb..0000000000000000000000000000000000000000
--- a/media/base/android/media_decoder_job.cc
+++ /dev/null
@@ -1,693 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/base/android/media_decoder_job.h"
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/trace_event/trace_event.h"
-#include "media/base/android/media_drm_bridge.h"
-#include "media/base/bind_to_current_loop.h"
-#include "media/base/timestamp_constants.h"
-
-namespace media {
-
-// Timeout value for media codec operations. Because the first
-// DequeInputBuffer() can take about 150 milliseconds, use 250 milliseconds
-// here. See http://b/9357571.
-static const int kMediaCodecTimeoutInMilliseconds = 250;
-
-MediaDecoderJob::MediaDecoderJob(
- const scoped_refptr<base::SingleThreadTaskRunner>& decoder_task_runner,
- const base::Closure& request_data_cb,
- const base::Closure& config_changed_cb)
- : need_to_reconfig_decoder_job_(false),
- ui_task_runner_(base::ThreadTaskRunnerHandle::Get()),
- decoder_task_runner_(decoder_task_runner),
- needs_flush_(false),
- input_eos_encountered_(false),
- output_eos_encountered_(false),
- skip_eos_enqueue_(true),
- prerolling_(true),
- request_data_cb_(request_data_cb),
- config_changed_cb_(config_changed_cb),
- current_demuxer_data_index_(0),
- input_buf_index_(-1),
- is_content_encrypted_(false),
- stop_decode_pending_(false),
- destroy_pending_(false),
- is_requesting_demuxer_data_(false),
- is_incoming_data_invalid_(false),
- release_resources_pending_(false),
- drm_bridge_(NULL),
- drain_decoder_(false) {
- InitializeReceivedData();
- eos_unit_.is_end_of_stream = true;
-}
-
-MediaDecoderJob::~MediaDecoderJob() {
- ReleaseMediaCodecBridge();
-}
-
-void MediaDecoderJob::OnDataReceived(const DemuxerData& data) {
- DVLOG(1) << __FUNCTION__ << ": " << data.access_units.size() << " units";
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- DCHECK(NoAccessUnitsRemainingInChunk(false));
-
- TRACE_EVENT_ASYNC_END2(
- "media", "MediaDecoderJob::RequestData", this,
- "Data type", data.type == media::DemuxerStream::AUDIO ? "AUDIO" : "VIDEO",
- "Units read", data.access_units.size());
-
- if (is_incoming_data_invalid_) {
- is_incoming_data_invalid_ = false;
-
- // If there is a pending callback, need to request the data again to get
- // valid data.
- if (!data_received_cb_.is_null())
- request_data_cb_.Run();
- else
- is_requesting_demuxer_data_ = false;
- return;
- }
-
- size_t next_demuxer_data_index = inactive_demuxer_data_index();
- received_data_[next_demuxer_data_index] = data;
- access_unit_index_[next_demuxer_data_index] = 0;
- is_requesting_demuxer_data_ = false;
-
- base::Closure done_cb = base::ResetAndReturn(&data_received_cb_);
-
- // If this data request is for the inactive chunk, or |data_received_cb_|
- // was set to null by Flush() or Release(), do nothing.
- if (done_cb.is_null())
- return;
-
- if (stop_decode_pending_) {
- DCHECK(is_decoding());
- OnDecodeCompleted(MEDIA_CODEC_ABORT, false, kNoTimestamp, kNoTimestamp);
- return;
- }
-
- done_cb.Run();
-}
-
-void MediaDecoderJob::Prefetch(const base::Closure& prefetch_cb) {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- DCHECK(data_received_cb_.is_null());
- DCHECK(decode_cb_.is_null());
-
- if (HasData()) {
- DVLOG(1) << __FUNCTION__ << " : using previously received data";
- ui_task_runner_->PostTask(FROM_HERE, prefetch_cb);
- return;
- }
-
- DVLOG(1) << __FUNCTION__ << " : requesting data";
- RequestData(prefetch_cb);
-}
-
-MediaDecoderJob::MediaDecoderJobStatus MediaDecoderJob::Decode(
- base::TimeTicks start_time_ticks,
- base::TimeDelta start_presentation_timestamp,
- const DecoderCallback& callback) {
- DCHECK(decode_cb_.is_null());
- DCHECK(data_received_cb_.is_null());
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- if (!media_codec_bridge_ || need_to_reconfig_decoder_job_) {
- if (drain_decoder_)
- OnDecoderDrained();
- MediaDecoderJobStatus status = CreateMediaCodecBridge();
- need_to_reconfig_decoder_job_ = (status != STATUS_SUCCESS);
- skip_eos_enqueue_ = true;
- if (need_to_reconfig_decoder_job_)
- return status;
- }
-
- decode_cb_ = callback;
-
- if (!HasData()) {
- RequestData(base::Bind(&MediaDecoderJob::DecodeCurrentAccessUnit,
- base::Unretained(this),
- start_time_ticks,
- start_presentation_timestamp));
- return STATUS_SUCCESS;
- }
-
- DecodeCurrentAccessUnit(start_time_ticks, start_presentation_timestamp);
- return STATUS_SUCCESS;
-}
-
-void MediaDecoderJob::StopDecode() {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- DCHECK(is_decoding());
- stop_decode_pending_ = true;
-}
-
-bool MediaDecoderJob::OutputEOSReached() const {
- return !drain_decoder_ && output_eos_encountered_;
-}
-
-void MediaDecoderJob::SetDrmBridge(MediaDrmBridge* drm_bridge) {
- drm_bridge_ = drm_bridge;
- need_to_reconfig_decoder_job_ = true;
-}
-
-void MediaDecoderJob::Flush() {
- DVLOG(1) << __FUNCTION__;
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- DCHECK(data_received_cb_.is_null());
- DCHECK(decode_cb_.is_null());
-
- // Clean up the received data.
- current_demuxer_data_index_ = 0;
- InitializeReceivedData();
- if (is_requesting_demuxer_data_)
- is_incoming_data_invalid_ = true;
- input_eos_encountered_ = false;
- output_eos_encountered_ = false;
- drain_decoder_ = false;
-
- // Do nothing, flush when the next Decode() happens.
- needs_flush_ = true;
-}
-
-void MediaDecoderJob::BeginPrerolling(base::TimeDelta preroll_timestamp) {
- DVLOG(1) << __FUNCTION__ << "(" << preroll_timestamp.InSecondsF() << ")";
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- DCHECK(!is_decoding());
-
- preroll_timestamp_ = preroll_timestamp;
- prerolling_ = true;
-}
-
-void MediaDecoderJob::ReleaseDecoderResources() {
- DVLOG(1) << __FUNCTION__;
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- if (decode_cb_.is_null()) {
- DCHECK(!drain_decoder_);
- // Since the decoder job is not decoding data, we can safely destroy
- // |media_codec_bridge_|.
- ReleaseMediaCodecBridge();
- return;
- }
-
- // Release |media_codec_bridge_| once decoding is completed.
- release_resources_pending_ = true;
-}
-
-jobject MediaDecoderJob::GetMediaCrypto() {
- return drm_bridge_ ? drm_bridge_->GetMediaCrypto() : nullptr;
-}
-
-bool MediaDecoderJob::SetCurrentFrameToPreviouslyCachedKeyFrame() {
- const std::vector<AccessUnit>& access_units =
- received_data_[current_demuxer_data_index_].access_units;
- // If the current data chunk is empty, the player must be in an initial or
- // seek state. The next access unit will always be a key frame.
- if (access_units.size() == 0)
- return true;
-
- // Find key frame in all the access units the decoder have decoded,
- // or is about to decode.
- int i = std::min(access_unit_index_[current_demuxer_data_index_],
- access_units.size() - 1);
- for (; i >= 0; --i) {
- // Config change is always the last access unit, and it always come with
- // a key frame afterwards.
- if (access_units[i].status == DemuxerStream::kConfigChanged)
- return true;
- if (access_units[i].is_key_frame) {
- access_unit_index_[current_demuxer_data_index_] = i;
- return true;
- }
- }
- return false;
-}
-
-
-void MediaDecoderJob::Release() {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- DVLOG(1) << __FUNCTION__;
-
- // If the decoder job is still decoding, we cannot delete the job immediately.
- destroy_pending_ = is_decoding();
-
- request_data_cb_.Reset();
- data_received_cb_.Reset();
- decode_cb_.Reset();
-
- if (destroy_pending_) {
- DVLOG(1) << __FUNCTION__ << " : delete is pending decode completion";
- return;
- }
-
- delete this;
-}
-
-MediaCodecStatus MediaDecoderJob::QueueInputBuffer(const AccessUnit& unit) {
- DVLOG(1) << __FUNCTION__;
- DCHECK(decoder_task_runner_->BelongsToCurrentThread());
- TRACE_EVENT0("media", __FUNCTION__);
-
- int input_buf_index = input_buf_index_;
- input_buf_index_ = -1;
-
- // TODO(xhwang): Hide DequeueInputBuffer() and the index in MediaCodecBridge.
- if (input_buf_index == -1) {
- base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(
- kMediaCodecTimeoutInMilliseconds);
- MediaCodecStatus status =
- media_codec_bridge_->DequeueInputBuffer(timeout, &input_buf_index);
- if (status != MEDIA_CODEC_OK) {
- DVLOG(1) << "DequeueInputBuffer fails: " << status;
- return status;
- }
- }
-
- // TODO(qinmin): skip frames if video is falling far behind.
- DCHECK_GE(input_buf_index, 0);
- if (unit.is_end_of_stream || unit.data.empty()) {
- media_codec_bridge_->QueueEOS(input_buf_index);
- return MEDIA_CODEC_INPUT_END_OF_STREAM;
- }
-
- if (unit.key_id.empty() || unit.iv.empty()) {
- DCHECK(unit.iv.empty() || !unit.key_id.empty());
- return media_codec_bridge_->QueueInputBuffer(
- input_buf_index, &unit.data[0], unit.data.size(), unit.timestamp);
- }
-
- MediaCodecStatus status = media_codec_bridge_->QueueSecureInputBuffer(
- input_buf_index, &unit.data[0], unit.data.size(), unit.key_id, unit.iv,
- unit.subsamples.empty() ? NULL : &unit.subsamples[0],
- unit.subsamples.size(), unit.timestamp);
-
- // In case of MEDIA_CODEC_NO_KEY, we must reuse the |input_buf_index_|.
- // Otherwise MediaDrm will report errors.
- if (status == MEDIA_CODEC_NO_KEY)
- input_buf_index_ = input_buf_index;
-
- return status;
-}
-
-bool MediaDecoderJob::HasData() const {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- // When |input_eos_encountered_| is set, |access_unit_index_| and
- // |current_demuxer_data_index_| must be pointing to an EOS unit,
- // or a |kConfigChanged| unit if |drain_decoder_| is true. In both cases,
- // we'll feed an EOS input unit to drain the decoder until we hit output EOS.
- DCHECK(!input_eos_encountered_ || !NoAccessUnitsRemainingInChunk(true));
- return !NoAccessUnitsRemainingInChunk(true) ||
- !NoAccessUnitsRemainingInChunk(false);
-}
-
-void MediaDecoderJob::RequestData(const base::Closure& done_cb) {
- DVLOG(1) << __FUNCTION__;
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- DCHECK(data_received_cb_.is_null());
- DCHECK(!input_eos_encountered_);
- DCHECK(NoAccessUnitsRemainingInChunk(false));
-
- TRACE_EVENT_ASYNC_BEGIN0("media", "MediaDecoderJob::RequestData", this);
-
- data_received_cb_ = done_cb;
-
- // If we are already expecting new data, just set the callback and do
- // nothing.
- if (is_requesting_demuxer_data_)
- return;
-
- // The new incoming data will be stored as the next demuxer data chunk, since
- // the decoder might still be decoding the current one.
- size_t next_demuxer_data_index = inactive_demuxer_data_index();
- received_data_[next_demuxer_data_index] = DemuxerData();
- access_unit_index_[next_demuxer_data_index] = 0;
- is_requesting_demuxer_data_ = true;
-
- request_data_cb_.Run();
-}
-
-void MediaDecoderJob::DecodeCurrentAccessUnit(
- base::TimeTicks start_time_ticks,
- base::TimeDelta start_presentation_timestamp) {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- DCHECK(!decode_cb_.is_null());
-
- RequestCurrentChunkIfEmpty();
- const AccessUnit& access_unit = CurrentAccessUnit();
- if (CurrentAccessUnit().status == DemuxerStream::kConfigChanged) {
- int index = CurrentReceivedDataChunkIndex();
- const DemuxerConfigs& configs = received_data_[index].demuxer_configs[0];
- bool reconfigure_needed = IsCodecReconfigureNeeded(configs);
- SetDemuxerConfigs(configs);
- if (!drain_decoder_) {
- // If we haven't decoded any data yet, just skip the current access unit
- // and request the MediaCodec to be recreated on next Decode().
- if (skip_eos_enqueue_ || !reconfigure_needed) {
- need_to_reconfig_decoder_job_ =
- need_to_reconfig_decoder_job_ || reconfigure_needed;
- // Report MEDIA_CODEC_OK status so decoder will continue decoding and
- // MEDIA_CODEC_OUTPUT_FORMAT_CHANGED status will come later.
- ui_task_runner_->PostTask(
- FROM_HERE, base::Bind(&MediaDecoderJob::OnDecodeCompleted,
- base::Unretained(this), MEDIA_CODEC_OK, false,
- kNoTimestamp, kNoTimestamp));
- return;
- }
- // Start draining the decoder so that all the remaining frames are
- // rendered.
- drain_decoder_ = true;
- }
- }
-
- DCHECK(!(needs_flush_ && drain_decoder_));
- decoder_task_runner_->PostTask(FROM_HERE, base::Bind(
- &MediaDecoderJob::DecodeInternal, base::Unretained(this),
- drain_decoder_ ? eos_unit_ : access_unit,
- start_time_ticks, start_presentation_timestamp, needs_flush_,
- media::BindToCurrentLoop(base::Bind(
- &MediaDecoderJob::OnDecodeCompleted, base::Unretained(this)))));
- needs_flush_ = false;
-}
-
-void MediaDecoderJob::DecodeInternal(
- const AccessUnit& unit,
- base::TimeTicks start_time_ticks,
- base::TimeDelta start_presentation_timestamp,
- bool needs_flush,
- const MediaDecoderJob::DecoderCallback& callback) {
- DVLOG(1) << __FUNCTION__;
- DCHECK(decoder_task_runner_->BelongsToCurrentThread());
- TRACE_EVENT0("media", __FUNCTION__);
-
- if (needs_flush) {
- DVLOG(1) << "DecodeInternal needs flush.";
- input_eos_encountered_ = false;
- output_eos_encountered_ = false;
- input_buf_index_ = -1;
- MediaCodecStatus flush_status = media_codec_bridge_->Flush();
- if (flush_status != MEDIA_CODEC_OK) {
- callback.Run(flush_status, false, kNoTimestamp, kNoTimestamp);
- return;
- }
- }
-
- // Once output EOS has occurred, we should not be asked to decode again.
- // MediaCodec has undefined behavior if similarly asked to decode after output
- // EOS.
- DCHECK(!output_eos_encountered_);
-
- // For aborted access unit, just skip it and inform the player.
- if (unit.status == DemuxerStream::kAborted) {
- callback.Run(MEDIA_CODEC_ABORT, false, kNoTimestamp, kNoTimestamp);
- return;
- }
-
- if (skip_eos_enqueue_) {
- if (unit.is_end_of_stream || unit.data.empty()) {
- input_eos_encountered_ = true;
- output_eos_encountered_ = true;
- callback.Run(MEDIA_CODEC_OUTPUT_END_OF_STREAM, false, kNoTimestamp,
- kNoTimestamp);
- return;
- }
-
- skip_eos_enqueue_ = false;
- }
-
- MediaCodecStatus input_status = MEDIA_CODEC_INPUT_END_OF_STREAM;
- if (!input_eos_encountered_) {
- input_status = QueueInputBuffer(unit);
- if (input_status == MEDIA_CODEC_INPUT_END_OF_STREAM) {
- input_eos_encountered_ = true;
- } else if (input_status == MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER) {
- // In some cases, all buffers must be released to codec before format
- // change can be resolved. Context: b/21786703
- DVLOG(1) << "dequeueInputBuffer gave AGAIN_LATER, dequeue output buffers";
- } else if (input_status != MEDIA_CODEC_OK) {
- callback.Run(input_status, false, kNoTimestamp, kNoTimestamp);
- return;
- }
- }
-
- int buffer_index = 0;
- size_t offset = 0;
- size_t size = 0;
- base::TimeDelta presentation_timestamp;
-
- base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(
- kMediaCodecTimeoutInMilliseconds);
-
- MediaCodecStatus status = MEDIA_CODEC_OK;
- bool has_format_change = false;
- // Dequeue the output buffer until a MEDIA_CODEC_OK, MEDIA_CODEC_ERROR or
- // MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER is received.
- do {
- status = media_codec_bridge_->DequeueOutputBuffer(
- timeout,
- &buffer_index,
- &offset,
- &size,
- &presentation_timestamp,
- &output_eos_encountered_,
- NULL);
- if (status == MEDIA_CODEC_OUTPUT_FORMAT_CHANGED) {
- // TODO(qinmin): instead of waiting for the next output buffer to be
- // dequeued, post a task on the UI thread to signal the format change.
- if (OnOutputFormatChanged())
- has_format_change = true;
- else
- status = MEDIA_CODEC_ERROR;
- }
- } while (status != MEDIA_CODEC_OK && status != MEDIA_CODEC_ERROR &&
- status != MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER);
-
- if (status != MEDIA_CODEC_OK) {
- callback.Run(status, false, kNoTimestamp, kNoTimestamp);
- return;
- }
-
- // TODO(xhwang/qinmin): This logic is correct but strange. Clean it up.
- if (output_eos_encountered_)
- status = MEDIA_CODEC_OUTPUT_END_OF_STREAM;
- else if (has_format_change)
- status = MEDIA_CODEC_OUTPUT_FORMAT_CHANGED;
-
- bool render_output = presentation_timestamp >= preroll_timestamp_ &&
- (status != MEDIA_CODEC_OUTPUT_END_OF_STREAM || size != 0u);
- base::TimeDelta time_to_render;
- DCHECK(!start_time_ticks.is_null());
- if (render_output && ComputeTimeToRender()) {
- time_to_render = presentation_timestamp - (base::TimeTicks::Now() -
- start_time_ticks + start_presentation_timestamp);
- }
-
- if (time_to_render > base::TimeDelta()) {
- decoder_task_runner_->PostDelayedTask(
- FROM_HERE, base::Bind(&MediaDecoderJob::ReleaseOutputBuffer,
- base::Unretained(this), buffer_index, offset,
- size, render_output,
- false, // this is not a late frame
- presentation_timestamp, status, callback),
- time_to_render);
- return;
- }
-
- // TODO(qinmin): The codec is lagging behind, need to recalculate the
- // |start_presentation_timestamp_| and |start_time_ticks_| in
- // media_source_player.cc.
- DVLOG(1) << "codec is lagging behind :" << time_to_render.InMicroseconds();
- if (render_output) {
- // The player won't expect a timestamp smaller than the
- // |start_presentation_timestamp|. However, this could happen due to decoder
- // errors.
- presentation_timestamp = std::max(
- presentation_timestamp, start_presentation_timestamp);
- } else {
- presentation_timestamp = kNoTimestamp;
- }
-
- const bool is_late_frame = (time_to_render < base::TimeDelta());
- ReleaseOutputBuffer(buffer_index, offset, size, render_output, is_late_frame,
- presentation_timestamp, status, callback);
-}
-
-void MediaDecoderJob::OnDecodeCompleted(
- MediaCodecStatus status,
- bool is_late_frame,
- base::TimeDelta current_presentation_timestamp,
- base::TimeDelta max_presentation_timestamp) {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
-
- if (destroy_pending_) {
- DVLOG(1) << __FUNCTION__ << " : completing pending deletion";
- delete this;
- return;
- }
-
- if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
- output_eos_encountered_ = true;
-
- DCHECK(!decode_cb_.is_null());
-
- // If output was queued for rendering, then we have completed prerolling.
- if (current_presentation_timestamp != kNoTimestamp ||
- status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) {
- prerolling_ = false;
- }
-
- switch (status) {
- case MEDIA_CODEC_OK:
- case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
- case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED:
- case MEDIA_CODEC_OUTPUT_END_OF_STREAM:
- if (!input_eos_encountered_)
- access_unit_index_[current_demuxer_data_index_]++;
- break;
-
- case MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER:
- case MEDIA_CODEC_INPUT_END_OF_STREAM:
- case MEDIA_CODEC_NO_KEY:
- case MEDIA_CODEC_ABORT:
- case MEDIA_CODEC_ERROR:
- // Do nothing.
- break;
-
- case MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED:
- DCHECK(false) << "Invalid output status";
- break;
- };
-
- if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM && drain_decoder_) {
- OnDecoderDrained();
- status = MEDIA_CODEC_OK;
- }
-
- if (status == MEDIA_CODEC_OUTPUT_FORMAT_CHANGED) {
- if (UpdateOutputFormat())
- config_changed_cb_.Run();
- status = MEDIA_CODEC_OK;
- }
-
- if (release_resources_pending_) {
- ReleaseMediaCodecBridge();
- release_resources_pending_ = false;
- if (drain_decoder_)
- OnDecoderDrained();
- }
-
- stop_decode_pending_ = false;
- base::ResetAndReturn(&decode_cb_)
- .Run(status, is_late_frame, current_presentation_timestamp,
- max_presentation_timestamp);
-}
-
-const AccessUnit& MediaDecoderJob::CurrentAccessUnit() const {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- DCHECK(HasData());
- size_t index = CurrentReceivedDataChunkIndex();
- return received_data_[index].access_units[access_unit_index_[index]];
-}
-
-size_t MediaDecoderJob::CurrentReceivedDataChunkIndex() const {
- return NoAccessUnitsRemainingInChunk(true) ?
- inactive_demuxer_data_index() : current_demuxer_data_index_;
-}
-
-bool MediaDecoderJob::NoAccessUnitsRemainingInChunk(
- bool is_active_chunk) const {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- size_t index = is_active_chunk ? current_demuxer_data_index_ :
- inactive_demuxer_data_index();
- return received_data_[index].access_units.size() <= access_unit_index_[index];
-}
-
-void MediaDecoderJob::RequestCurrentChunkIfEmpty() {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- DCHECK(HasData());
- if (!NoAccessUnitsRemainingInChunk(true))
- return;
-
- // Requests new data if the the last access unit of the next chunk is not EOS.
- current_demuxer_data_index_ = inactive_demuxer_data_index();
- const AccessUnit& last_access_unit =
- received_data_[current_demuxer_data_index_].access_units.back();
- if (!last_access_unit.is_end_of_stream &&
- last_access_unit.status != DemuxerStream::kAborted) {
- RequestData(base::Closure());
- }
-}
-
-void MediaDecoderJob::InitializeReceivedData() {
- for (size_t i = 0; i < 2; ++i) {
- received_data_[i] = DemuxerData();
- access_unit_index_[i] = 0;
- }
-}
-
-void MediaDecoderJob::OnDecoderDrained() {
- DVLOG(1) << __FUNCTION__;
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- DCHECK(drain_decoder_);
-
- input_eos_encountered_ = false;
- output_eos_encountered_ = false;
- drain_decoder_ = false;
- ReleaseMediaCodecBridge();
- // Increase the access unit index so that the new decoder will not handle
- // the config change again.
- access_unit_index_[current_demuxer_data_index_]++;
-}
-
-MediaDecoderJob::MediaDecoderJobStatus
- MediaDecoderJob::CreateMediaCodecBridge() {
- DVLOG(1) << __FUNCTION__;
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- DCHECK(decode_cb_.is_null());
-
- if (!HasStream()) {
- ReleaseMediaCodecBridge();
- return STATUS_FAILURE;
- }
-
- // Create |media_codec_bridge_| only if config changes.
- if (media_codec_bridge_ && !need_to_reconfig_decoder_job_)
- return STATUS_SUCCESS;
-
- if (is_content_encrypted_ && !GetMediaCrypto())
- return STATUS_FAILURE;
-
- ReleaseMediaCodecBridge();
- DVLOG(1) << __FUNCTION__ << " : creating new media codec bridge";
-
- return CreateMediaCodecBridgeInternal();
-}
-
-bool MediaDecoderJob::IsCodecReconfigureNeeded(
- const DemuxerConfigs& configs) const {
- if (!AreDemuxerConfigsChanged(configs))
- return false;
- return true;
-}
-
-bool MediaDecoderJob::OnOutputFormatChanged() {
- return true;
-}
-
-bool MediaDecoderJob::UpdateOutputFormat() {
- return false;
-}
-
-void MediaDecoderJob::ReleaseMediaCodecBridge() {
- if (!media_codec_bridge_)
- return;
-
- media_codec_bridge_.reset();
- input_buf_index_ = -1;
-}
-
-} // namespace media

Powered by Google App Engine
This is Rietveld 408576698