Commit 267652ed authored by miu's avatar miu Committed by Commit bot

[cast/test] Use AudioConverter in FakeMediaSource to play back 6-channel WEBM's.

Replaces the use of MultiChannelResampler with AudioConverter in
FakeMediaSource to allow the cast_sender_app and cast_simulator to
re-mix any-number-of-channels audio into the 2-channel audio for Cast
sending.

Review URL: https://codereview.chromium.org/900913004

Cr-Commit-Position: refs/heads/master@{#314680}
parent 1ea8a245
......@@ -15,7 +15,6 @@
#include "media/base/audio_fifo.h"
#include "media/base/audio_timestamp_helper.h"
#include "media/base/media.h"
#include "media/base/multi_channel_resampler.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
#include "media/cast/cast_sender.h"
......@@ -31,8 +30,6 @@
namespace {
static const int kAudioChannels = 2;
static const int kAudioSamplingFrequency = 48000;
static const int kSoundFrequency = 440; // Frequency of sinusoid wave.
static const float kSoundVolume = 0.10f;
static const int kAudioFrameMs = 10; // Each audio frame is exactly 10ms.
......@@ -69,9 +66,15 @@ namespace cast {
FakeMediaSource::FakeMediaSource(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
base::TickClock* clock,
const AudioSenderConfig& audio_config,
const VideoSenderConfig& video_config,
bool keep_frames)
: task_runner_(task_runner),
output_audio_params_(AudioParameters::AUDIO_PCM_LINEAR,
media::GuessChannelLayout(audio_config.channels),
audio_config.frequency,
32,
audio_config.frequency / kAudioPacketsPerSecond),
video_config_(video_config),
keep_frames_(keep_frames),
variable_frame_size_mode_(false),
......@@ -88,8 +91,9 @@ FakeMediaSource::FakeMediaSource(
video_first_pts_(0),
video_first_pts_set_(false),
weak_factory_(this) {
audio_bus_factory_.reset(new TestAudioBusFactory(kAudioChannels,
kAudioSamplingFrequency,
CHECK(output_audio_params_.IsValid());
audio_bus_factory_.reset(new TestAudioBusFactory(audio_config.channels,
audio_config.frequency,
kSoundFrequency,
kSoundVolume));
}
......@@ -161,13 +165,14 @@ void FakeMediaSource::SetSourceFile(const base::FilePath& video_file,
LOG(WARNING) << "Found multiple audio streams.";
}
audio_stream_index_ = static_cast<int>(i);
audio_params_.Reset(
source_audio_params_.Reset(
AudioParameters::AUDIO_PCM_LINEAR,
layout,
av_codec_context->channels,
av_codec_context->sample_rate,
8 * av_get_bytes_per_sample(av_codec_context->sample_fmt),
av_codec_context->sample_rate / kAudioPacketsPerSecond);
CHECK(source_audio_params_.IsValid());
LOG(INFO) << "Source file has audio.";
} else if (av_codec->type == AVMEDIA_TYPE_VIDEO) {
VideoFrame::Format format =
......@@ -228,21 +233,18 @@ void FakeMediaSource::Start(scoped_refptr<AudioFrameInput> audio_frame_input,
}
// Send transcoding streams.
audio_algo_.Initialize(audio_params_);
audio_algo_.Initialize(source_audio_params_);
audio_algo_.FlushBuffers();
audio_fifo_input_bus_ =
AudioBus::Create(
audio_params_.channels(), audio_params_.frames_per_buffer());
audio_fifo_input_bus_ = AudioBus::Create(
source_audio_params_.channels(),
source_audio_params_.frames_per_buffer());
// Audio FIFO can carry all data fron AudioRendererAlgorithm.
audio_fifo_.reset(
new AudioFifo(audio_params_.channels(),
new AudioFifo(source_audio_params_.channels(),
audio_algo_.QueueCapacity()));
audio_resampler_.reset(new media::MultiChannelResampler(
audio_params_.channels(),
static_cast<double>(audio_params_.sample_rate()) /
kAudioSamplingFrequency,
audio_params_.frames_per_buffer(),
base::Bind(&FakeMediaSource::ProvideData, weak_factory_.GetWeakPtr())));
audio_converter_.reset(new media::AudioConverter(
source_audio_params_, output_audio_params_, true));
audio_converter_->AddInput(this);
task_runner_->PostTask(
FROM_HERE,
base::Bind(&FakeMediaSource::SendNextFrame, weak_factory_.GetWeakPtr()));
......@@ -462,7 +464,7 @@ void FakeMediaSource::DecodeAudio(ScopedAVPacket packet) {
// Not the frequency of the source file. This is because we
// increment the frame count by samples we sent.
audio_sent_ts_.reset(
new AudioTimestampHelper(kAudioSamplingFrequency));
new AudioTimestampHelper(output_audio_params_.sample_rate()));
// For some files this is an invalid value.
base::TimeDelta base_ts;
audio_sent_ts_->SetBaseTimestamp(base_ts);
......@@ -506,16 +508,15 @@ void FakeMediaSource::DecodeAudio(ScopedAVPacket packet) {
// Make sure there's enough data to resample audio.
if (audio_fifo_->frames() <
2 * audio_params_.sample_rate() / kAudioPacketsPerSecond) {
2 * source_audio_params_.sample_rate() / kAudioPacketsPerSecond) {
continue;
}
scoped_ptr<media::AudioBus> resampled_bus(
media::AudioBus::Create(
audio_params_.channels(),
kAudioSamplingFrequency / kAudioPacketsPerSecond));
audio_resampler_->Resample(resampled_bus->frames(),
resampled_bus.get());
output_audio_params_.channels(),
output_audio_params_.sample_rate() / kAudioPacketsPerSecond));
audio_converter_->Convert(resampled_bus.get());
audio_bus_queue_.push(resampled_bus.release());
}
}
......@@ -588,13 +589,15 @@ void FakeMediaSource::Decode(bool decode_audio) {
}
}
void FakeMediaSource::ProvideData(int frame_delay,
media::AudioBus* output_bus) {
double FakeMediaSource::ProvideInput(media::AudioBus* output_bus,
base::TimeDelta buffer_delay) {
if (audio_fifo_->frames() >= output_bus->frames()) {
audio_fifo_->Consume(output_bus, 0, output_bus->frames());
return 1.0;
} else {
LOG(WARNING) << "Not enough audio data for resampling.";
output_bus->Zero();
return 0.0;
}
}
......
......@@ -19,6 +19,7 @@
#include "base/single_thread_task_runner.h"
#include "base/time/tick_clock.h"
#include "media/audio/audio_parameters.h"
#include "media/base/audio_converter.h"
#include "media/cast/cast_config.h"
#include "media/filters/audio_renderer_algorithm.h"
#include "media/filters/ffmpeg_demuxer.h"
......@@ -29,11 +30,11 @@ struct AVFormatContext;
namespace media {
class AudioBus;
class AudioConverter;
class AudioFifo;
class AudioTimestampHelper;
class FFmpegGlue;
class InMemoryUrlProtocol;
class MultiChannelResampler;
namespace cast {
......@@ -41,17 +42,19 @@ class AudioFrameInput;
class VideoFrameInput;
class TestAudioBusFactory;
class FakeMediaSource {
class FakeMediaSource : public media::AudioConverter::InputCallback {
public:
// |task_runner| is to schedule decoding tasks.
// |clock| is used by this source but is not owned.
// |audio_config| is the desired audio config.
// |video_config| is the desired video config.
// |keep_frames| is true if all VideoFrames are saved in a queue.
FakeMediaSource(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
base::TickClock* clock,
const AudioSenderConfig& audio_config,
const VideoSenderConfig& video_config,
bool keep_frames);
~FakeMediaSource();
~FakeMediaSource() override;
// Transcode this file as the source of video and audio frames.
// If |override_fps| is non zero then the file is played at the desired rate.
......@@ -100,7 +103,9 @@ class FakeMediaSource {
void DecodeVideo(ScopedAVPacket packet);
void Decode(bool decode_audio);
void ProvideData(int frame_delay, media::AudioBus* output_bus);
// media::AudioConverter::InputCallback implementation.
double ProvideInput(media::AudioBus* output_bus, base::TimeDelta buffer_delay)
override;
AVStream* av_audio_stream();
AVStream* av_video_stream();
......@@ -108,6 +113,7 @@ class FakeMediaSource {
AVCodecContext* av_video_context();
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
const media::AudioParameters output_audio_params_;
const VideoSenderConfig video_config_;
const bool keep_frames_;
bool variable_frame_size_mode_;
......@@ -132,7 +138,7 @@ class FakeMediaSource {
AVFormatContext* av_format_context_;
int audio_stream_index_;
AudioParameters audio_params_;
AudioParameters source_audio_params_;
double playback_rate_;
int video_stream_index_;
......@@ -140,7 +146,7 @@ class FakeMediaSource {
int video_frame_rate_denominator_;
// These are used for audio resampling.
scoped_ptr<media::MultiChannelResampler> audio_resampler_;
scoped_ptr<media::AudioConverter> audio_converter_;
scoped_ptr<media::AudioFifo> audio_fifo_;
scoped_ptr<media::AudioBus> audio_fifo_input_bus_;
media::AudioRendererAlgorithm audio_algo_;
......
......@@ -259,7 +259,9 @@ int main(int argc, char** argv) {
scoped_ptr<media::cast::FakeMediaSource> fake_media_source(
new media::cast::FakeMediaSource(test_thread.message_loop_proxy(),
cast_environment->Clock(),
video_config, false));
audio_config,
video_config,
false));
int override_fps = 0;
if (!base::StringToInt(cmd->GetSwitchValueASCII(kSwitchFps),
......
......@@ -480,6 +480,7 @@ void RunSimulation(const base::FilePath& source_path,
const bool quality_test = !metrics_output_path.empty();
FakeMediaSource media_source(task_runner,
&testing_clock,
audio_sender_config,
video_sender_config,
quality_test);
scoped_ptr<EncodedVideoFrameTracker> video_frame_tracker;
......
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