Commit 1b82514c authored by Yi Fan's avatar Yi Fan Committed by Commit Bot

add AudioConfig to cast_audio_decoder callback

To fix the issue of decoder reporting different sample rate
from the demuxer.

some AAC streams' (from NBC Sports/ESPN, etc) ADTS header info,
especially the sample rate, does not match the payload. The
demuxer reports wrong sample rate to mixer, causing incorrect
audio resampling. Currently the decodedbuffer does not include
the sample rate property, so add AudioConfig field to the callback
to return the info back to mixer and adjust the sample rate when
needed. It should apply to all audio paths that needs AudioConfig.

Bug: internal b/112898981
Test: local test NBC sports, audio sounds normal

Depends-On: eureka-internal/199064

Change-Id: Iebef3acf50e856c8fcb47c8d0b13c3598c6df20f
Reviewed-on: https://chromium-review.googlesource.com/1213320
Commit-Queue: Yi Fan <yfa@chromium.org>
Reviewed-by: default avatarKenneth MacKay <kmackay@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589677}
parent f789584a
...@@ -217,7 +217,7 @@ AudioDecoderAndroid::BufferStatus AudioDecoderAndroid::PushBuffer( ...@@ -217,7 +217,7 @@ AudioDecoderAndroid::BufferStatus AudioDecoderAndroid::PushBuffer(
FROM_HERE, FROM_HERE,
base::Bind(&AudioDecoderAndroid::OnBufferDecoded, base::Bind(&AudioDecoderAndroid::OnBufferDecoded,
weak_factory_.GetWeakPtr(), input_bytes, weak_factory_.GetWeakPtr(), input_bytes,
CastAudioDecoder::Status::kDecodeOk, buffer_base)); CastAudioDecoder::Status::kDecodeOk, config_, buffer_base));
return MediaPipelineBackendAndroid::kBufferPending; return MediaPipelineBackendAndroid::kBufferPending;
} }
...@@ -369,6 +369,7 @@ void AudioDecoderAndroid::OnDecoderInitialized(bool success) { ...@@ -369,6 +369,7 @@ void AudioDecoderAndroid::OnDecoderInitialized(bool success) {
void AudioDecoderAndroid::OnBufferDecoded( void AudioDecoderAndroid::OnBufferDecoded(
uint64_t input_bytes, uint64_t input_bytes,
CastAudioDecoder::Status status, CastAudioDecoder::Status status,
const AudioConfig& config,
const scoped_refptr<DecoderBufferBase>& decoded) { const scoped_refptr<DecoderBufferBase>& decoded) {
if (decoded->end_of_stream()) { if (decoded->end_of_stream()) {
VLOG(3) << __func__ << ": EOS"; VLOG(3) << __func__ << ": EOS";
...@@ -407,6 +408,8 @@ void AudioDecoderAndroid::OnBufferDecoded( ...@@ -407,6 +408,8 @@ void AudioDecoderAndroid::OnBufferDecoded(
DCHECK(!rate_shifter_info_.empty()); DCHECK(!rate_shifter_info_.empty());
// TODO(yfa): handle sample rate change correctly here (from AudioConfig)
// If not AudioChannel::kAll, wipe all other channels for stereo sound. // If not AudioChannel::kAll, wipe all other channels for stereo sound.
if (backend_->AudioChannel() != AudioChannel::kAll) { if (backend_->AudioChannel() != AudioChannel::kAll) {
// There is an assumption hardcoded for playout_channel to be left // There is an assumption hardcoded for playout_channel to be left
......
...@@ -80,6 +80,7 @@ class AudioDecoderAndroid : public MediaPipelineBackend::AudioDecoder, ...@@ -80,6 +80,7 @@ class AudioDecoderAndroid : public MediaPipelineBackend::AudioDecoder,
void OnDecoderInitialized(bool success); void OnDecoderInitialized(bool success);
void OnBufferDecoded(uint64_t input_bytes, void OnBufferDecoded(uint64_t input_bytes,
CastAudioDecoder::Status status, CastAudioDecoder::Status status,
const AudioConfig& config,
const scoped_refptr<DecoderBufferBase>& decoded); const scoped_refptr<DecoderBufferBase>& decoded);
void CheckBufferComplete(); void CheckBufferComplete();
void PushRateShifted(); void PushRateShifted();
......
...@@ -269,10 +269,10 @@ AudioDecoderForMixer::BufferStatus AudioDecoderForMixer::PushBuffer( ...@@ -269,10 +269,10 @@ AudioDecoderForMixer::BufferStatus AudioDecoderForMixer::PushBuffer(
if (BypassDecoder()) { if (BypassDecoder()) {
DCHECK(!decoder_); DCHECK(!decoder_);
task_runner_->PostTask( task_runner_->PostTask(
FROM_HERE, FROM_HERE, base::BindOnce(&AudioDecoderForMixer::OnBufferDecoded,
base::BindOnce(&AudioDecoderForMixer::OnBufferDecoded, weak_factory_.GetWeakPtr(), input_bytes,
weak_factory_.GetWeakPtr(), input_bytes, CastAudioDecoder::Status::kDecodeOk, config_,
CastAudioDecoder::Status::kDecodeOk, buffer_base)); buffer_base));
return MediaPipelineBackend::kBufferPending; return MediaPipelineBackend::kBufferPending;
} }
...@@ -409,6 +409,7 @@ void AudioDecoderForMixer::OnDecoderInitialized(bool success) { ...@@ -409,6 +409,7 @@ void AudioDecoderForMixer::OnDecoderInitialized(bool success) {
void AudioDecoderForMixer::OnBufferDecoded( void AudioDecoderForMixer::OnBufferDecoded(
uint64_t input_bytes, uint64_t input_bytes,
CastAudioDecoder::Status status, CastAudioDecoder::Status status,
const AudioConfig& config,
const scoped_refptr<DecoderBufferBase>& decoded) { const scoped_refptr<DecoderBufferBase>& decoded) {
TRACE_FUNCTION_ENTRY0(); TRACE_FUNCTION_ENTRY0();
DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(task_runner_->BelongsToCurrentThread());
...@@ -440,6 +441,22 @@ void AudioDecoderForMixer::OnBufferDecoded( ...@@ -440,6 +441,22 @@ void AudioDecoderForMixer::OnBufferDecoded(
} else { } else {
int input_frames = decoded->data_size() / (kNumChannels * sizeof(float)); int input_frames = decoded->data_size() / (kNumChannels * sizeof(float));
if (config.samples_per_second != config_.samples_per_second) {
LOG(WARNING) << "mixer_input sample_rate changed to: "
<< config.samples_per_second;
CreateRateShifter(config.samples_per_second);
mixer_input_.reset();
mixer_input_.reset(new BufferingMixerSource(
this, config.samples_per_second, backend_->Primary(),
backend_->DeviceId(), backend_->ContentType(),
ToPlayoutChannel(backend_->AudioChannel()), playback_start_pts_,
start_playback_asap_));
mixer_input_->SetVolumeMultiplier(volume_multiplier_);
pending_output_frames_ = kNoPendingOutput;
config_.samples_per_second = config.samples_per_second;
last_mixer_delay_ = RenderingDelay();
}
last_push_pts_ = decoded->timestamp(); last_push_pts_ = decoded->timestamp();
last_push_pts_length_ = last_push_pts_length_ =
input_frames * kMicrosecondsPerSecond / config_.samples_per_second; input_frames * kMicrosecondsPerSecond / config_.samples_per_second;
......
...@@ -83,6 +83,7 @@ class AudioDecoderForMixer : public MediaPipelineBackend::AudioDecoder, ...@@ -83,6 +83,7 @@ class AudioDecoderForMixer : public MediaPipelineBackend::AudioDecoder,
void OnDecoderInitialized(bool success); void OnDecoderInitialized(bool success);
void OnBufferDecoded(uint64_t input_bytes, void OnBufferDecoded(uint64_t input_bytes,
CastAudioDecoder::Status status, CastAudioDecoder::Status status,
const AudioConfig& config,
const scoped_refptr<DecoderBufferBase>& decoded); const scoped_refptr<DecoderBufferBase>& decoded);
void CheckBufferComplete(); void CheckBufferComplete();
void PushRateShifted(); void PushRateShifted();
......
...@@ -161,6 +161,7 @@ void AudioDecoderSoftwareWrapper::OnDecoderInitialized(bool success) { ...@@ -161,6 +161,7 @@ void AudioDecoderSoftwareWrapper::OnDecoderInitialized(bool success) {
void AudioDecoderSoftwareWrapper::OnDecodedBuffer( void AudioDecoderSoftwareWrapper::OnDecodedBuffer(
CastAudioDecoder::Status status, CastAudioDecoder::Status status,
const media::AudioConfig& config,
const scoped_refptr<DecoderBufferBase>& decoded) { const scoped_refptr<DecoderBufferBase>& decoded) {
DCHECK(delegate_); DCHECK(delegate_);
if (status != CastAudioDecoder::kDecodeOk) { if (status != CastAudioDecoder::kDecodeOk) {
......
...@@ -44,6 +44,7 @@ class AudioDecoderSoftwareWrapper ...@@ -44,6 +44,7 @@ class AudioDecoderSoftwareWrapper
bool CreateSoftwareDecoder(const AudioConfig& config); bool CreateSoftwareDecoder(const AudioConfig& config);
void OnDecoderInitialized(bool success); void OnDecoderInitialized(bool success);
void OnDecodedBuffer(CastAudioDecoder::Status status, void OnDecodedBuffer(CastAudioDecoder::Status status,
const media::AudioConfig& config,
const scoped_refptr<DecoderBufferBase>& decoded); const scoped_refptr<DecoderBufferBase>& decoded);
// MediaPipelineBackend::Decoder::Delegate implementation: // MediaPipelineBackend::Decoder::Delegate implementation:
......
...@@ -92,7 +92,8 @@ class CastAudioDecoderImpl : public CastAudioDecoder { ...@@ -92,7 +92,8 @@ class CastAudioDecoderImpl : public CastAudioDecoder {
// Post the task to ensure that |decode_callback| is not called from // Post the task to ensure that |decode_callback| is not called from
// within a call to Decode(). // within a call to Decode().
task_runner_->PostTask( task_runner_->PostTask(
FROM_HERE, base::BindOnce(decode_callback, kDecodeError, data)); FROM_HERE,
base::BindOnce(decode_callback, kDecodeError, config_, data));
} else if (!initialized_ || decode_pending_) { } else if (!initialized_ || decode_pending_) {
decode_queue_.push(std::make_pair(data, decode_callback)); decode_queue_.push(std::make_pair(data, decode_callback));
} else { } else {
...@@ -110,8 +111,8 @@ class CastAudioDecoderImpl : public CastAudioDecoder { ...@@ -110,8 +111,8 @@ class CastAudioDecoderImpl : public CastAudioDecoder {
if (data->end_of_stream()) { if (data->end_of_stream()) {
// Post the task to ensure that |decode_callback| is not called from // Post the task to ensure that |decode_callback| is not called from
// within a call to Decode(). // within a call to Decode().
task_runner_->PostTask(FROM_HERE, task_runner_->PostTask(
base::BindOnce(decode_callback, kDecodeOk, data)); FROM_HERE, base::BindOnce(decode_callback, kDecodeOk, config_, data));
return; return;
} }
...@@ -168,7 +169,7 @@ class CastAudioDecoderImpl : public CastAudioDecoder { ...@@ -168,7 +169,7 @@ class CastAudioDecoderImpl : public CastAudioDecoder {
decoded_chunks_.clear(); decoded_chunks_.clear();
decoded->set_timestamp(buffer_timestamp); decoded->set_timestamp(buffer_timestamp);
base::WeakPtr<CastAudioDecoderImpl> self = weak_factory_.GetWeakPtr(); base::WeakPtr<CastAudioDecoderImpl> self = weak_factory_.GetWeakPtr();
decode_callback.Run(result_status, decoded); decode_callback.Run(result_status, config_, decoded);
if (!self.get()) if (!self.get())
return; // Return immediately if the decode callback deleted this. return; // Return immediately if the decode callback deleted this.
...@@ -188,6 +189,11 @@ class CastAudioDecoderImpl : public CastAudioDecoder { ...@@ -188,6 +189,11 @@ class CastAudioDecoderImpl : public CastAudioDecoder {
} }
void OnDecoderOutput(const scoped_refptr<::media::AudioBuffer>& decoded) { void OnDecoderOutput(const scoped_refptr<::media::AudioBuffer>& decoded) {
if (decoded->sample_rate() != config_.samples_per_second) {
LOG(WARNING) << "sample_rate changed to " << decoded->sample_rate()
<< " from " << config_.samples_per_second;
config_.samples_per_second = decoded->sample_rate();
}
decoded_chunks_.push_back(decoded); decoded_chunks_.push_back(decoded);
} }
......
...@@ -40,7 +40,9 @@ class CastAudioDecoder { ...@@ -40,7 +40,9 @@ class CastAudioDecoder {
typedef base::Callback<void(bool success)> InitializedCallback; typedef base::Callback<void(bool success)> InitializedCallback;
typedef base::Callback<void( typedef base::Callback<void(
Status status, Status status,
const scoped_refptr<media::DecoderBufferBase>& decoded)> DecodeCallback; const AudioConfig& config,
const scoped_refptr<media::DecoderBufferBase>& decoded)>
DecodeCallback;
// Creates a CastAudioDecoder instance for the given |config|. Decoding must // Creates a CastAudioDecoder instance for the given |config|. Decoding must
// occur on the same thread as |task_runner|. Returns an empty unique_ptr if // occur on the same thread as |task_runner|. Returns an empty unique_ptr if
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment