1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "media/cast/test/fake_media_source.h"
6 
7 #include <utility>
8 
9 #include "base/bind.h"
10 #include "base/files/scoped_file.h"
11 #include "base/logging.h"
12 #include "base/rand_util.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "media/base/audio_buffer.h"
15 #include "media/base/audio_bus.h"
16 #include "media/base/audio_fifo.h"
17 #include "media/base/audio_timestamp_helper.h"
18 #include "media/base/media.h"
19 #include "media/base/video_frame.h"
20 #include "media/base/video_util.h"
21 #include "media/cast/cast_sender.h"
22 #include "media/cast/test/utility/audio_utility.h"
23 #include "media/cast/test/utility/video_utility.h"
24 #include "ui/gfx/geometry/size.h"
25 
26 // TODO(miu): Figure out why _mkdir() and _rmdir() are missing when compiling
27 // third_party/ffmpeg/libavformat/os_support.h (lines 182, 183).
28 // http://crbug.com/572986
29 #if defined(OS_WIN)
30 #include <direct.h>
31 #endif  // defined(OS_WIN)
32 #include "media/ffmpeg/ffmpeg_common.h"
33 #include "media/ffmpeg/ffmpeg_decoding_loop.h"
34 #include "media/ffmpeg/ffmpeg_deleters.h"
35 #include "media/filters/ffmpeg_glue.h"
36 #include "media/filters/in_memory_url_protocol.h"
37 
38 namespace {
39 
40 static const int kSoundFrequency = 440;  // Frequency of sinusoid wave.
41 static const float kSoundVolume = 0.10f;
42 static const int kAudioFrameMs = 10;  // Each audio frame is exactly 10ms.
43 static const int kAudioPacketsPerSecond = 1000 / kAudioFrameMs;
44 
45 // Bounds for variable frame size mode.
46 static const int kMinFakeFrameWidth = 60;
47 static const int kMinFakeFrameHeight = 34;
48 static const int kStartingFakeFrameWidth = 854;
49 static const int kStartingFakeFrameHeight = 480;
50 static const int kMaxFakeFrameWidth = 1280;
51 static const int kMaxFakeFrameHeight = 720;
52 static const int kMaxFrameSizeChangeMillis = 5000;
53 
AVFreeFrame(AVFrame * frame)54 void AVFreeFrame(AVFrame* frame) {
55   av_frame_free(&frame);
56 }
57 
PtsToTimeDelta(int64_t pts,const AVRational & time_base)58 base::TimeDelta PtsToTimeDelta(int64_t pts, const AVRational& time_base) {
59   return pts * base::TimeDelta::FromSeconds(1) * time_base.num / time_base.den;
60 }
61 
TimeDeltaToPts(base::TimeDelta delta,const AVRational & time_base)62 int64_t TimeDeltaToPts(base::TimeDelta delta, const AVRational& time_base) {
63   return static_cast<int64_t>(
64       delta.InSecondsF() * time_base.den / time_base.num + 0.5 /* rounding */);
65 }
66 
67 }  // namespace
68 
69 namespace media {
70 namespace cast {
71 
FakeMediaSource(scoped_refptr<base::SingleThreadTaskRunner> task_runner,const base::TickClock * clock,const FrameSenderConfig & audio_config,const FrameSenderConfig & video_config,bool keep_frames)72 FakeMediaSource::FakeMediaSource(
73     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
74     const base::TickClock* clock,
75     const FrameSenderConfig& audio_config,
76     const FrameSenderConfig& video_config,
77     bool keep_frames)
78     : task_runner_(task_runner),
79       output_audio_params_(AudioParameters::AUDIO_PCM_LINEAR,
80                            media::GuessChannelLayout(audio_config.channels),
81                            audio_config.rtp_timebase,
82                            audio_config.rtp_timebase / kAudioPacketsPerSecond),
83       video_config_(video_config),
84       keep_frames_(keep_frames),
85       variable_frame_size_mode_(false),
86       synthetic_count_(0),
87       clock_(clock),
88       audio_frame_count_(0),
89       video_frame_count_(0),
90       av_format_context_(nullptr),
91       audio_stream_index_(-1),
92       playback_rate_(1.0),
93       video_stream_index_(-1),
94       video_frame_rate_numerator_(video_config.max_frame_rate),
95       video_frame_rate_denominator_(1),
96       audio_algo_(&media_log_),
97       video_first_pts_(0),
98       video_first_pts_set_(false) {
99   CHECK(output_audio_params_.IsValid());
100   audio_bus_factory_.reset(
101       new TestAudioBusFactory(audio_config.channels, audio_config.rtp_timebase,
102                               kSoundFrequency, kSoundVolume));
103 }
104 
105 FakeMediaSource::~FakeMediaSource() = default;
106 
SetSourceFile(const base::FilePath & video_file,int final_fps)107 void FakeMediaSource::SetSourceFile(const base::FilePath& video_file,
108                                     int final_fps) {
109   DCHECK(!video_file.empty());
110 
111   LOG(INFO) << "Source: " << video_file.value();
112   if (!file_data_.Initialize(video_file)) {
113     LOG(ERROR) << "Cannot load file.";
114     return;
115   }
116   protocol_.reset(
117       new InMemoryUrlProtocol(file_data_.data(), file_data_.length(), false));
118   glue_.reset(new FFmpegGlue(protocol_.get()));
119 
120   if (!glue_->OpenContext()) {
121     LOG(ERROR) << "Cannot open file.";
122     return;
123   }
124 
125   // AVFormatContext is owned by the glue.
126   av_format_context_ = glue_->format_context();
127   if (avformat_find_stream_info(av_format_context_, NULL) < 0) {
128     LOG(ERROR) << "Cannot find stream information.";
129     return;
130   }
131 
132   // Prepare FFmpeg decoders.
133   for (unsigned int i = 0; i < av_format_context_->nb_streams; ++i) {
134     AVStream* av_stream = av_format_context_->streams[i];
135     std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> av_codec_context(
136         AVStreamToAVCodecContext(av_stream));
137     if (!av_codec_context) {
138       LOG(ERROR) << "Cannot get a codec context for the codec: "
139                  << av_stream->codecpar->codec_id;
140       continue;
141     }
142 
143     AVCodec* av_codec = avcodec_find_decoder(av_codec_context->codec_id);
144 
145     if (!av_codec) {
146       LOG(ERROR) << "Cannot find decoder for the codec: "
147                  << av_codec_context->codec_id;
148       continue;
149     }
150 
151     // Number of threads for decoding.
152     av_codec_context->thread_count = 2;
153     av_codec_context->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
154     av_codec_context->request_sample_fmt = AV_SAMPLE_FMT_S16;
155 
156     if (avcodec_open2(av_codec_context.get(), av_codec, nullptr) < 0) {
157       LOG(ERROR) << "Cannot open AVCodecContext for the codec: "
158                  << av_codec_context->codec_id;
159       return;
160     }
161 
162     if (av_codec->type == AVMEDIA_TYPE_AUDIO) {
163       if (av_codec_context->sample_fmt == AV_SAMPLE_FMT_S16P) {
164         LOG(ERROR) << "Audio format not supported.";
165         continue;
166       }
167       ChannelLayout layout = ChannelLayoutToChromeChannelLayout(
168           av_codec_context->channel_layout,
169           av_codec_context->channels);
170       if (layout == CHANNEL_LAYOUT_UNSUPPORTED) {
171         LOG(ERROR) << "Unsupported audio channels layout.";
172         continue;
173       }
174       if (audio_stream_index_ != -1) {
175         LOG(WARNING) << "Found multiple audio streams.";
176       }
177       audio_stream_index_ = static_cast<int>(i);
178       av_audio_context_ = std::move(av_codec_context);
179       source_audio_params_.Reset(
180           AudioParameters::AUDIO_PCM_LINEAR, layout,
181           av_audio_context_->sample_rate,
182           av_audio_context_->sample_rate / kAudioPacketsPerSecond);
183       source_audio_params_.set_channels_for_discrete(
184           av_audio_context_->channels);
185       CHECK(source_audio_params_.IsValid());
186       LOG(INFO) << "Source file has audio.";
187       audio_decoding_loop_.reset(
188           new FFmpegDecodingLoop(av_audio_context_.get()));
189     } else if (av_codec->type == AVMEDIA_TYPE_VIDEO) {
190       VideoPixelFormat format =
191           AVPixelFormatToVideoPixelFormat(av_codec_context->pix_fmt);
192       if (format != PIXEL_FORMAT_I420) {
193         LOG(ERROR) << "Cannot handle non YV12 video format: " << format;
194         continue;
195       }
196       if (video_stream_index_ != -1) {
197         LOG(WARNING) << "Found multiple video streams.";
198       }
199       video_stream_index_ = static_cast<int>(i);
200       av_video_context_ = std::move(av_codec_context);
201       video_decoding_loop_.reset(
202           new FFmpegDecodingLoop(av_video_context_.get()));
203       if (final_fps > 0) {
204         // If video is played at a manual speed audio needs to match.
205         playback_rate_ = 1.0 * final_fps *
206             av_stream->r_frame_rate.den / av_stream->r_frame_rate.num;
207         video_frame_rate_numerator_ = final_fps;
208         video_frame_rate_denominator_ = 1;
209       } else {
210         playback_rate_ = 1.0;
211         video_frame_rate_numerator_ = av_stream->r_frame_rate.num;
212         video_frame_rate_denominator_ = av_stream->r_frame_rate.den;
213       }
214       LOG(INFO) << "Source file has video.";
215     } else {
216       LOG(ERROR) << "Unknown stream type; ignore.";
217     }
218   }
219 
220   Rewind();
221 }
222 
SetVariableFrameSizeMode(bool enabled)223 void FakeMediaSource::SetVariableFrameSizeMode(bool enabled) {
224   variable_frame_size_mode_ = enabled;
225 }
226 
Start(scoped_refptr<AudioFrameInput> audio_frame_input,scoped_refptr<VideoFrameInput> video_frame_input)227 void FakeMediaSource::Start(scoped_refptr<AudioFrameInput> audio_frame_input,
228                             scoped_refptr<VideoFrameInput> video_frame_input) {
229   audio_frame_input_ = audio_frame_input;
230   video_frame_input_ = video_frame_input;
231 
232   LOG(INFO) << "Max Frame rate: " << video_config_.max_frame_rate;
233   LOG(INFO) << "Source Frame rate: "
234             << video_frame_rate_numerator_ << "/"
235             << video_frame_rate_denominator_ << " fps.";
236   LOG(INFO) << "Audio playback rate: " << playback_rate_;
237 
238   if (start_time_.is_null())
239     start_time_ = clock_->NowTicks();
240 
241   if (!is_transcoding_audio() && !is_transcoding_video()) {
242     // Send fake patterns.
243     task_runner_->PostTask(FROM_HERE,
244                            base::BindOnce(&FakeMediaSource::SendNextFakeFrame,
245                                           weak_factory_.GetWeakPtr()));
246     return;
247   }
248 
249   // Send transcoding streams.
250   bool is_encrypted = false;
251   audio_algo_.Initialize(source_audio_params_, is_encrypted);
252   audio_algo_.FlushBuffers();
253   audio_fifo_input_bus_ = AudioBus::Create(
254       source_audio_params_.channels(),
255       source_audio_params_.frames_per_buffer());
256   // Audio FIFO can carry all data fron AudioRendererAlgorithm.
257   audio_fifo_.reset(
258       new AudioFifo(source_audio_params_.channels(),
259                     audio_algo_.QueueCapacity()));
260   audio_converter_.reset(new media::AudioConverter(
261       source_audio_params_, output_audio_params_, true));
262   audio_converter_->AddInput(this);
263   task_runner_->PostTask(FROM_HERE,
264                          base::BindOnce(&FakeMediaSource::SendNextFrame,
265                                         weak_factory_.GetWeakPtr()));
266 }
267 
SendNextFakeFrame()268 void FakeMediaSource::SendNextFakeFrame() {
269   UpdateNextFrameSize();
270   scoped_refptr<VideoFrame> video_frame =
271       VideoFrame::CreateBlackFrame(current_frame_size_);
272   PopulateVideoFrame(video_frame.get(), synthetic_count_);
273   ++synthetic_count_;
274 
275   const base::TimeTicks now = clock_->NowTicks();
276 
277   base::TimeDelta video_time = VideoFrameTime(++video_frame_count_);
278   video_frame->set_timestamp(video_time);
279   if (keep_frames_)
280     inserted_video_frame_queue_.push(video_frame);
281   video_frame_input_->InsertRawVideoFrame(video_frame,
282                                           start_time_ + video_time);
283 
284   // Send just enough audio data to match next video frame's time.
285   base::TimeDelta audio_time = AudioFrameTime(audio_frame_count_);
286   while (audio_time < video_time) {
287     if (is_transcoding_audio()) {
288       Decode(true);
289       CHECK(!audio_bus_queue_.empty()) << "No audio decoded.";
290       std::unique_ptr<AudioBus> bus(audio_bus_queue_.front());
291       audio_bus_queue_.pop();
292       audio_frame_input_->InsertAudio(std::move(bus), start_time_ + audio_time);
293     } else {
294       audio_frame_input_->InsertAudio(
295           audio_bus_factory_->NextAudioBus(
296               base::TimeDelta::FromMilliseconds(kAudioFrameMs)),
297           start_time_ + audio_time);
298     }
299     audio_time = AudioFrameTime(++audio_frame_count_);
300   }
301 
302   // This is the time since FakeMediaSource was started.
303   const base::TimeDelta elapsed_time = now - start_time_;
304 
305   // Handle the case when frame generation cannot keep up.
306   // Move the time ahead to match the next frame.
307   while (video_time < elapsed_time) {
308     LOG(WARNING) << "Skipping one frame.";
309     video_time = VideoFrameTime(++video_frame_count_);
310   }
311 
312   task_runner_->PostDelayedTask(
313       FROM_HERE,
314       base::BindOnce(&FakeMediaSource::SendNextFakeFrame,
315                      weak_factory_.GetWeakPtr()),
316       video_time - elapsed_time);
317 }
318 
UpdateNextFrameSize()319 void FakeMediaSource::UpdateNextFrameSize() {
320   if (variable_frame_size_mode_) {
321     bool update_size_change_time = false;
322     if (current_frame_size_.IsEmpty()) {
323       current_frame_size_ = gfx::Size(kStartingFakeFrameWidth,
324                                       kStartingFakeFrameHeight);
325       update_size_change_time = true;
326     } else if (clock_->NowTicks() >= next_frame_size_change_time_) {
327       current_frame_size_ = gfx::Size(
328           base::RandInt(kMinFakeFrameWidth, kMaxFakeFrameWidth),
329           base::RandInt(kMinFakeFrameHeight, kMaxFakeFrameHeight));
330       update_size_change_time = true;
331     }
332 
333     if (update_size_change_time) {
334       next_frame_size_change_time_ = clock_->NowTicks() +
335           base::TimeDelta::FromMillisecondsD(
336               base::RandDouble() * kMaxFrameSizeChangeMillis);
337     }
338   } else {
339     current_frame_size_ = gfx::Size(kStartingFakeFrameWidth,
340                                     kStartingFakeFrameHeight);
341     next_frame_size_change_time_ = base::TimeTicks();
342   }
343 }
344 
SendNextTranscodedVideo(base::TimeDelta elapsed_time)345 bool FakeMediaSource::SendNextTranscodedVideo(base::TimeDelta elapsed_time) {
346   if (!is_transcoding_video())
347     return false;
348 
349   Decode(false);
350   if (video_frame_queue_.empty())
351     return false;
352 
353   const scoped_refptr<VideoFrame> video_frame = video_frame_queue_.front();
354   if (elapsed_time < video_frame->timestamp())
355     return false;
356   video_frame_queue_.pop();
357 
358   // Use the timestamp from the file if we're transcoding.
359   video_frame->set_timestamp(ScaleTimestamp(video_frame->timestamp()));
360   if (keep_frames_)
361     inserted_video_frame_queue_.push(video_frame);
362   video_frame_input_->InsertRawVideoFrame(
363       video_frame, start_time_ + video_frame->timestamp());
364 
365   // Make sure queue is not empty.
366   Decode(false);
367   return true;
368 }
369 
SendNextTranscodedAudio(base::TimeDelta elapsed_time)370 bool FakeMediaSource::SendNextTranscodedAudio(base::TimeDelta elapsed_time) {
371   if (!is_transcoding_audio())
372     return false;
373 
374   Decode(true);
375   if (audio_bus_queue_.empty())
376     return false;
377 
378   base::TimeDelta audio_time = audio_sent_ts_->GetTimestamp();
379   if (elapsed_time < audio_time)
380     return false;
381   std::unique_ptr<AudioBus> bus(audio_bus_queue_.front());
382   audio_bus_queue_.pop();
383   audio_sent_ts_->AddFrames(bus->frames());
384   audio_frame_input_->InsertAudio(std::move(bus), start_time_ + audio_time);
385 
386   // Make sure queue is not empty.
387   Decode(true);
388   return true;
389 }
390 
SendNextFrame()391 void FakeMediaSource::SendNextFrame() {
392   // Send as much as possible. Audio is sent according to
393   // system time.
394   while (SendNextTranscodedAudio(clock_->NowTicks() - start_time_)) {
395   }
396 
397   // Video is sync'ed to audio.
398   while (SendNextTranscodedVideo(audio_sent_ts_->GetTimestamp())) {
399   }
400 
401   if (audio_bus_queue_.empty() && video_frame_queue_.empty()) {
402     // Both queues are empty can only mean that we have reached
403     // the end of the stream.
404     LOG(INFO) << "Rewind.";
405     Rewind();
406   }
407 
408   // Send next send.
409   task_runner_->PostDelayedTask(
410       FROM_HERE,
411       base::BindOnce(&FakeMediaSource::SendNextFrame,
412                      weak_factory_.GetWeakPtr()),
413       base::TimeDelta::FromMilliseconds(kAudioFrameMs));
414 }
415 
VideoFrameTime(int frame_number)416 base::TimeDelta FakeMediaSource::VideoFrameTime(int frame_number) {
417   return frame_number * base::TimeDelta::FromSeconds(1) *
418       video_frame_rate_denominator_ / video_frame_rate_numerator_;
419 }
420 
ScaleTimestamp(base::TimeDelta timestamp)421 base::TimeDelta FakeMediaSource::ScaleTimestamp(base::TimeDelta timestamp) {
422   return timestamp / playback_rate_;
423 }
424 
AudioFrameTime(int frame_number)425 base::TimeDelta FakeMediaSource::AudioFrameTime(int frame_number) {
426   return frame_number * base::TimeDelta::FromMilliseconds(kAudioFrameMs);
427 }
428 
Rewind()429 void FakeMediaSource::Rewind() {
430   CHECK(av_seek_frame(av_format_context_, -1, 0, AVSEEK_FLAG_BACKWARD) >= 0)
431       << "Failed to rewind to the beginning.";
432 }
433 
DemuxOnePacket(bool * audio)434 ScopedAVPacket FakeMediaSource::DemuxOnePacket(bool* audio) {
435   ScopedAVPacket packet(new AVPacket());
436   if (av_read_frame(av_format_context_, packet.get()) < 0) {
437     VLOG(1) << "Failed to read one AVPacket.";
438     packet.reset();
439     return packet;
440   }
441 
442   int stream_index = static_cast<int>(packet->stream_index);
443   if (stream_index == audio_stream_index_) {
444     *audio = true;
445   } else if (stream_index == video_stream_index_) {
446     *audio = false;
447   } else {
448     // Ignore unknown packet.
449     LOG(INFO) << "Unknown packet.";
450     packet.reset();
451   }
452   return packet;
453 }
454 
DecodeAudio(ScopedAVPacket packet)455 void FakeMediaSource::DecodeAudio(ScopedAVPacket packet) {
456   auto result = audio_decoding_loop_->DecodePacket(
457       packet.get(), base::BindRepeating(&FakeMediaSource::OnNewAudioFrame,
458                                         base::Unretained(this)));
459   CHECK_EQ(result, FFmpegDecodingLoop::DecodeStatus::kOkay)
460       << "Failed to decode audio.";
461 
462   const int frames_needed_to_scale =
463       playback_rate_ * av_audio_context_->sample_rate / kAudioPacketsPerSecond;
464   while (frames_needed_to_scale <= audio_algo_.BufferedFrames()) {
465     if (!audio_algo_.FillBuffer(audio_fifo_input_bus_.get(), 0,
466                                 audio_fifo_input_bus_->frames(),
467                                 playback_rate_)) {
468       // Nothing can be scaled. Decode some more.
469       return;
470     }
471 
472     // Prevent overflow of audio data in the FIFO.
473     if (audio_fifo_input_bus_->frames() + audio_fifo_->frames() <=
474         audio_fifo_->max_frames()) {
475       audio_fifo_->Push(audio_fifo_input_bus_.get());
476     } else {
477       LOG(WARNING) << "Audio FIFO full; dropping samples.";
478     }
479 
480     // Make sure there's enough data to resample audio.
481     if (audio_fifo_->frames() <
482         2 * source_audio_params_.sample_rate() / kAudioPacketsPerSecond) {
483       continue;
484     }
485 
486     std::unique_ptr<media::AudioBus> resampled_bus(media::AudioBus::Create(
487         output_audio_params_.channels(),
488         output_audio_params_.sample_rate() / kAudioPacketsPerSecond));
489     audio_converter_->Convert(resampled_bus.get());
490     audio_bus_queue_.push(resampled_bus.release());
491   }
492 }
493 
OnNewAudioFrame(AVFrame * frame)494 bool FakeMediaSource::OnNewAudioFrame(AVFrame* frame) {
495   int frames_read = frame->nb_samples;
496   if (frames_read < 0)
497     return false;
498 
499   if (!audio_sent_ts_) {
500     // Initialize the base time to the first packet in the file. This is set to
501     // the frequency we send to the receiver. Not the frequency of the source
502     // file. This is because we increment the frame count by samples we sent.
503     audio_sent_ts_.reset(
504         new AudioTimestampHelper(output_audio_params_.sample_rate()));
505     // For some files this is an invalid value.
506     base::TimeDelta base_ts;
507     audio_sent_ts_->SetBaseTimestamp(base_ts);
508   }
509 
510   scoped_refptr<AudioBuffer> buffer = AudioBuffer::CopyFrom(
511       AVSampleFormatToSampleFormat(av_audio_context_->sample_fmt,
512                                    av_audio_context_->codec_id),
513       ChannelLayoutToChromeChannelLayout(av_audio_context_->channel_layout,
514                                          av_audio_context_->channels),
515       av_audio_context_->channels, av_audio_context_->sample_rate, frames_read,
516       &frame->data[0],
517       PtsToTimeDelta(frame->pts, av_audio_stream()->time_base));
518   audio_algo_.EnqueueBuffer(buffer);
519   return true;
520 }
521 
DecodeVideo(ScopedAVPacket packet)522 void FakeMediaSource::DecodeVideo(ScopedAVPacket packet) {
523   auto result = video_decoding_loop_->DecodePacket(
524       packet.get(), base::BindRepeating(&FakeMediaSource::OnNewVideoFrame,
525                                         base::Unretained(this)));
526   CHECK_EQ(result, FFmpegDecodingLoop::DecodeStatus::kOkay)
527       << "Failed to decode video.";
528 }
529 
OnNewVideoFrame(AVFrame * frame)530 bool FakeMediaSource::OnNewVideoFrame(AVFrame* frame) {
531   gfx::Size size(av_video_context_->width, av_video_context_->height);
532 
533   if (!video_first_pts_set_) {
534     video_first_pts_ = frame->pts;
535     video_first_pts_set_ = true;
536   }
537   const AVRational& time_base = av_video_stream()->time_base;
538   base::TimeDelta timestamp =
539       PtsToTimeDelta(frame->pts - video_first_pts_, time_base);
540   if (timestamp < last_video_frame_timestamp_) {
541     // Stream has rewound.  Rebase |video_first_pts_|.
542     const AVRational& frame_rate = av_video_stream()->r_frame_rate;
543     timestamp = last_video_frame_timestamp_ + (base::TimeDelta::FromSeconds(1) *
544                                                frame_rate.den / frame_rate.num);
545     const int64_t adjustment_pts = TimeDeltaToPts(timestamp, time_base);
546     video_first_pts_ = frame->pts - adjustment_pts;
547   }
548 
549   AVFrame* shallow_copy = av_frame_clone(frame);
550   scoped_refptr<media::VideoFrame> video_frame =
551       VideoFrame::WrapExternalYuvData(
552           media::PIXEL_FORMAT_I420, size, gfx::Rect(size), size,
553           shallow_copy->linesize[0], shallow_copy->linesize[1],
554           shallow_copy->linesize[2], shallow_copy->data[0],
555           shallow_copy->data[1], shallow_copy->data[2], timestamp);
556   if (!video_frame)
557     return false;
558   video_frame_queue_.push(video_frame);
559   video_frame_queue_.back()->AddDestructionObserver(
560       base::BindOnce(&AVFreeFrame, shallow_copy));
561   last_video_frame_timestamp_ = timestamp;
562   return true;
563 }
564 
Decode(bool decode_audio)565 void FakeMediaSource::Decode(bool decode_audio) {
566   // Read the stream until one video frame can be decoded.
567   while (true) {
568     if (decode_audio && !audio_bus_queue_.empty())
569       return;
570     if (!decode_audio && !video_frame_queue_.empty())
571       return;
572 
573     bool audio_packet = false;
574     ScopedAVPacket packet = DemuxOnePacket(&audio_packet);
575     if (!packet) {
576       VLOG(1) << "End of stream.";
577       return;
578     }
579 
580     if (audio_packet)
581       DecodeAudio(std::move(packet));
582     else
583       DecodeVideo(std::move(packet));
584   }
585 }
586 
ProvideInput(media::AudioBus * output_bus,uint32_t frames_delayed)587 double FakeMediaSource::ProvideInput(media::AudioBus* output_bus,
588                                      uint32_t frames_delayed) {
589   if (audio_fifo_->frames() >= output_bus->frames()) {
590     audio_fifo_->Consume(output_bus, 0, output_bus->frames());
591     return 1.0;
592   } else {
593     LOG(WARNING) << "Not enough audio data for resampling.";
594     output_bus->Zero();
595     return 0.0;
596   }
597 }
598 
599 scoped_refptr<media::VideoFrame>
PopOldestInsertedVideoFrame()600 FakeMediaSource::PopOldestInsertedVideoFrame() {
601   CHECK(!inserted_video_frame_queue_.empty());
602   scoped_refptr<media::VideoFrame> video_frame =
603       inserted_video_frame_queue_.front();
604   inserted_video_frame_queue_.pop();
605   return video_frame;
606 }
607 
av_audio_stream()608 AVStream* FakeMediaSource::av_audio_stream() {
609   return av_format_context_->streams[audio_stream_index_];
610 }
611 
av_video_stream()612 AVStream* FakeMediaSource::av_video_stream() {
613   return av_format_context_->streams[video_stream_index_];
614 }
615 
616 }  // namespace cast
617 }  // namespace media
618