Chromium Code Reviews| 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); |
|
xhwang
2014/05/30 21:58:07
Why |is_audio_encrypted| is special?
Actually, c
qinmin
2014/05/30 23:43:33
is_content_encrypted_ is private in base class, so
|
| + 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()); |
|
xhwang
2014/05/30 21:58:07
If we separate DemuxerConfigs into AudioConfig and
|
| +} |
| + |
| +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 |