| Index: media/base/android/audio_decoder_job.cc
|
| diff --git a/media/base/android/audio_decoder_job.cc b/media/base/android/audio_decoder_job.cc
|
| index 580c63f13af6994576000f4f9cfe0a1b32241c4b..ad11624b9ef2e5cb886915555c9d2db784835756 100644
|
| --- a/media/base/android/audio_decoder_job.cc
|
| +++ b/media/base/android/audio_decoder_job.cc
|
| @@ -32,48 +32,35 @@ class AudioDecoderThread : public base::Thread {
|
| base::LazyInstance<AudioDecoderThread>::Leaky
|
| g_audio_decoder_thread = LAZY_INSTANCE_INITIALIZER;
|
|
|
| -AudioDecoderJob* AudioDecoderJob::Create(
|
| - const AudioCodec audio_codec,
|
| - int sample_rate,
|
| - int channel_count,
|
| - const uint8* extra_data,
|
| - size_t extra_data_size,
|
| - jobject media_crypto,
|
| - const base::Closure& request_data_cb) {
|
| - scoped_ptr<AudioCodecBridge> codec(AudioCodecBridge::Create(audio_codec));
|
| - if (codec && codec->Start(audio_codec, sample_rate, channel_count, extra_data,
|
| - extra_data_size, true, media_crypto)) {
|
| - scoped_ptr<AudioTimestampHelper> audio_timestamp_helper(
|
| - new AudioTimestampHelper(sample_rate));
|
| - return new AudioDecoderJob(
|
| - audio_timestamp_helper.Pass(), codec.Pass(),
|
| - kBytesPerAudioOutputSample * channel_count, request_data_cb);
|
| - }
|
| - LOG(ERROR) << "Failed to create AudioDecoderJob.";
|
| - return NULL;
|
| -}
|
| -
|
| AudioDecoderJob::AudioDecoderJob(
|
| - scoped_ptr<AudioTimestampHelper> audio_timestamp_helper,
|
| - scoped_ptr<AudioCodecBridge> audio_codec_bridge,
|
| - int bytes_per_frame,
|
| - const base::Closure& request_data_cb)
|
| + const base::Closure& request_data_cb,
|
| + const base::Closure& on_demuxer_config_changed_cb)
|
| : MediaDecoderJob(g_audio_decoder_thread.Pointer()->message_loop_proxy(),
|
| - audio_codec_bridge.get(), request_data_cb),
|
| - bytes_per_frame_(bytes_per_frame),
|
| - audio_codec_bridge_(audio_codec_bridge.Pass()),
|
| - audio_timestamp_helper_(audio_timestamp_helper.Pass()) {
|
| + request_data_cb,
|
| + on_demuxer_config_changed_cb),
|
| + audio_codec_(kUnknownAudioCodec),
|
| + num_channels_(0),
|
| + sampling_rate_(0),
|
| + volume_(-1.0),
|
| + bytes_per_frame_(0) {
|
| }
|
|
|
| -AudioDecoderJob::~AudioDecoderJob() {
|
| +AudioDecoderJob::~AudioDecoderJob() {}
|
| +
|
| +bool AudioDecoderJob::HasStream() const {
|
| + return audio_codec_ != kUnknownAudioCodec;
|
| }
|
|
|
| void AudioDecoderJob::SetVolume(double volume) {
|
| - audio_codec_bridge_->SetVolume(volume);
|
| + volume_ = volume;
|
| + SetVolumeInternal();
|
| }
|
|
|
| void AudioDecoderJob::SetBaseTimestamp(base::TimeDelta base_timestamp) {
|
| - audio_timestamp_helper_->SetBaseTimestamp(base_timestamp);
|
| + DCHECK(!is_decoding());
|
| + base_timestamp_ = base_timestamp;
|
| + if (audio_timestamp_helper_)
|
| + audio_timestamp_helper_->SetBaseTimestamp(base_timestamp_);
|
| }
|
|
|
| void AudioDecoderJob::ReleaseOutputBuffer(
|
| @@ -84,9 +71,10 @@ void AudioDecoderJob::ReleaseOutputBuffer(
|
| const ReleaseOutputCompletionCallback& callback) {
|
| render_output = render_output && (size != 0u);
|
| if (render_output) {
|
| - int64 head_position = audio_codec_bridge_->PlayOutputBuffer(
|
| - output_buffer_index, size);
|
| - audio_timestamp_helper_->AddFrames(size / (bytes_per_frame_));
|
| + int64 head_position =(static_cast<AudioCodecBridge*>(
|
| + media_codec_bridge_.get()))->PlayOutputBuffer(
|
| + output_buffer_index, size);
|
| + audio_timestamp_helper_->AddFrames(size / bytes_per_frame_);
|
| int64 frames_to_play =
|
| audio_timestamp_helper_->frame_count() - head_position;
|
| DCHECK_GE(frames_to_play, 0);
|
| @@ -96,7 +84,8 @@ void AudioDecoderJob::ReleaseOutputBuffer(
|
| } else {
|
| current_presentation_timestamp = kNoTimestamp();
|
| }
|
| - audio_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, false);
|
| + media_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, false);
|
| +
|
| callback.Run(current_presentation_timestamp,
|
| audio_timestamp_helper_->GetTimestamp());
|
| }
|
| @@ -105,4 +94,54 @@ bool AudioDecoderJob::ComputeTimeToRender() const {
|
| return false;
|
| }
|
|
|
| +void AudioDecoderJob::UpdateDemuxerConfigs(const DemuxerConfigs& configs) {
|
| + audio_codec_ = configs.audio_codec;
|
| + num_channels_ = configs.audio_channels;
|
| + sampling_rate_ = configs.audio_sampling_rate;
|
| + set_is_content_encrypted(configs.is_audio_encrypted);
|
| + audio_extra_data_ = configs.audio_extra_data;
|
| + bytes_per_frame_ = kBytesPerAudioOutputSample * num_channels_;
|
| +}
|
| +
|
| +bool AudioDecoderJob::IsDemuxerConfigChanged(
|
| + const DemuxerConfigs& configs) const {
|
| + return audio_codec_ != configs.audio_codec ||
|
| + num_channels_ != configs.audio_channels ||
|
| + sampling_rate_ != configs.audio_sampling_rate ||
|
| + is_content_encrypted() != configs.is_audio_encrypted ||
|
| + audio_extra_data_.size() != configs.audio_extra_data.size() ||
|
| + !std::equal(audio_extra_data_.begin(),
|
| + audio_extra_data_.end(),
|
| + configs.audio_extra_data.begin());
|
| +}
|
| +
|
| +bool AudioDecoderJob::CreateMediaCodecBridgeInternal() {
|
| + media_codec_bridge_.reset(AudioCodecBridge::Create(audio_codec_));
|
| + if (!media_codec_bridge_)
|
| + return false;
|
| +
|
| + if (!(static_cast<AudioCodecBridge*>(media_codec_bridge_.get()))->Start(
|
| + audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0],
|
| + audio_extra_data_.size(), true, GetMediaCrypto().obj())) {
|
| + media_codec_bridge_.reset();
|
| + return false;
|
| + }
|
| +
|
| + SetVolumeInternal();
|
| +
|
| + // Need to pass the base timestamp to the new decoder.
|
| + if (audio_timestamp_helper_)
|
| + base_timestamp_ = audio_timestamp_helper_->GetTimestamp();
|
| + audio_timestamp_helper_.reset(new AudioTimestampHelper(sampling_rate_));
|
| + audio_timestamp_helper_->SetBaseTimestamp(base_timestamp_);
|
| + return true;
|
| +}
|
| +
|
| +void AudioDecoderJob::SetVolumeInternal() {
|
| + if (media_codec_bridge_) {
|
| + static_cast<AudioCodecBridge*>(media_codec_bridge_.get())->SetVolume(
|
| + volume_);
|
| + }
|
| +}
|
| +
|
| } // namespace media
|
|
|