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