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

Side by Side Diff: media/cast/test/fake_media_source.cc

Issue 900913004: [cast/test] Use AudioConverter in FakeMediaSource to play back 6-channel WEBM's. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 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 unified diff | Download patch
« no previous file with comments | « media/cast/test/fake_media_source.h ('k') | media/cast/test/sender.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/cast/test/fake_media_source.h" 5 #include "media/cast/test/fake_media_source.h"
6 6
7 #include "base/files/memory_mapped_file.h" 7 #include "base/files/memory_mapped_file.h"
8 #include "base/files/scoped_file.h" 8 #include "base/files/scoped_file.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/rand_util.h" 10 #include "base/rand_util.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "media/audio/audio_parameters.h" 12 #include "media/audio/audio_parameters.h"
13 #include "media/base/audio_buffer.h" 13 #include "media/base/audio_buffer.h"
14 #include "media/base/audio_bus.h" 14 #include "media/base/audio_bus.h"
15 #include "media/base/audio_fifo.h" 15 #include "media/base/audio_fifo.h"
16 #include "media/base/audio_timestamp_helper.h" 16 #include "media/base/audio_timestamp_helper.h"
17 #include "media/base/media.h" 17 #include "media/base/media.h"
18 #include "media/base/multi_channel_resampler.h"
19 #include "media/base/video_frame.h" 18 #include "media/base/video_frame.h"
20 #include "media/base/video_util.h" 19 #include "media/base/video_util.h"
21 #include "media/cast/cast_sender.h" 20 #include "media/cast/cast_sender.h"
22 #include "media/cast/test/utility/audio_utility.h" 21 #include "media/cast/test/utility/audio_utility.h"
23 #include "media/cast/test/utility/video_utility.h" 22 #include "media/cast/test/utility/video_utility.h"
24 #include "media/ffmpeg/ffmpeg_common.h" 23 #include "media/ffmpeg/ffmpeg_common.h"
25 #include "media/ffmpeg/ffmpeg_deleters.h" 24 #include "media/ffmpeg/ffmpeg_deleters.h"
26 #include "media/filters/audio_renderer_algorithm.h" 25 #include "media/filters/audio_renderer_algorithm.h"
27 #include "media/filters/ffmpeg_demuxer.h" 26 #include "media/filters/ffmpeg_demuxer.h"
28 #include "media/filters/ffmpeg_glue.h" 27 #include "media/filters/ffmpeg_glue.h"
29 #include "media/filters/in_memory_url_protocol.h" 28 #include "media/filters/in_memory_url_protocol.h"
30 #include "ui/gfx/geometry/size.h" 29 #include "ui/gfx/geometry/size.h"
31 30
32 namespace { 31 namespace {
33 32
34 static const int kAudioChannels = 2;
35 static const int kAudioSamplingFrequency = 48000;
36 static const int kSoundFrequency = 440; // Frequency of sinusoid wave. 33 static const int kSoundFrequency = 440; // Frequency of sinusoid wave.
37 static const float kSoundVolume = 0.10f; 34 static const float kSoundVolume = 0.10f;
38 static const int kAudioFrameMs = 10; // Each audio frame is exactly 10ms. 35 static const int kAudioFrameMs = 10; // Each audio frame is exactly 10ms.
39 static const int kAudioPacketsPerSecond = 1000 / kAudioFrameMs; 36 static const int kAudioPacketsPerSecond = 1000 / kAudioFrameMs;
40 37
41 // Bounds for variable frame size mode. 38 // Bounds for variable frame size mode.
42 static const int kMinFakeFrameWidth = 60; 39 static const int kMinFakeFrameWidth = 60;
43 static const int kMinFakeFrameHeight = 34; 40 static const int kMinFakeFrameHeight = 34;
44 static const int kStartingFakeFrameWidth = 854; 41 static const int kStartingFakeFrameWidth = 854;
45 static const int kStartingFakeFrameHeight = 480; 42 static const int kStartingFakeFrameHeight = 480;
(...skipping 16 matching lines...) Expand all
62 } 59 }
63 60
64 } // namespace 61 } // namespace
65 62
66 namespace media { 63 namespace media {
67 namespace cast { 64 namespace cast {
68 65
69 FakeMediaSource::FakeMediaSource( 66 FakeMediaSource::FakeMediaSource(
70 scoped_refptr<base::SingleThreadTaskRunner> task_runner, 67 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
71 base::TickClock* clock, 68 base::TickClock* clock,
69 const AudioSenderConfig& audio_config,
72 const VideoSenderConfig& video_config, 70 const VideoSenderConfig& video_config,
73 bool keep_frames) 71 bool keep_frames)
74 : task_runner_(task_runner), 72 : task_runner_(task_runner),
73 output_audio_params_(AudioParameters::AUDIO_PCM_LINEAR,
74 media::GuessChannelLayout(audio_config.channels),
75 audio_config.frequency,
76 32,
77 audio_config.frequency / kAudioPacketsPerSecond),
75 video_config_(video_config), 78 video_config_(video_config),
76 keep_frames_(keep_frames), 79 keep_frames_(keep_frames),
77 variable_frame_size_mode_(false), 80 variable_frame_size_mode_(false),
78 synthetic_count_(0), 81 synthetic_count_(0),
79 clock_(clock), 82 clock_(clock),
80 audio_frame_count_(0), 83 audio_frame_count_(0),
81 video_frame_count_(0), 84 video_frame_count_(0),
82 av_format_context_(NULL), 85 av_format_context_(NULL),
83 audio_stream_index_(-1), 86 audio_stream_index_(-1),
84 playback_rate_(1.0), 87 playback_rate_(1.0),
85 video_stream_index_(-1), 88 video_stream_index_(-1),
86 video_frame_rate_numerator_(video_config.max_frame_rate), 89 video_frame_rate_numerator_(video_config.max_frame_rate),
87 video_frame_rate_denominator_(1), 90 video_frame_rate_denominator_(1),
88 video_first_pts_(0), 91 video_first_pts_(0),
89 video_first_pts_set_(false), 92 video_first_pts_set_(false),
90 weak_factory_(this) { 93 weak_factory_(this) {
91 audio_bus_factory_.reset(new TestAudioBusFactory(kAudioChannels, 94 CHECK(output_audio_params_.IsValid());
92 kAudioSamplingFrequency, 95 audio_bus_factory_.reset(new TestAudioBusFactory(audio_config.channels,
96 audio_config.frequency,
93 kSoundFrequency, 97 kSoundFrequency,
94 kSoundVolume)); 98 kSoundVolume));
95 } 99 }
96 100
97 FakeMediaSource::~FakeMediaSource() { 101 FakeMediaSource::~FakeMediaSource() {
98 } 102 }
99 103
100 void FakeMediaSource::SetSourceFile(const base::FilePath& video_file, 104 void FakeMediaSource::SetSourceFile(const base::FilePath& video_file,
101 int override_fps) { 105 int override_fps) {
102 DCHECK(!video_file.empty()); 106 DCHECK(!video_file.empty());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 av_codec_context->channel_layout, 158 av_codec_context->channel_layout,
155 av_codec_context->channels); 159 av_codec_context->channels);
156 if (layout == CHANNEL_LAYOUT_UNSUPPORTED) { 160 if (layout == CHANNEL_LAYOUT_UNSUPPORTED) {
157 LOG(ERROR) << "Unsupported audio channels layout."; 161 LOG(ERROR) << "Unsupported audio channels layout.";
158 continue; 162 continue;
159 } 163 }
160 if (audio_stream_index_ != -1) { 164 if (audio_stream_index_ != -1) {
161 LOG(WARNING) << "Found multiple audio streams."; 165 LOG(WARNING) << "Found multiple audio streams.";
162 } 166 }
163 audio_stream_index_ = static_cast<int>(i); 167 audio_stream_index_ = static_cast<int>(i);
164 audio_params_.Reset( 168 source_audio_params_.Reset(
165 AudioParameters::AUDIO_PCM_LINEAR, 169 AudioParameters::AUDIO_PCM_LINEAR,
166 layout, 170 layout,
167 av_codec_context->channels, 171 av_codec_context->channels,
168 av_codec_context->sample_rate, 172 av_codec_context->sample_rate,
169 8 * av_get_bytes_per_sample(av_codec_context->sample_fmt), 173 8 * av_get_bytes_per_sample(av_codec_context->sample_fmt),
170 av_codec_context->sample_rate / kAudioPacketsPerSecond); 174 av_codec_context->sample_rate / kAudioPacketsPerSecond);
175 CHECK(source_audio_params_.IsValid());
171 LOG(INFO) << "Source file has audio."; 176 LOG(INFO) << "Source file has audio.";
172 } else if (av_codec->type == AVMEDIA_TYPE_VIDEO) { 177 } else if (av_codec->type == AVMEDIA_TYPE_VIDEO) {
173 VideoFrame::Format format = 178 VideoFrame::Format format =
174 PixelFormatToVideoFormat(av_codec_context->pix_fmt); 179 PixelFormatToVideoFormat(av_codec_context->pix_fmt);
175 if (format != VideoFrame::YV12) { 180 if (format != VideoFrame::YV12) {
176 LOG(ERROR) << "Cannot handle non YV12 video format: " << format; 181 LOG(ERROR) << "Cannot handle non YV12 video format: " << format;
177 continue; 182 continue;
178 } 183 }
179 if (video_stream_index_ != -1) { 184 if (video_stream_index_ != -1) {
180 LOG(WARNING) << "Found multiple video streams."; 185 LOG(WARNING) << "Found multiple video streams.";
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 if (!is_transcoding_audio() && !is_transcoding_video()) { 226 if (!is_transcoding_audio() && !is_transcoding_video()) {
222 // Send fake patterns. 227 // Send fake patterns.
223 task_runner_->PostTask( 228 task_runner_->PostTask(
224 FROM_HERE, 229 FROM_HERE,
225 base::Bind(&FakeMediaSource::SendNextFakeFrame, 230 base::Bind(&FakeMediaSource::SendNextFakeFrame,
226 weak_factory_.GetWeakPtr())); 231 weak_factory_.GetWeakPtr()));
227 return; 232 return;
228 } 233 }
229 234
230 // Send transcoding streams. 235 // Send transcoding streams.
231 audio_algo_.Initialize(audio_params_); 236 audio_algo_.Initialize(source_audio_params_);
232 audio_algo_.FlushBuffers(); 237 audio_algo_.FlushBuffers();
233 audio_fifo_input_bus_ = 238 audio_fifo_input_bus_ = AudioBus::Create(
234 AudioBus::Create( 239 source_audio_params_.channels(),
235 audio_params_.channels(), audio_params_.frames_per_buffer()); 240 source_audio_params_.frames_per_buffer());
236 // Audio FIFO can carry all data fron AudioRendererAlgorithm. 241 // Audio FIFO can carry all data fron AudioRendererAlgorithm.
237 audio_fifo_.reset( 242 audio_fifo_.reset(
238 new AudioFifo(audio_params_.channels(), 243 new AudioFifo(source_audio_params_.channels(),
239 audio_algo_.QueueCapacity())); 244 audio_algo_.QueueCapacity()));
240 audio_resampler_.reset(new media::MultiChannelResampler( 245 audio_converter_.reset(new media::AudioConverter(
241 audio_params_.channels(), 246 source_audio_params_, output_audio_params_, true));
242 static_cast<double>(audio_params_.sample_rate()) / 247 audio_converter_->AddInput(this);
243 kAudioSamplingFrequency,
244 audio_params_.frames_per_buffer(),
245 base::Bind(&FakeMediaSource::ProvideData, weak_factory_.GetWeakPtr())));
246 task_runner_->PostTask( 248 task_runner_->PostTask(
247 FROM_HERE, 249 FROM_HERE,
248 base::Bind(&FakeMediaSource::SendNextFrame, weak_factory_.GetWeakPtr())); 250 base::Bind(&FakeMediaSource::SendNextFrame, weak_factory_.GetWeakPtr()));
249 } 251 }
250 252
251 void FakeMediaSource::SendNextFakeFrame() { 253 void FakeMediaSource::SendNextFakeFrame() {
252 UpdateNextFrameSize(); 254 UpdateNextFrameSize();
253 scoped_refptr<VideoFrame> video_frame = 255 scoped_refptr<VideoFrame> video_frame =
254 VideoFrame::CreateBlackFrame(current_frame_size_); 256 VideoFrame::CreateBlackFrame(current_frame_size_);
255 PopulateVideoFrame(video_frame.get(), synthetic_count_); 257 PopulateVideoFrame(video_frame.get(), synthetic_count_);
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 int frames_read = avframe->nb_samples; 457 int frames_read = avframe->nb_samples;
456 if (frames_read < 0) 458 if (frames_read < 0)
457 break; 459 break;
458 460
459 if (!audio_sent_ts_) { 461 if (!audio_sent_ts_) {
460 // Initialize the base time to the first packet in the file. 462 // Initialize the base time to the first packet in the file.
461 // This is set to the frequency we send to the receiver. 463 // This is set to the frequency we send to the receiver.
462 // Not the frequency of the source file. This is because we 464 // Not the frequency of the source file. This is because we
463 // increment the frame count by samples we sent. 465 // increment the frame count by samples we sent.
464 audio_sent_ts_.reset( 466 audio_sent_ts_.reset(
465 new AudioTimestampHelper(kAudioSamplingFrequency)); 467 new AudioTimestampHelper(output_audio_params_.sample_rate()));
466 // For some files this is an invalid value. 468 // For some files this is an invalid value.
467 base::TimeDelta base_ts; 469 base::TimeDelta base_ts;
468 audio_sent_ts_->SetBaseTimestamp(base_ts); 470 audio_sent_ts_->SetBaseTimestamp(base_ts);
469 } 471 }
470 472
471 scoped_refptr<AudioBuffer> buffer = 473 scoped_refptr<AudioBuffer> buffer =
472 AudioBuffer::CopyFrom( 474 AudioBuffer::CopyFrom(
473 AVSampleFormatToSampleFormat( 475 AVSampleFormatToSampleFormat(
474 av_audio_context()->sample_fmt), 476 av_audio_context()->sample_fmt),
475 ChannelLayoutToChromeChannelLayout( 477 ChannelLayoutToChromeChannelLayout(
(...skipping 23 matching lines...) Expand all
499 // Prevent overflow of audio data in the FIFO. 501 // Prevent overflow of audio data in the FIFO.
500 if (audio_fifo_input_bus_->frames() + audio_fifo_->frames() 502 if (audio_fifo_input_bus_->frames() + audio_fifo_->frames()
501 <= audio_fifo_->max_frames()) { 503 <= audio_fifo_->max_frames()) {
502 audio_fifo_->Push(audio_fifo_input_bus_.get()); 504 audio_fifo_->Push(audio_fifo_input_bus_.get());
503 } else { 505 } else {
504 LOG(WARNING) << "Audio FIFO full; dropping samples."; 506 LOG(WARNING) << "Audio FIFO full; dropping samples.";
505 } 507 }
506 508
507 // Make sure there's enough data to resample audio. 509 // Make sure there's enough data to resample audio.
508 if (audio_fifo_->frames() < 510 if (audio_fifo_->frames() <
509 2 * audio_params_.sample_rate() / kAudioPacketsPerSecond) { 511 2 * source_audio_params_.sample_rate() / kAudioPacketsPerSecond) {
510 continue; 512 continue;
511 } 513 }
512 514
513 scoped_ptr<media::AudioBus> resampled_bus( 515 scoped_ptr<media::AudioBus> resampled_bus(
514 media::AudioBus::Create( 516 media::AudioBus::Create(
515 audio_params_.channels(), 517 output_audio_params_.channels(),
516 kAudioSamplingFrequency / kAudioPacketsPerSecond)); 518 output_audio_params_.sample_rate() / kAudioPacketsPerSecond));
517 audio_resampler_->Resample(resampled_bus->frames(), 519 audio_converter_->Convert(resampled_bus.get());
518 resampled_bus.get());
519 audio_bus_queue_.push(resampled_bus.release()); 520 audio_bus_queue_.push(resampled_bus.release());
520 } 521 }
521 } 522 }
522 523
523 void FakeMediaSource::DecodeVideo(ScopedAVPacket packet) { 524 void FakeMediaSource::DecodeVideo(ScopedAVPacket packet) {
524 // Video. 525 // Video.
525 int got_picture; 526 int got_picture;
526 AVFrame* avframe = av_frame_alloc(); 527 AVFrame* avframe = av_frame_alloc();
527 CHECK(avcodec_decode_video2( 528 CHECK(avcodec_decode_video2(
528 av_video_context(), avframe, &got_picture, packet.get()) >= 0) 529 av_video_context(), avframe, &got_picture, packet.get()) >= 0)
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 return; 582 return;
582 } 583 }
583 584
584 if (audio_packet) 585 if (audio_packet)
585 DecodeAudio(packet.Pass()); 586 DecodeAudio(packet.Pass());
586 else 587 else
587 DecodeVideo(packet.Pass()); 588 DecodeVideo(packet.Pass());
588 } 589 }
589 } 590 }
590 591
591 void FakeMediaSource::ProvideData(int frame_delay, 592 double FakeMediaSource::ProvideInput(media::AudioBus* output_bus,
592 media::AudioBus* output_bus) { 593 base::TimeDelta buffer_delay) {
593 if (audio_fifo_->frames() >= output_bus->frames()) { 594 if (audio_fifo_->frames() >= output_bus->frames()) {
594 audio_fifo_->Consume(output_bus, 0, output_bus->frames()); 595 audio_fifo_->Consume(output_bus, 0, output_bus->frames());
596 return 1.0;
595 } else { 597 } else {
596 LOG(WARNING) << "Not enough audio data for resampling."; 598 LOG(WARNING) << "Not enough audio data for resampling.";
597 output_bus->Zero(); 599 output_bus->Zero();
600 return 0.0;
598 } 601 }
599 } 602 }
600 603
601 scoped_refptr<media::VideoFrame> 604 scoped_refptr<media::VideoFrame>
602 FakeMediaSource::PopOldestInsertedVideoFrame() { 605 FakeMediaSource::PopOldestInsertedVideoFrame() {
603 CHECK(!inserted_video_frame_queue_.empty()); 606 CHECK(!inserted_video_frame_queue_.empty());
604 scoped_refptr<media::VideoFrame> video_frame = 607 scoped_refptr<media::VideoFrame> video_frame =
605 inserted_video_frame_queue_.front(); 608 inserted_video_frame_queue_.front();
606 inserted_video_frame_queue_.pop(); 609 inserted_video_frame_queue_.pop();
607 return video_frame; 610 return video_frame;
(...skipping 10 matching lines...) Expand all
618 AVCodecContext* FakeMediaSource::av_audio_context() { 621 AVCodecContext* FakeMediaSource::av_audio_context() {
619 return av_audio_stream()->codec; 622 return av_audio_stream()->codec;
620 } 623 }
621 624
622 AVCodecContext* FakeMediaSource::av_video_context() { 625 AVCodecContext* FakeMediaSource::av_video_context() {
623 return av_video_stream()->codec; 626 return av_video_stream()->codec;
624 } 627 }
625 628
626 } // namespace cast 629 } // namespace cast
627 } // namespace media 630 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/test/fake_media_source.h ('k') | media/cast/test/sender.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698