1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file. 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/test/fake_media_source.h" 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/files/memory_mapped_file.h" 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/files/scoped_file.h" 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/logging.h" 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/string_number_conversions.h" 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/audio/audio_parameters.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/base/audio_buffer.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/base/audio_bus.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/base/audio_fifo.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/base/audio_timestamp_helper.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/base/media.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/base/multi_channel_resampler.h" 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/base/video_frame.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/base/video_util.h" 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/cast_sender.h" 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/test/utility/audio_utility.h" 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/test/utility/video_utility.h" 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/ffmpeg/ffmpeg_common.h" 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/ffmpeg/ffmpeg_deleters.h" 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/filters/audio_renderer_algorithm.h" 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/filters/ffmpeg_demuxer.h" 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/filters/ffmpeg_glue.h" 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/filters/in_memory_url_protocol.h" 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/gfx/size.h" 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace { 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const int kAudioChannels = 2; 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const int kAudioSamplingFrequency = 48000; 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const int kSoundFrequency = 1234; // Frequency of sinusoid wave. 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const float kSoundVolume = 0.5f; 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const int kAudioFrameMs = 10; // Each audio frame is exactly 10ms. 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const int kAudioPacketsPerSecond = 1000 / kAudioFrameMs; 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AVFreeFrame(AVFrame* frame) { 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_frame_free(&frame); 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace media { 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace cast { 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 49116680a4aac90f2aa7413d9095a592090648e557Ben MurdochFakeMediaSource::FakeMediaSource( 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<base::SingleThreadTaskRunner> task_runner, 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::TickClock* clock, 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const VideoSenderConfig& video_config) 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : task_runner_(task_runner), 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_config_(video_config), 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch synthetic_count_(0), 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch clock_(clock), 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_frame_count_(0), 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_count_(0), 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_factory_(this), 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_format_context_(NULL), 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_stream_index_(-1), 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch playback_rate_(1.0), 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_stream_index_(-1), 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_rate_numerator_(video_config.max_frame_rate), 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_rate_denominator_(1), 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_first_pts_(0), 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_first_pts_set_(false) { 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_bus_factory_.reset(new TestAudioBusFactory(kAudioChannels, 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kAudioSamplingFrequency, 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kSoundFrequency, 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kSoundVolume)); 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 74116680a4aac90f2aa7413d9095a592090648e557Ben MurdochFakeMediaSource::~FakeMediaSource() { 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid FakeMediaSource::SetSourceFile(const base::FilePath& video_file, 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int override_fps) { 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!video_file.empty()); 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (override_fps) { 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_config_.max_frame_rate = override_fps; 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_rate_numerator_ = override_fps; 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(INFO) << "Source: " << video_file.value(); 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!file_data_.Initialize(video_file)) { 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(ERROR) << "Cannot load file."; 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch protocol_.reset( 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new InMemoryUrlProtocol(file_data_.data(), file_data_.length(), false)); 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch glue_.reset(new FFmpegGlue(protocol_.get())); 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!glue_->OpenContext()) { 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(ERROR) << "Cannot open file."; 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // AVFormatContext is owned by the glue. 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_format_context_ = glue_->format_context(); 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (avformat_find_stream_info(av_format_context_, NULL) < 0) { 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(ERROR) << "Cannot find stream information."; 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Prepare FFmpeg decoders. 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (unsigned int i = 0; i < av_format_context_->nb_streams; ++i) { 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AVStream* av_stream = av_format_context_->streams[i]; 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AVCodecContext* av_codec_context = av_stream->codec; 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AVCodec* av_codec = avcodec_find_decoder(av_codec_context->codec_id); 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!av_codec) { 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(ERROR) << "Cannot find decoder for the codec: " 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << av_codec_context->codec_id; 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch continue; 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Number of threads for decoding. 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_codec_context->thread_count = 2; 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_codec_context->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_codec_context->request_sample_fmt = AV_SAMPLE_FMT_S16; 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (avcodec_open2(av_codec_context, av_codec, NULL) < 0) { 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(ERROR) << "Cannot open AVCodecContext for the codec: " 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << av_codec_context->codec_id; 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (av_codec->type == AVMEDIA_TYPE_AUDIO) { 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (av_codec_context->sample_fmt == AV_SAMPLE_FMT_S16P) { 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(ERROR) << "Audio format not supported."; 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch continue; 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ChannelLayout layout = ChannelLayoutToChromeChannelLayout( 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_codec_context->channel_layout, 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_codec_context->channels); 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (layout == CHANNEL_LAYOUT_UNSUPPORTED) { 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(ERROR) << "Unsupported audio channels layout."; 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch continue; 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (audio_stream_index_ != -1) { 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(WARNING) << "Found multiple audio streams."; 144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_stream_index_ = static_cast<int>(i); 146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_params_.Reset( 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AudioParameters::AUDIO_PCM_LINEAR, 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch layout, 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_codec_context->channels, 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_codec_context->sample_rate, 151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 8 * av_get_bytes_per_sample(av_codec_context->sample_fmt), 152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_codec_context->sample_rate / kAudioPacketsPerSecond); 153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(INFO) << "Source file has audio."; 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else if (av_codec->type == AVMEDIA_TYPE_VIDEO) { 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VideoFrame::Format format = 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PixelFormatToVideoFormat(av_codec_context->pix_fmt); 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (format != VideoFrame::YV12) { 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(ERROR) << "Cannot handle non YV12 video format: " << format; 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch continue; 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (video_stream_index_ != -1) { 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(WARNING) << "Found multiple video streams."; 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_stream_index_ = static_cast<int>(i); 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!override_fps) { 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_rate_numerator_ = av_stream->r_frame_rate.num; 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_rate_denominator_ = av_stream->r_frame_rate.den; 168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Max frame rate is rounded up. 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_config_.max_frame_rate = 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_rate_denominator_ + 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_rate_numerator_ - 1; 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_config_.max_frame_rate /= video_frame_rate_denominator_; 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If video is played at a manual speed audio needs to match. 175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch playback_rate_ = 1.0 * override_fps * 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_stream->r_frame_rate.den / av_stream->r_frame_rate.num; 177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(INFO) << "Source file has video."; 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(ERROR) << "Unknown stream type; ignore."; 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Rewind(); 185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid FakeMediaSource::Start(scoped_refptr<AudioFrameInput> audio_frame_input, 188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<VideoFrameInput> video_frame_input) { 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_frame_input_ = audio_frame_input; 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_input_ = video_frame_input; 191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(INFO) << "Max Frame rate: " << video_config_.max_frame_rate; 193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(INFO) << "Real Frame rate: " 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << video_frame_rate_numerator_ << "/" 195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << video_frame_rate_denominator_ << " fps."; 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(INFO) << "Audio playback rate: " << playback_rate_; 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!is_transcoding_audio() && !is_transcoding_video()) { 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Send fake patterns. 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch task_runner_->PostTask( 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind( 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &FakeMediaSource::SendNextFakeFrame, 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this))); 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Send transcoding streams. 2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) audio_algo_.Initialize(audio_params_); 210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_algo_.FlushBuffers(); 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_fifo_input_bus_ = 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AudioBus::Create( 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_params_.channels(), audio_params_.frames_per_buffer()); 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Audio FIFO can carry all data fron AudioRendererAlgorithm. 215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_fifo_.reset( 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new AudioFifo(audio_params_.channels(), 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_algo_.QueueCapacity())); 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_resampler_.reset(new media::MultiChannelResampler( 219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_params_.channels(), 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static_cast<double>(audio_params_.sample_rate()) / 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kAudioSamplingFrequency, 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_params_.frames_per_buffer(), 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&FakeMediaSource::ProvideData, base::Unretained(this)))); 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch task_runner_->PostTask( 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind( 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &FakeMediaSource::SendNextFrame, 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this))); 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 231116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid FakeMediaSource::SendNextFakeFrame() { 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gfx::Size size(video_config_.width, video_config_.height); 233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<VideoFrame> video_frame = 234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VideoFrame::CreateBlackFrame(size); 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PopulateVideoFrame(video_frame.get(), synthetic_count_); 236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++synthetic_count_; 237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::TimeTicks now = clock_->NowTicks(); 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (start_time_.is_null()) 240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch start_time_ = now; 241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::TimeDelta video_time = VideoFrameTime(++video_frame_count_); 243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame->set_timestamp(video_time); 244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_input_->InsertRawVideoFrame(video_frame, 245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch start_time_ + video_time); 246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Send just enough audio data to match next video frame's time. 248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::TimeDelta audio_time = AudioFrameTime(audio_frame_count_); 249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while (audio_time < video_time) { 250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (is_transcoding_audio()) { 251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Decode(true); 252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK(!audio_bus_queue_.empty()) << "No audio decoded."; 253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<AudioBus> bus(audio_bus_queue_.front()); 254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_bus_queue_.pop(); 255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_frame_input_->InsertAudio( 256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bus.Pass(), start_time_ + audio_time); 257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_frame_input_->InsertAudio( 259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_bus_factory_->NextAudioBus( 260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::TimeDelta::FromMilliseconds(kAudioFrameMs)), 261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch start_time_ + audio_time); 262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_time = AudioFrameTime(++audio_frame_count_); 264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // This is the time since the stream started. 267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::TimeDelta elapsed_time = now - start_time_; 268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Handle the case when frame generation cannot keep up. 270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Move the time ahead to match the next frame. 271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while (video_time < elapsed_time) { 272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(WARNING) << "Skipping one frame."; 273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_time = VideoFrameTime(++video_frame_count_); 274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch task_runner_->PostDelayedTask( 277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&FakeMediaSource::SendNextFakeFrame, 279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_factory_.GetWeakPtr()), 280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_time - elapsed_time); 281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 283116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool FakeMediaSource::SendNextTranscodedVideo(base::TimeDelta elapsed_time) { 284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!is_transcoding_video()) 285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Decode(false); 288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (video_frame_queue_.empty()) 289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<VideoFrame> decoded_frame = 292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_queue_.front(); 293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (elapsed_time < decoded_frame->timestamp()) 294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gfx::Size size(video_config_.width, video_config_.height); 297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<VideoFrame> video_frame = 298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VideoFrame::CreateBlackFrame(size); 299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_queue_.pop(); 300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch media::CopyPlane(VideoFrame::kYPlane, 301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch decoded_frame->data(VideoFrame::kYPlane), 302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch decoded_frame->stride(VideoFrame::kYPlane), 303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch decoded_frame->rows(VideoFrame::kYPlane), 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_frame.get()); 305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch media::CopyPlane(VideoFrame::kUPlane, 306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch decoded_frame->data(VideoFrame::kUPlane), 307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch decoded_frame->stride(VideoFrame::kUPlane), 308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch decoded_frame->rows(VideoFrame::kUPlane), 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_frame.get()); 310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch media::CopyPlane(VideoFrame::kVPlane, 311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch decoded_frame->data(VideoFrame::kVPlane), 312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch decoded_frame->stride(VideoFrame::kVPlane), 313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch decoded_frame->rows(VideoFrame::kVPlane), 3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_frame.get()); 315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 316116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::TimeDelta video_time; 317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Use the timestamp from the file if we're transcoding. 318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_time = ScaleTimestamp(decoded_frame->timestamp()); 319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_input_->InsertRawVideoFrame( 320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame, start_time_ + video_time); 321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Make sure queue is not empty. 323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Decode(false); 324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 327116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool FakeMediaSource::SendNextTranscodedAudio(base::TimeDelta elapsed_time) { 328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!is_transcoding_audio()) 329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Decode(true); 332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (audio_bus_queue_.empty()) 333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::TimeDelta audio_time = audio_sent_ts_->GetTimestamp(); 336116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (elapsed_time < audio_time) 337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<AudioBus> bus(audio_bus_queue_.front()); 339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_bus_queue_.pop(); 340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_sent_ts_->AddFrames(bus->frames()); 341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_frame_input_->InsertAudio( 342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bus.Pass(), start_time_ + audio_time); 343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Make sure queue is not empty. 345116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Decode(true); 346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 349116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid FakeMediaSource::SendNextFrame() { 350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (start_time_.is_null()) 351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch start_time_ = clock_->NowTicks(); 352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (start_time_.is_null()) 353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch start_time_ = clock_->NowTicks(); 354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Send as much as possible. Audio is sent according to 356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // system time. 357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while (SendNextTranscodedAudio(clock_->NowTicks() - start_time_)); 358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Video is sync'ed to audio. 360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while (SendNextTranscodedVideo(audio_sent_ts_->GetTimestamp())); 361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (audio_bus_queue_.empty() && video_frame_queue_.empty()) { 363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Both queues are empty can only mean that we have reached 364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the end of the stream. 365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(INFO) << "Rewind."; 366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Rewind(); 367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch start_time_ = base::TimeTicks(); 368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_sent_ts_.reset(); 369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_first_pts_set_ = false; 370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Send next send. 373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch task_runner_->PostDelayedTask( 374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind( 376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &FakeMediaSource::SendNextFrame, 377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this)), 378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::TimeDelta::FromMilliseconds(kAudioFrameMs)); 379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 381116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::TimeDelta FakeMediaSource::VideoFrameTime(int frame_number) { 382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return frame_number * base::TimeDelta::FromSeconds(1) * 383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_rate_denominator_ / video_frame_rate_numerator_; 384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 386116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::TimeDelta FakeMediaSource::ScaleTimestamp(base::TimeDelta timestamp) { 387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return base::TimeDelta::FromMicroseconds( 388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch timestamp.InMicroseconds() / playback_rate_); 389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 391116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::TimeDelta FakeMediaSource::AudioFrameTime(int frame_number) { 392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return frame_number * base::TimeDelta::FromMilliseconds(kAudioFrameMs); 393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 395116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid FakeMediaSource::Rewind() { 396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK(av_seek_frame(av_format_context_, -1, 0, AVSEEK_FLAG_BACKWARD) >= 0) 397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << "Failed to rewind to the beginning."; 398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 400116680a4aac90f2aa7413d9095a592090648e557Ben MurdochScopedAVPacket FakeMediaSource::DemuxOnePacket(bool* audio) { 401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScopedAVPacket packet(new AVPacket()); 402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (av_read_frame(av_format_context_, packet.get()) < 0) { 403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(ERROR) << "Failed to read one AVPacket."; 404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packet.reset(); 405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return packet.Pass(); 406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int stream_index = static_cast<int>(packet->stream_index); 409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (stream_index == audio_stream_index_) { 410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *audio = true; 411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else if (stream_index == video_stream_index_) { 412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *audio = false; 413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Ignore unknown packet. 415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(INFO) << "Unknown packet."; 416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packet.reset(); 417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return packet.Pass(); 419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 421116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid FakeMediaSource::DecodeAudio(ScopedAVPacket packet) { 422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Audio. 423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AVFrame* avframe = av_frame_alloc(); 424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Make a shallow copy of packet so we can slide packet.data as frames are 426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // decoded from the packet; otherwise av_free_packet() will corrupt memory. 427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AVPacket packet_temp = *packet.get(); 428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch do { 430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int frame_decoded = 0; 431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int result = avcodec_decode_audio4( 432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_audio_context(), avframe, &frame_decoded, &packet_temp); 433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK(result >= 0) << "Failed to decode audio."; 434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packet_temp.size -= result; 435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch packet_temp.data += result; 436116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!frame_decoded) 437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch continue; 438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int frames_read = avframe->nb_samples; 440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (frames_read < 0) 441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!audio_sent_ts_) { 444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Initialize the base time to the first packet in the file. 445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // This is set to the frequency we send to the receiver. 446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Not the frequency of the source file. This is because we 447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // increment the frame count by samples we sent. 448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_sent_ts_.reset( 449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new AudioTimestampHelper(kAudioSamplingFrequency)); 450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // For some files this is an invalid value. 451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::TimeDelta base_ts; 452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_sent_ts_->SetBaseTimestamp(base_ts); 453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<AudioBuffer> buffer = 456116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AudioBuffer::CopyFrom( 457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AVSampleFormatToSampleFormat( 458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_audio_context()->sample_fmt), 459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ChannelLayoutToChromeChannelLayout( 460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_audio_context()->channel_layout, 461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_audio_context()->channels), 462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_audio_context()->channels, 463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_audio_context()->sample_rate, 464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch frames_read, 465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &avframe->data[0], 466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Note: Not all files have correct values for pkt_pts. 467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::TimeDelta::FromMilliseconds(avframe->pkt_pts)); 468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_algo_.EnqueueBuffer(buffer); 469116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_frame_unref(avframe); 470116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } while (packet_temp.size > 0); 471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_frame_free(&avframe); 472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const int frames_needed_to_scale = 474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch playback_rate_ * av_audio_context()->sample_rate / 475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kAudioPacketsPerSecond; 476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while (frames_needed_to_scale <= audio_algo_.frames_buffered()) { 477116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!audio_algo_.FillBuffer(audio_fifo_input_bus_.get(), 4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) audio_fifo_input_bus_->frames(), 4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) playback_rate_)) { 480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Nothing can be scaled. Decode some more. 481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 483116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 484116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Prevent overflow of audio data in the FIFO. 485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (audio_fifo_input_bus_->frames() + audio_fifo_->frames() 486116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch <= audio_fifo_->max_frames()) { 487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_fifo_->Push(audio_fifo_input_bus_.get()); 488116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 489116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(WARNING) << "Audio FIFO full; dropping samples."; 490116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 491116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 492116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Make sure there's enough data to resample audio. 493116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (audio_fifo_->frames() < 494116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2 * audio_params_.sample_rate() / kAudioPacketsPerSecond) { 495116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch continue; 496116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 497116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 498116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<media::AudioBus> resampled_bus( 499116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch media::AudioBus::Create( 500116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_params_.channels(), 501116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kAudioSamplingFrequency / kAudioPacketsPerSecond)); 502116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_resampler_->Resample(resampled_bus->frames(), 503116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch resampled_bus.get()); 504116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_bus_queue_.push(resampled_bus.release()); 505116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 506116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 507116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 508116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid FakeMediaSource::DecodeVideo(ScopedAVPacket packet) { 509116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Video. 510116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int got_picture; 511116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AVFrame* avframe = av_frame_alloc(); 512116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Tell the decoder to reorder for us. 513116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch avframe->reordered_opaque = 514116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_video_context()->reordered_opaque = packet->pts; 515116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK(avcodec_decode_video2( 516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_video_context(), avframe, &got_picture, packet.get()) >= 0) 517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << "Video decode error."; 518116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!got_picture) { 519116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch av_frame_free(&avframe); 520116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gfx::Size size(av_video_context()->width, av_video_context()->height); 523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!video_first_pts_set_ || 524116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch avframe->reordered_opaque < video_first_pts_) { 525116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_first_pts_set_ = true; 526116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_first_pts_ = avframe->reordered_opaque; 527116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 528116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int64 pts = avframe->reordered_opaque - video_first_pts_; 529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch video_frame_queue_.push( 530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VideoFrame::WrapExternalYuvData( 531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch media::VideoFrame::YV12, 532116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size, 533116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gfx::Rect(size), 534116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size, 535116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch avframe->linesize[0], 536116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch avframe->linesize[1], 537116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch avframe->linesize[2], 538116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch avframe->data[0], 539116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch avframe->data[1], 540116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch avframe->data[2], 541116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::TimeDelta::FromMilliseconds(pts), 542116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&AVFreeFrame, avframe))); 543116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 544116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 545116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid FakeMediaSource::Decode(bool decode_audio) { 546116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Read the stream until one video frame can be decoded. 547116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while (true) { 548116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (decode_audio && !audio_bus_queue_.empty()) 549116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 550116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!decode_audio && !video_frame_queue_.empty()) 551116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 552116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 553116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool audio_packet = false; 554116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScopedAVPacket packet = DemuxOnePacket(&audio_packet); 555116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!packet) { 556116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(INFO) << "End of stream."; 557116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 558116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 559116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 560116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (audio_packet) 561116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DecodeAudio(packet.Pass()); 562116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else 563116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DecodeVideo(packet.Pass()); 564116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 565116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 566116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 567116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid FakeMediaSource::ProvideData(int frame_delay, 568116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch media::AudioBus* output_bus) { 569116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (audio_fifo_->frames() >= output_bus->frames()) { 570116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch audio_fifo_->Consume(output_bus, 0, output_bus->frames()); 571116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 572116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(WARNING) << "Not enough audio data for resampling."; 573116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch output_bus->Zero(); 574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 575116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 576116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 577116680a4aac90f2aa7413d9095a592090648e557Ben MurdochAVStream* FakeMediaSource::av_audio_stream() { 578116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return av_format_context_->streams[audio_stream_index_]; 579116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 580116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 581116680a4aac90f2aa7413d9095a592090648e557Ben MurdochAVStream* FakeMediaSource::av_video_stream() { 582116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return av_format_context_->streams[video_stream_index_]; 583116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 584116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 585116680a4aac90f2aa7413d9095a592090648e557Ben MurdochAVCodecContext* FakeMediaSource::av_audio_context() { 586116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return av_audio_stream()->codec; 587116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 588116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 589116680a4aac90f2aa7413d9095a592090648e557Ben MurdochAVCodecContext* FakeMediaSource::av_video_context() { 590116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return av_video_stream()->codec; 591116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 592116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 593116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace cast 594116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace media 595