1 // Copyright (c) 2012 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 <stddef.h>
6 #include <stdint.h>
7 
8 #include <algorithm>
9 #include <string>
10 #include <utility>
11 
12 #include "base/bind.h"
13 #include "base/callback_forward.h"
14 #include "base/files/file_path.h"
15 #include "base/location.h"
16 #include "base/logging.h"
17 #include "base/path_service.h"
18 #include "base/run_loop.h"
19 #include "base/single_thread_task_runner.h"
20 #include "base/stl_util.h"
21 #include "base/test/mock_callback.h"
22 #include "base/test/task_environment.h"
23 #include "base/threading/thread.h"
24 #include "base/threading/thread_task_runner_handle.h"
25 #include "build/build_config.h"
26 #include "media/base/decrypt_config.h"
27 #include "media/base/demuxer_stream.h"
28 #include "media/base/media_client.h"
29 #include "media/base/media_tracks.h"
30 #include "media/base/media_util.h"
31 #include "media/base/mock_demuxer_host.h"
32 #include "media/base/mock_filters.h"
33 #include "media/base/mock_media_log.h"
34 #include "media/base/test_helpers.h"
35 #include "media/base/timestamp_constants.h"
36 #include "media/ffmpeg/ffmpeg_common.h"
37 #include "media/filters/ffmpeg_demuxer.h"
38 #include "media/filters/file_data_source.h"
39 #include "media/formats/mp4/avc.h"
40 #include "media/formats/mp4/bitstream_converter.h"
41 #include "media/media_buildflags.h"
42 #include "testing/gtest/include/gtest/gtest.h"
43 #include "ui/gfx/color_space.h"
44 
45 using ::testing::_;
46 using ::testing::AnyNumber;
47 using ::testing::DoAll;
48 using ::testing::Eq;
49 using ::testing::Exactly;
50 using ::testing::InSequence;
51 using ::testing::Invoke;
52 using ::testing::NotNull;
53 using ::testing::Return;
54 using ::testing::SaveArg;
55 using ::testing::SetArgPointee;
56 using ::testing::StrictMock;
57 using ::testing::WithArgs;
58 
59 namespace media {
60 
61 MATCHER(IsEndOfStreamBuffer,
62         std::string(negation ? "isn't" : "is") + " end of stream") {
63   return arg->end_of_stream();
64 }
65 
66 // This does not verify any of the codec parameters that may be included in the
67 // log entry.
68 MATCHER_P(SimpleCreatedFFmpegDemuxerStream, stream_type, "") {
69   return CONTAINS_STRING(arg, "\"info\":\"FFmpegDemuxer: created " +
70                                   std::string(stream_type) +
71                                   " stream, config codec:");
72 }
73 
74 MATCHER_P(FailedToCreateValidDecoderConfigFromStream, stream_type, "") {
75   return CONTAINS_STRING(
76       arg,
77       "\"debug\":\"Warning, FFmpegDemuxer failed to create a "
78       "valid/supported " +
79           std::string(stream_type) +
80           " decoder configuration from muxed stream");
81 }
82 
83 MATCHER_P(SkippingUnsupportedStream, stream_type, "") {
84   return CONTAINS_STRING(
85       arg, "\"info\":\"FFmpegDemuxer: skipping invalid or unsupported " +
86                std::string(stream_type) + " track");
87 }
88 
89 const uint8_t kEncryptedMediaInitData[] = {
90     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
91     0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
92 };
93 
EosOnReadDone(bool * got_eos_buffer,DemuxerStream::Status status,scoped_refptr<DecoderBuffer> buffer)94 static void EosOnReadDone(bool* got_eos_buffer,
95                           DemuxerStream::Status status,
96                           scoped_refptr<DecoderBuffer> buffer) {
97   base::ThreadTaskRunnerHandle::Get()->PostTask(
98       FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated());
99 
100   EXPECT_EQ(status, DemuxerStream::kOk);
101   if (buffer->end_of_stream()) {
102     *got_eos_buffer = true;
103     return;
104   }
105 
106   EXPECT_TRUE(buffer->data());
107   EXPECT_GT(buffer->data_size(), 0u);
108   *got_eos_buffer = false;
109 }
110 
111 // Fixture class to facilitate writing tests.  Takes care of setting up the
112 // FFmpeg, pipeline and filter host mocks.
113 class FFmpegDemuxerTest : public testing::Test {
114  protected:
115   FFmpegDemuxerTest() = default;
116 
~FFmpegDemuxerTest()117   ~FFmpegDemuxerTest() override { Shutdown(); }
118 
Shutdown()119   void Shutdown() {
120     if (demuxer_)
121       demuxer_->Stop();
122     demuxer_.reset();
123     task_environment_.RunUntilIdle();
124     data_source_.reset();
125   }
126 
127   // TODO(wolenetz): Combine with CreateDemuxer() and expand coverage of all of
128   // these tests to use strict media log. See https://crbug.com/749178.
CreateDemuxerWithStrictMediaLog(const std::string & name)129   void CreateDemuxerWithStrictMediaLog(const std::string& name) {
130     CreateDemuxerInternal(name, &media_log_);
131   }
132 
CreateDemuxer(const std::string & name)133   void CreateDemuxer(const std::string& name) {
134     CreateDemuxerInternal(name, &dummy_media_log_);
135   }
136 
GetStream(DemuxerStream::Type type)137   DemuxerStream* GetStream(DemuxerStream::Type type) {
138     std::vector<DemuxerStream*> streams = demuxer_->GetAllStreams();
139     for (auto* stream : streams) {
140       if (stream->type() == type)
141         return stream;
142     }
143     return nullptr;
144   }
145 
146   MOCK_METHOD1(CheckPoint, void(int v));
147 
InitializeDemuxerInternal(media::PipelineStatus expected_pipeline_status,base::Time timeline_offset)148   void InitializeDemuxerInternal(media::PipelineStatus expected_pipeline_status,
149                                  base::Time timeline_offset) {
150     if (expected_pipeline_status == PIPELINE_OK)
151       EXPECT_CALL(host_, SetDuration(_)).Times(AnyNumber());
152     WaitableMessageLoopEvent event;
153     demuxer_->Initialize(&host_, event.GetPipelineStatusCB());
154     demuxer_->timeline_offset_ = timeline_offset;
155     event.RunAndWaitForStatus(expected_pipeline_status);
156   }
157 
InitializeDemuxer()158   void InitializeDemuxer() {
159     InitializeDemuxerInternal(PIPELINE_OK, base::Time());
160   }
161 
InitializeDemuxerWithTimelineOffset(base::Time timeline_offset)162   void InitializeDemuxerWithTimelineOffset(base::Time timeline_offset) {
163     InitializeDemuxerInternal(PIPELINE_OK, timeline_offset);
164   }
165 
InitializeDemuxerAndExpectPipelineStatus(media::PipelineStatus expected_pipeline_status)166   void InitializeDemuxerAndExpectPipelineStatus(
167       media::PipelineStatus expected_pipeline_status) {
168     InitializeDemuxerInternal(expected_pipeline_status, base::Time());
169   }
170 
SeekOnVideoTrackChangePassthrough(base::TimeDelta time,base::OnceCallback<void (DemuxerStream::Type,const std::vector<DemuxerStream * > &)> cb,DemuxerStream::Type type,const std::vector<DemuxerStream * > & streams)171   void SeekOnVideoTrackChangePassthrough(
172       base::TimeDelta time,
173       base::OnceCallback<void(DemuxerStream::Type,
174                               const std::vector<DemuxerStream*>&)> cb,
175       DemuxerStream::Type type,
176       const std::vector<DemuxerStream*>& streams) {
177     // The tests can't access private methods directly because gtest uses
178     // some magic macros that break the 'friend' declaration.
179     demuxer_->SeekOnVideoTrackChange(time, std::move(cb), type, streams);
180   }
181 
182   MOCK_METHOD2(OnReadDoneCalled, void(int, int64_t));
183 
184   struct ReadExpectation {
ReadExpectationmedia::FFmpegDemuxerTest::ReadExpectation185     ReadExpectation(size_t size,
186                     int64_t timestamp_us,
187                     base::TimeDelta discard_front_padding,
188                     bool is_key_frame,
189                     DemuxerStream::Status status)
190         : size(size),
191           timestamp_us(timestamp_us),
192           discard_front_padding(discard_front_padding),
193           is_key_frame(is_key_frame),
194           status(status) {}
195 
196     size_t size;
197     int64_t timestamp_us;
198     base::TimeDelta discard_front_padding;
199     bool is_key_frame;
200     DemuxerStream::Status status;
201   };
202 
203   // Verifies that |buffer| has a specific |size| and |timestamp|.
204   // |location| simply indicates where the call to this function was made.
205   // This makes it easier to track down where test failures occur.
OnReadDone(const base::Location & location,const ReadExpectation & read_expectation,base::OnceClosure quit_closure,DemuxerStream::Status status,scoped_refptr<DecoderBuffer> buffer)206   void OnReadDone(const base::Location& location,
207                   const ReadExpectation& read_expectation,
208                   base::OnceClosure quit_closure,
209                   DemuxerStream::Status status,
210                   scoped_refptr<DecoderBuffer> buffer) {
211     std::string location_str = location.ToString();
212     location_str += "\n";
213     SCOPED_TRACE(location_str);
214     EXPECT_EQ(read_expectation.status, status);
215     if (status == DemuxerStream::kOk) {
216       EXPECT_TRUE(buffer);
217       EXPECT_EQ(read_expectation.size, buffer->data_size());
218       EXPECT_EQ(read_expectation.timestamp_us,
219                 buffer->timestamp().InMicroseconds());
220       EXPECT_EQ(read_expectation.discard_front_padding,
221                 buffer->discard_padding().first);
222       EXPECT_EQ(read_expectation.is_key_frame, buffer->is_key_frame());
223     }
224     OnReadDoneCalled(read_expectation.size, read_expectation.timestamp_us);
225     std::move(quit_closure).Run();
226   }
227 
NewReadCBWithCheckedDiscard(const base::Location & location,int size,int64_t timestamp_us,base::TimeDelta discard_front_padding,bool is_key_frame,DemuxerStream::Status status,base::OnceClosure quit_closure)228   DemuxerStream::ReadCB NewReadCBWithCheckedDiscard(
229       const base::Location& location,
230       int size,
231       int64_t timestamp_us,
232       base::TimeDelta discard_front_padding,
233       bool is_key_frame,
234       DemuxerStream::Status status,
235       base::OnceClosure quit_closure) {
236     EXPECT_CALL(*this, OnReadDoneCalled(size, timestamp_us));
237 
238     struct ReadExpectation read_expectation(
239         size, timestamp_us, discard_front_padding, is_key_frame, status);
240 
241     return base::BindOnce(&FFmpegDemuxerTest::OnReadDone,
242                           base::Unretained(this), location, read_expectation,
243                           std::move(quit_closure));
244   }
245 
Read(DemuxerStream * stream,const base::Location & location,int size,int64_t timestamp_us,bool is_key_frame,DemuxerStream::Status status=DemuxerStream::Status::kOk,base::TimeDelta discard_front_padding=base::TimeDelta ())246   void Read(DemuxerStream* stream,
247             const base::Location& location,
248             int size,
249             int64_t timestamp_us,
250             bool is_key_frame,
251             DemuxerStream::Status status = DemuxerStream::Status::kOk,
252             base::TimeDelta discard_front_padding = base::TimeDelta()) {
253     base::RunLoop run_loop;
254     stream->Read(NewReadCBWithCheckedDiscard(
255         location, size, timestamp_us, discard_front_padding, is_key_frame,
256         status, run_loop.QuitClosure()));
257     run_loop.Run();
258 
259     // Ensure tasks posted after the ReadCB is satisfied run. These are always
260     // tasks posted to FFmpegDemuxer's internal |blocking_task_runner_|, which
261     // the RunLoop above won't pump.
262     task_environment_.RunUntilIdle();
263   }
264 
265   MOCK_METHOD2(OnEncryptedMediaInitData,
266                void(EmeInitDataType init_data_type,
267                     const std::vector<uint8_t>& init_data));
268 
OnMediaTracksUpdated(std::unique_ptr<MediaTracks> tracks)269   void OnMediaTracksUpdated(std::unique_ptr<MediaTracks> tracks) {
270     CHECK(tracks.get());
271     media_tracks_ = std::move(tracks);
272   }
273 
274   // Accessor to demuxer internals.
SetDurationKnown(bool duration_known)275   void SetDurationKnown(bool duration_known) {
276     demuxer_->duration_known_ = duration_known;
277     if (!duration_known)
278       demuxer_->duration_ = kInfiniteDuration;
279   }
280 
281 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
HasBitstreamConverter(DemuxerStream * stream) const282   bool HasBitstreamConverter(DemuxerStream* stream) const {
283     return !!reinterpret_cast<FFmpegDemuxerStream*>(stream)
284                  ->bitstream_converter_;
285   }
286 #endif
287 
288   // Fixture members.
289 
290   base::test::TaskEnvironment task_environment_;
291 
292   // TODO(wolenetz): Consider expanding MediaLog verification coverage here
293   // using StrictMock<MockMediaLog> for all FFmpegDemuxerTests. See
294   // https://crbug.com/749178.
295   StrictMock<MockMediaLog> media_log_;
296   NullMediaLog dummy_media_log_;
297 
298   std::unique_ptr<FileDataSource> data_source_;
299   std::unique_ptr<FFmpegDemuxer> demuxer_;
300   StrictMock<MockDemuxerHost> host_;
301   std::unique_ptr<MediaTracks> media_tracks_;
302 
format_context()303   AVFormatContext* format_context() {
304     return demuxer_->glue_->format_context();
305   }
306 
preferred_seeking_stream(base::TimeDelta seek_time) const307   DemuxerStream* preferred_seeking_stream(base::TimeDelta seek_time) const {
308     return demuxer_->FindPreferredStreamForSeeking(seek_time);
309   }
310 
ReadUntilEndOfStream(DemuxerStream * stream)311   void ReadUntilEndOfStream(DemuxerStream* stream) {
312     bool got_eos_buffer = false;
313     const int kMaxBuffers = 170;
314     for (int i = 0; !got_eos_buffer && i < kMaxBuffers; i++) {
315       stream->Read(base::BindOnce(&EosOnReadDone, &got_eos_buffer));
316       base::RunLoop().Run();
317     }
318 
319     EXPECT_TRUE(got_eos_buffer);
320   }
321 
Seek(base::TimeDelta seek_target)322   void Seek(base::TimeDelta seek_target) {
323     WaitableMessageLoopEvent event;
324     demuxer_->Seek(seek_target, event.GetPipelineStatusCB());
325     event.RunAndWaitForStatus(PIPELINE_OK);
326   }
327 
328  private:
CreateDemuxerInternal(const std::string & name,MediaLog * media_log)329   void CreateDemuxerInternal(const std::string& name, MediaLog* media_log) {
330     CHECK(!demuxer_);
331 
332     EXPECT_CALL(host_, OnBufferedTimeRangesChanged(_)).Times(AnyNumber());
333 
334     CreateDataSource(name);
335 
336     Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb =
337         base::BindRepeating(&FFmpegDemuxerTest::OnEncryptedMediaInitData,
338                             base::Unretained(this));
339 
340     Demuxer::MediaTracksUpdatedCB tracks_updated_cb = base::Bind(
341         &FFmpegDemuxerTest::OnMediaTracksUpdated, base::Unretained(this));
342 
343     demuxer_.reset(new FFmpegDemuxer(
344         base::ThreadTaskRunnerHandle::Get(), data_source_.get(),
345         encrypted_media_init_data_cb, tracks_updated_cb, media_log, false));
346   }
347 
CreateDataSource(const std::string & name)348   void CreateDataSource(const std::string& name) {
349     CHECK(!data_source_);
350 
351     base::FilePath file_path;
352     EXPECT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &file_path));
353 
354     file_path = file_path.Append(FILE_PATH_LITERAL("media"))
355                     .Append(FILE_PATH_LITERAL("test"))
356                     .Append(FILE_PATH_LITERAL("data"))
357                     .AppendASCII(name);
358 
359     data_source_.reset(new FileDataSource());
360     EXPECT_TRUE(data_source_->Initialize(file_path));
361   }
362 
363   DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest);
364 };
365 
TEST_F(FFmpegDemuxerTest,Initialize_OpenFails)366 TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) {
367   // Simulate avformat_open_input() failing.
368   CreateDemuxer("ten_byte_file");
369   WaitableMessageLoopEvent event;
370   demuxer_->Initialize(&host_, event.GetPipelineStatusCB());
371   event.RunAndWaitForStatus(DEMUXER_ERROR_COULD_NOT_OPEN);
372 }
373 
TEST_F(FFmpegDemuxerTest,Initialize_NoStreams)374 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) {
375   // Open a file with no streams whatsoever.
376   CreateDemuxer("no_streams.webm");
377   WaitableMessageLoopEvent event;
378   demuxer_->Initialize(&host_, event.GetPipelineStatusCB());
379   event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
380 }
381 
TEST_F(FFmpegDemuxerTest,Initialize_NoAudioVideo)382 TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) {
383   // Open a file containing streams but none of which are audio/video streams.
384   CreateDemuxer("no_audio_video.webm");
385   WaitableMessageLoopEvent event;
386   demuxer_->Initialize(&host_, event.GetPipelineStatusCB());
387   event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
388 }
389 
TEST_F(FFmpegDemuxerTest,Initialize_Successful)390 TEST_F(FFmpegDemuxerTest, Initialize_Successful) {
391   CreateDemuxer("bear-320x240.webm");
392   InitializeDemuxer();
393 
394   // Video stream should be present.
395   DemuxerStream* stream = GetStream(DemuxerStream::VIDEO);
396   ASSERT_TRUE(stream);
397   EXPECT_EQ(DemuxerStream::VIDEO, stream->type());
398 
399   const VideoDecoderConfig& video_config = stream->video_decoder_config();
400   EXPECT_EQ(kCodecVP8, video_config.codec());
401   EXPECT_EQ(VideoDecoderConfig::AlphaMode::kIsOpaque,
402             video_config.alpha_mode());
403   EXPECT_EQ(320, video_config.coded_size().width());
404   EXPECT_EQ(240, video_config.coded_size().height());
405   EXPECT_EQ(0, video_config.visible_rect().x());
406   EXPECT_EQ(0, video_config.visible_rect().y());
407   EXPECT_EQ(320, video_config.visible_rect().width());
408   EXPECT_EQ(240, video_config.visible_rect().height());
409   EXPECT_EQ(320, video_config.natural_size().width());
410   EXPECT_EQ(240, video_config.natural_size().height());
411   EXPECT_TRUE(video_config.extra_data().empty());
412 
413   // Audio stream should be present.
414   stream = GetStream(DemuxerStream::AUDIO);
415   ASSERT_TRUE(stream);
416   EXPECT_EQ(DemuxerStream::AUDIO, stream->type());
417 
418   const AudioDecoderConfig& audio_config = stream->audio_decoder_config();
419   EXPECT_EQ(kCodecVorbis, audio_config.codec());
420   EXPECT_EQ(32, audio_config.bits_per_channel());
421   EXPECT_EQ(CHANNEL_LAYOUT_STEREO, audio_config.channel_layout());
422   EXPECT_EQ(44100, audio_config.samples_per_second());
423   EXPECT_EQ(kSampleFormatPlanarF32, audio_config.sample_format());
424   EXPECT_FALSE(audio_config.extra_data().empty());
425 
426   // Unknown stream should never be present.
427   EXPECT_EQ(2u, demuxer_->GetAllStreams().size());
428 }
429 
430 // Android has no Theora support, so this test doesn't work.
431 #if !defined(OS_ANDROID)
TEST_F(FFmpegDemuxerTest,Initialize_Multitrack)432 TEST_F(FFmpegDemuxerTest, Initialize_Multitrack) {
433   // Open a file containing the following streams:
434   //   Stream #0: Video (VP8)
435   //   Stream #1: Audio (Vorbis)
436   //   Stream #2: Subtitles (SRT)
437   //   Stream #3: Video (Theora)
438   //   Stream #4: Audio (16-bit signed little endian PCM)
439   CreateDemuxer("bear-320x240-multitrack.webm");
440   InitializeDemuxer();
441 
442   std::vector<DemuxerStream*> streams = demuxer_->GetAllStreams();
443   EXPECT_EQ(4u, streams.size());
444 
445   // Stream #0 should be VP8 video.
446   DemuxerStream* stream = streams[0];
447   ASSERT_TRUE(stream);
448   EXPECT_EQ(DemuxerStream::VIDEO, stream->type());
449   EXPECT_EQ(kCodecVP8, stream->video_decoder_config().codec());
450 
451   // Stream #1 should be Vorbis audio.
452   stream = streams[1];
453   ASSERT_TRUE(stream);
454   EXPECT_EQ(DemuxerStream::AUDIO, stream->type());
455   EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec());
456 
457   // The subtitles stream is skipped.
458   // Stream #2 should be Theora video.
459   stream = streams[2];
460   ASSERT_TRUE(stream);
461   EXPECT_EQ(DemuxerStream::VIDEO, stream->type());
462   EXPECT_EQ(kCodecTheora, stream->video_decoder_config().codec());
463 
464   // Stream #3 should be PCM audio.
465   stream = streams[3];
466   ASSERT_TRUE(stream);
467   EXPECT_EQ(DemuxerStream::AUDIO, stream->type());
468   EXPECT_EQ(kCodecPCM, stream->audio_decoder_config().codec());
469 }
470 #endif
471 
TEST_F(FFmpegDemuxerTest,Initialize_Encrypted)472 TEST_F(FFmpegDemuxerTest, Initialize_Encrypted) {
473   EXPECT_CALL(
474       *this, OnEncryptedMediaInitData(
475                  EmeInitDataType::WEBM,
476                  std::vector<uint8_t>(kEncryptedMediaInitData,
477                                       kEncryptedMediaInitData +
478                                           base::size(kEncryptedMediaInitData))))
479       .Times(Exactly(2));
480 
481   CreateDemuxer("bear-320x240-av_enc-av.webm");
482   InitializeDemuxer();
483 }
484 
TEST_F(FFmpegDemuxerTest,Initialize_NoConfigChangeSupport)485 TEST_F(FFmpegDemuxerTest, Initialize_NoConfigChangeSupport) {
486   // Will create one audio, one video, and one text stream.
487   CreateDemuxer("bear-vp8-webvtt.webm");
488   InitializeDemuxer();
489 
490   for (auto* stream : demuxer_->GetAllStreams())
491     EXPECT_FALSE(stream->SupportsConfigChanges());
492 }
493 
TEST_F(FFmpegDemuxerTest,AbortPendingReads)494 TEST_F(FFmpegDemuxerTest, AbortPendingReads) {
495   // We test that on a successful audio packet read.
496   CreateDemuxer("bear-320x240.webm");
497   InitializeDemuxer();
498 
499   // Attempt a read from the audio stream and run the message loop until done.
500   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
501 
502   // Depending on where in the reading process ffmpeg is, an error may cause the
503   // stream to be marked as EOF.  Simulate this here to ensure it is properly
504   // cleared by the AbortPendingReads() call.
505   format_context()->pb->eof_reached = 1;
506   {
507     base::RunLoop run_loop;
508     audio->Read(NewReadCBWithCheckedDiscard(FROM_HERE, 29, 0, base::TimeDelta(),
509                                             true, DemuxerStream::kAborted,
510                                             run_loop.QuitClosure()));
511     demuxer_->AbortPendingReads();
512     run_loop.Run();
513     task_environment_.RunUntilIdle();
514   }
515 
516   // Additional reads should also be aborted (until a Seek()).
517   Read(audio, FROM_HERE, 29, 0, true, DemuxerStream::kAborted);
518 
519   // Ensure blocking thread has completed outstanding work.
520   demuxer_->Stop();
521   EXPECT_EQ(format_context()->pb->eof_reached, 0);
522 
523   // Calling abort after stop should not crash.
524   demuxer_->AbortPendingReads();
525   demuxer_.reset();
526 }
527 
TEST_F(FFmpegDemuxerTest,Read_Audio)528 TEST_F(FFmpegDemuxerTest, Read_Audio) {
529   // We test that on a successful audio packet read.
530   CreateDemuxer("bear-320x240.webm");
531   InitializeDemuxer();
532 
533   // Attempt a read from the audio stream and run the message loop until done.
534   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
535   Read(audio, FROM_HERE, 29, 0, true);
536   Read(audio, FROM_HERE, 27, 3000, true);
537   EXPECT_EQ(166866, demuxer_->GetMemoryUsage());
538 }
539 
TEST_F(FFmpegDemuxerTest,Read_Video)540 TEST_F(FFmpegDemuxerTest, Read_Video) {
541   // We test that on a successful video packet read.
542   CreateDemuxer("bear-320x240.webm");
543   InitializeDemuxer();
544 
545   // Attempt a read from the video stream and run the message loop until done.
546   DemuxerStream* video = GetStream(DemuxerStream::VIDEO);
547   Read(video, FROM_HERE, 22084, 0, true);
548   Read(video, FROM_HERE, 1057, 33000, false);
549   EXPECT_EQ(148778, demuxer_->GetMemoryUsage());
550 }
551 
TEST_F(FFmpegDemuxerTest,SeekInitialized_NoVideoStartTime)552 TEST_F(FFmpegDemuxerTest, SeekInitialized_NoVideoStartTime) {
553   CreateDemuxer("audio-start-time-only.webm");
554   InitializeDemuxer();
555   // Video stream should be preferred for seeking even if video start time is
556   // unknown.
557   DemuxerStream* vstream = GetStream(DemuxerStream::VIDEO);
558   EXPECT_EQ(vstream, preferred_seeking_stream(base::TimeDelta()));
559 }
560 
TEST_F(FFmpegDemuxerTest,Seeking_PreferredStreamSelection)561 TEST_F(FFmpegDemuxerTest, Seeking_PreferredStreamSelection) {
562   const int64_t kTimelineOffsetMs = 1352550896000LL;
563 
564   // Test the start time is the first timestamp of the video and audio stream.
565   CreateDemuxer("nonzero-start-time.webm");
566   InitializeDemuxerWithTimelineOffset(
567       base::Time::FromJsTime(kTimelineOffsetMs));
568 
569   FFmpegDemuxerStream* video =
570       static_cast<FFmpegDemuxerStream*>(GetStream(DemuxerStream::VIDEO));
571   FFmpegDemuxerStream* audio =
572       static_cast<FFmpegDemuxerStream*>(GetStream(DemuxerStream::AUDIO));
573 
574   const base::TimeDelta video_start_time =
575       base::TimeDelta::FromMicroseconds(400000);
576   const base::TimeDelta audio_start_time =
577       base::TimeDelta::FromMicroseconds(396000);
578 
579   // Seeking to a position lower than the start time of either stream should
580   // prefer video stream for seeking.
581   EXPECT_EQ(video, preferred_seeking_stream(base::TimeDelta()));
582   // Seeking to a position that has audio data, but not video, should prefer
583   // the audio stream for seeking.
584   EXPECT_EQ(audio, preferred_seeking_stream(audio_start_time));
585   // Seeking to a position where both audio and video streams have data should
586   // prefer the video stream for seeking.
587   EXPECT_EQ(video, preferred_seeking_stream(video_start_time));
588 
589   // A disabled stream should be preferred only when there's no other viable
590   // option among enabled streams.
591   audio->SetEnabled(false, base::TimeDelta());
592   EXPECT_EQ(video, preferred_seeking_stream(video_start_time));
593   // Audio stream is preferred, even though it is disabled, since video stream
594   // start time is higher than the seek target == audio_start_time in this case.
595   EXPECT_EQ(audio, preferred_seeking_stream(audio_start_time));
596 
597   audio->SetEnabled(true, base::TimeDelta());
598   video->SetEnabled(false, base::TimeDelta());
599   EXPECT_EQ(audio, preferred_seeking_stream(audio_start_time));
600   EXPECT_EQ(audio, preferred_seeking_stream(video_start_time));
601 
602   // When both audio and video streams are disabled and there's no enabled
603   // streams, then audio is preferred since it has lower start time.
604   audio->SetEnabled(false, base::TimeDelta());
605   EXPECT_EQ(audio, preferred_seeking_stream(audio_start_time));
606   EXPECT_EQ(audio, preferred_seeking_stream(video_start_time));
607 }
608 
TEST_F(FFmpegDemuxerTest,Read_VideoPositiveStartTime)609 TEST_F(FFmpegDemuxerTest, Read_VideoPositiveStartTime) {
610   const int64_t kTimelineOffsetMs = 1352550896000LL;
611 
612   // Test the start time is the first timestamp of the video and audio stream.
613   CreateDemuxer("nonzero-start-time.webm");
614   InitializeDemuxerWithTimelineOffset(
615       base::Time::FromJsTime(kTimelineOffsetMs));
616 
617   // Attempt a read from the video stream and run the message loop until done.
618   DemuxerStream* video = GetStream(DemuxerStream::VIDEO);
619   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
620 
621   const base::TimeDelta video_start_time =
622       base::TimeDelta::FromMicroseconds(400000);
623   const base::TimeDelta audio_start_time =
624       base::TimeDelta::FromMicroseconds(396000);
625 
626   // Run the test twice with a seek in between.
627   for (int i = 0; i < 2; ++i) {
628     Read(video, FROM_HERE, 5636, video_start_time.InMicroseconds(), true);
629     Read(audio, FROM_HERE, 165, audio_start_time.InMicroseconds(), true);
630 
631     // Verify that the start time is equal to the lowest timestamp (ie the
632     // audio).
633     EXPECT_EQ(audio_start_time, demuxer_->start_time());
634 
635     // Verify that the timeline offset has not been adjusted by the start time.
636     EXPECT_EQ(kTimelineOffsetMs, demuxer_->GetTimelineOffset().ToJavaTime());
637 
638     // Seek back to the beginning and repeat the test.
639     WaitableMessageLoopEvent event;
640     demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB());
641     event.RunAndWaitForStatus(PIPELINE_OK);
642   }
643 }
644 
TEST_F(FFmpegDemuxerTest,Read_AudioNoStartTime)645 TEST_F(FFmpegDemuxerTest, Read_AudioNoStartTime) {
646   // FFmpeg does not set timestamps when demuxing wave files.  Ensure that the
647   // demuxer sets a start time of zero in this case.
648   CreateDemuxer("sfx_s24le.wav");
649   InitializeDemuxer();
650 
651   // Run the test twice with a seek in between.
652   for (int i = 0; i < 2; ++i) {
653     Read(GetStream(DemuxerStream::AUDIO), FROM_HERE, 4095, 0, true);
654     EXPECT_EQ(base::TimeDelta(), demuxer_->start_time());
655 
656     // Seek back to the beginning and repeat the test.
657     WaitableMessageLoopEvent event;
658     demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB());
659     event.RunAndWaitForStatus(PIPELINE_OK);
660   }
661 }
662 
TEST_F(FFmpegDemuxerTest,Read_InvalidNegativeTimestamp)663 TEST_F(FFmpegDemuxerTest, Read_InvalidNegativeTimestamp) {
664   CreateDemuxer("negative_ts.flac");
665   InitializeDemuxer();
666   EXPECT_CALL(host_, OnDemuxerError(DEMUXER_ERROR_COULD_NOT_PARSE));
667   ReadUntilEndOfStream(GetStream(DemuxerStream::AUDIO));
668 }
669 
670 // Android has no Theora support, so these tests doesn't work.
671 #if !defined(OS_ANDROID)
TEST_F(FFmpegDemuxerTest,Read_AudioNegativeStartTimeAndOggDiscard_Bear)672 TEST_F(FFmpegDemuxerTest, Read_AudioNegativeStartTimeAndOggDiscard_Bear) {
673   // Many ogg files have negative starting timestamps, so ensure demuxing and
674   // seeking work correctly with a negative start time.
675   CreateDemuxer("bear.ogv");
676   InitializeDemuxer();
677 
678   // Attempt a read from the video stream and run the message loop until done.
679   DemuxerStream* video = GetStream(DemuxerStream::VIDEO);
680   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
681 
682   // Run the test once (should be twice..., see note) with a seek in between.
683   //
684   // TODO(dalecurtis): We only run the test once since FFmpeg does not currently
685   // guarantee the order of demuxed packets in OGG containers. See
686   // http://crbug.com/387996.
687   for (int i = 0; i < 1; ++i) {
688     Read(audio, FROM_HERE, 40, 0, true, DemuxerStream::Status::kOk,
689          kInfiniteDuration);
690     Read(audio, FROM_HERE, 41, 2903, true, DemuxerStream::Status::kOk,
691          kInfiniteDuration);
692     Read(audio, FROM_HERE, 173, 5805, true, DemuxerStream::Status::kOk,
693          base::TimeDelta::FromMicroseconds(10159));
694 
695     Read(audio, FROM_HERE, 148, 18866, true);
696     EXPECT_EQ(base::TimeDelta::FromMicroseconds(-15964),
697               demuxer_->start_time());
698 
699     Read(video, FROM_HERE, 5751, 0, true);
700     Read(video, FROM_HERE, 846, 33367, false);
701     Read(video, FROM_HERE, 1255, 66733, false);
702 
703     // Seek back to the beginning and repeat the test.
704     WaitableMessageLoopEvent event;
705     demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB());
706     event.RunAndWaitForStatus(PIPELINE_OK);
707   }
708 }
709 
710 // Same test above, but using sync2.ogv which has video stream muxed before the
711 // audio stream, so seeking based only on start time will fail since ffmpeg is
712 // essentially just seeking based on file position.
TEST_F(FFmpegDemuxerTest,Read_AudioNegativeStartTimeAndOggDiscard_Sync)713 TEST_F(FFmpegDemuxerTest, Read_AudioNegativeStartTimeAndOggDiscard_Sync) {
714   // Many ogg files have negative starting timestamps, so ensure demuxing and
715   // seeking work correctly with a negative start time.
716   CreateDemuxer("sync2.ogv");
717   InitializeDemuxer();
718 
719   // Attempt a read from the video stream and run the message loop until done.
720   DemuxerStream* video = GetStream(DemuxerStream::VIDEO);
721   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
722 
723   // Run the test twice with a seek in between.
724   for (int i = 0; i < 2; ++i) {
725     Read(audio, FROM_HERE, 1, 0, true, DemuxerStream::Status::kOk,
726          base::TimeDelta::FromMicroseconds(2902));
727     Read(audio, FROM_HERE, 1, 2902, true);
728     EXPECT_EQ(base::TimeDelta::FromMicroseconds(-2902), demuxer_->start_time());
729 
730     // Though the internal start time may be below zero, the exposed media time
731     // must always be >= zero.
732     EXPECT_EQ(base::TimeDelta(), demuxer_->GetStartTime());
733 
734     Read(video, FROM_HERE, 9997, 0, true);
735     Read(video, FROM_HERE, 16, 33241, false);
736     Read(video, FROM_HERE, 631, 66482, false);
737 
738     // Seek back to the beginning and repeat the test.
739     WaitableMessageLoopEvent event;
740     demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB());
741     event.RunAndWaitForStatus(PIPELINE_OK);
742   }
743 }
744 #endif  // !defined(OS_ANDROID)
745 
746 // Similar to the test above, but using an opus clip with a large amount of
747 // pre-skip, which ffmpeg encodes as negative timestamps.
TEST_F(FFmpegDemuxerTest,Read_AudioNegativeStartTimeAndOpusDiscard_Sync)748 TEST_F(FFmpegDemuxerTest, Read_AudioNegativeStartTimeAndOpusDiscard_Sync) {
749   CreateDemuxer("opus-trimming-video-test.webm");
750   InitializeDemuxer();
751 
752   // Attempt a read from the video stream and run the message loop until done.
753   DemuxerStream* video = GetStream(DemuxerStream::VIDEO);
754   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
755   EXPECT_EQ(audio->audio_decoder_config().codec_delay(), 65535);
756 
757   // Packet size to timestamp (in microseconds) mapping for the first N packets
758   // which should be fully discarded.
759   static const int kTestExpectations[][2] = {
760       {635, 0},      {594, 120000},  {597, 240000}, {591, 360000},
761       {582, 480000}, {583, 600000},  {592, 720000}, {567, 840000},
762       {579, 960000}, {572, 1080000}, {583, 1200000}};
763 
764   // Run the test twice with a seek in between.
765   for (int i = 0; i < 2; ++i) {
766     for (size_t j = 0; j < base::size(kTestExpectations); ++j) {
767       Read(audio, FROM_HERE, kTestExpectations[j][0], kTestExpectations[j][1],
768            true);
769     }
770 
771     // Though the internal start time may be below zero, the exposed media time
772     // must always be >= zero.
773     EXPECT_EQ(base::TimeDelta(), demuxer_->GetStartTime());
774 
775     Read(video, FROM_HERE, 16009, 0, true);
776     Read(video, FROM_HERE, 2715, 1000, false);
777     Read(video, FROM_HERE, 427, 33000, false);
778 
779     // Seek back to the beginning and repeat the test.
780     WaitableMessageLoopEvent event;
781     demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB());
782     event.RunAndWaitForStatus(PIPELINE_OK);
783   }
784 }
785 
786 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
787 
788 #if defined(OS_CHROMEOS)
TEST_F(FFmpegDemuxerTest,TestAudioNegativeTimestamps)789 TEST_F(FFmpegDemuxerTest, TestAudioNegativeTimestamps) {
790   // Note: This test will _crash_ the browser if negative timestamp
791   // values are skipped, since this file is heavily truncated to avoid
792   // copyright issue. If the negative timestamp packets are dropped, the
793   // demuxer will continue to read off the end of the stream.
794   CreateDemuxer("negative-audio-timestamps.avi");
795   InitializeDemuxer();
796 
797   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
798   Read(audio, FROM_HERE, 104, 0, true);
799   Read(audio, FROM_HERE, 104, 25873, true);
800   Read(audio, FROM_HERE, 104, 51746, true);
801   Read(audio, FROM_HERE, 104, 77619, true);
802   Read(audio, FROM_HERE, 104, 103492, true);
803 }
804 #endif  // defined(OS_CHROMEOS)
805 
806 // Similar to the test above, but using an opus clip plus h264 b-frames to
807 // ensure we don't apply chained ogg workarounds to other content.
TEST_F(FFmpegDemuxerTest,Read_AudioNegativeStartTimeAndOpusDiscardH264Mp4_Sync)808 TEST_F(FFmpegDemuxerTest,
809        Read_AudioNegativeStartTimeAndOpusDiscardH264Mp4_Sync) {
810   CreateDemuxer("tos-h264-opus.mp4");
811   InitializeDemuxer();
812 
813   // Attempt a read from the video stream and run the message loop until done.
814   DemuxerStream* video = GetStream(DemuxerStream::VIDEO);
815   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
816   EXPECT_EQ(audio->audio_decoder_config().codec_delay(), 312);
817 
818   // Packet size to timestamp (in microseconds) mapping for the first N packets
819   // which should be fully discarded.
820   static const int kTestExpectations[][2] = {
821       {234, 20000}, {228, 40000}, {340, 60000}};
822 
823   // Run the test twice with a seek in between.
824   for (int i = 0; i < 2; ++i) {
825     Read(audio, FROM_HERE, 408, 0, true, DemuxerStream::Status::kOk,
826          base::TimeDelta::FromMicroseconds(6500));
827 
828     for (size_t j = 0; j < base::size(kTestExpectations); ++j) {
829       Read(audio, FROM_HERE, kTestExpectations[j][0], kTestExpectations[j][1],
830            true);
831     }
832 
833     // Though the internal start time may be below zero, the exposed media time
834     // must always be >= zero.
835     EXPECT_EQ(base::TimeDelta(), demuxer_->GetStartTime());
836 
837     Read(video, FROM_HERE, 185105, 0, true);
838     Read(video, FROM_HERE, 35941, 125000, false);
839 
840     // If things aren't working correctly, this expectation will fail because
841     // the chained ogg workaround breaks out of order timestamps.
842     Read(video, FROM_HERE, 8129, 84000, false);
843 
844     // Seek back to the beginning and repeat the test.
845     WaitableMessageLoopEvent event;
846     demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB());
847     event.RunAndWaitForStatus(PIPELINE_OK);
848   }
849 }
850 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
851 
852 // Similar to the test above, but using sfx-opus.ogg, which has a much smaller
853 // amount of discard padding and no |start_time| set on the AVStream.
TEST_F(FFmpegDemuxerTest,Read_AudioNegativeStartTimeAndOpusSfxDiscard_Sync)854 TEST_F(FFmpegDemuxerTest, Read_AudioNegativeStartTimeAndOpusSfxDiscard_Sync) {
855   CreateDemuxer("sfx-opus.ogg");
856   InitializeDemuxer();
857 
858   // Attempt a read from the video stream and run the message loop until done.
859   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
860   EXPECT_EQ(audio->audio_decoder_config().codec_delay(), 312);
861 
862   // Run the test twice with a seek in between.
863   for (int i = 0; i < 2; ++i) {
864     Read(audio, FROM_HERE, 314, 0, true);
865     Read(audio, FROM_HERE, 244, 20000, true);
866 
867     // Though the internal start time may be below zero, the exposed media time
868     // must always be >= zero.
869     EXPECT_EQ(base::TimeDelta(), demuxer_->GetStartTime());
870 
871     // Seek back to the beginning and repeat the test.
872     WaitableMessageLoopEvent event;
873     demuxer_->Seek(base::TimeDelta(), event.GetPipelineStatusCB());
874     event.RunAndWaitForStatus(PIPELINE_OK);
875   }
876 }
877 
TEST_F(FFmpegDemuxerTest,Read_DiscardDisabledVideoStream)878 TEST_F(FFmpegDemuxerTest, Read_DiscardDisabledVideoStream) {
879   // Verify that disabling the video stream properly marks it as AVDISCARD_ALL
880   // in FFmpegDemuxer. The AVDISCARD_ALL flag allows FFmpeg to ignore key frame
881   // requirements for the disabled stream and thus allows to select the seek
882   // position closer to the |seek_target|, resulting in less data being read
883   // from the data source.
884   // The input file bear-vp8-webvtt.webm has key video frames at 1.602s and at
885   // 2.002s. If we want to seek to 2.0s position while the video stream is
886   // enabled, then FFmpeg is forced to start reading from 1.602s, which is the
887   // earliest position guaranteed to give us key frames for all enabled streams.
888   // But when the video stream is disabled, FFmpeg can start reading from 1.987s
889   // which is earliest audio key frame before the 2.0s |seek_target|.
890   const base::TimeDelta seek_target = base::TimeDelta::FromMilliseconds(2000);
891 
892   CreateDemuxer("bear-vp8-webvtt.webm");
893   InitializeDemuxer();
894   Seek(seek_target);
895   Read(GetStream(DemuxerStream::AUDIO), FROM_HERE, 163, 1612000, true);
896   auto bytes_read_with_video_enabled = data_source_->bytes_read_for_testing();
897 
898   static_cast<FFmpegDemuxerStream*>(GetStream(DemuxerStream::VIDEO))
899       ->SetEnabled(false, base::TimeDelta());
900   data_source_->reset_bytes_read_for_testing();
901   Seek(seek_target);
902   Read(GetStream(DemuxerStream::AUDIO), FROM_HERE, 156, 1987000, true);
903   auto bytes_read_with_video_disabled = data_source_->bytes_read_for_testing();
904   EXPECT_LT(bytes_read_with_video_disabled, bytes_read_with_video_enabled);
905 }
906 
TEST_F(FFmpegDemuxerTest,Read_EndOfStream)907 TEST_F(FFmpegDemuxerTest, Read_EndOfStream) {
908   // Verify that end of stream buffers are created.
909   CreateDemuxer("bear-320x240.webm");
910   InitializeDemuxer();
911   ReadUntilEndOfStream(GetStream(DemuxerStream::AUDIO));
912 }
913 
TEST_F(FFmpegDemuxerTest,Read_EndOfStream_NoDuration)914 TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration) {
915   // Verify that end of stream buffers are created.
916   CreateDemuxer("bear-320x240.webm");
917   InitializeDemuxer();
918   SetDurationKnown(false);
919   EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2744)));
920   ReadUntilEndOfStream(GetStream(DemuxerStream::AUDIO));
921   ReadUntilEndOfStream(GetStream(DemuxerStream::VIDEO));
922 }
923 
TEST_F(FFmpegDemuxerTest,Read_EndOfStream_NoDuration_VideoOnly)924 TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration_VideoOnly) {
925   // Verify that end of stream buffers are created.
926   CreateDemuxer("bear-320x240-video-only.webm");
927   InitializeDemuxer();
928   SetDurationKnown(false);
929   EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2703)));
930   ReadUntilEndOfStream(GetStream(DemuxerStream::VIDEO));
931 }
932 
TEST_F(FFmpegDemuxerTest,Read_EndOfStream_NoDuration_AudioOnly)933 TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration_AudioOnly) {
934   // Verify that end of stream buffers are created.
935   CreateDemuxer("bear-320x240-audio-only.webm");
936   InitializeDemuxer();
937   SetDurationKnown(false);
938   EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2744)));
939   ReadUntilEndOfStream(GetStream(DemuxerStream::AUDIO));
940 }
941 
TEST_F(FFmpegDemuxerTest,Read_EndOfStream_NoDuration_UnsupportedStream)942 TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration_UnsupportedStream) {
943   // Verify that end of stream buffers are created and we don't crash
944   // if there are streams in the file that we don't support.
945   CreateDemuxer("vorbis_audio_wmv_video.mkv");
946   InitializeDemuxer();
947   SetDurationKnown(false);
948   EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(991)));
949   ReadUntilEndOfStream(GetStream(DemuxerStream::AUDIO));
950 }
951 
TEST_F(FFmpegDemuxerTest,Seek)952 TEST_F(FFmpegDemuxerTest, Seek) {
953   // We're testing that the demuxer frees all queued packets when it receives
954   // a Seek().
955   CreateDemuxer("bear-320x240.webm");
956   InitializeDemuxer();
957 
958   // Get our streams.
959   DemuxerStream* video = GetStream(DemuxerStream::VIDEO);
960   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
961   ASSERT_TRUE(video);
962   ASSERT_TRUE(audio);
963 
964   // Read a video packet and release it.
965   Read(video, FROM_HERE, 22084, 0, true);
966 
967   // Issue a simple forward seek, which should discard queued packets.
968   WaitableMessageLoopEvent event;
969   demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000),
970                  event.GetPipelineStatusCB());
971   event.RunAndWaitForStatus(PIPELINE_OK);
972 
973   // Audio read #1.
974   Read(audio, FROM_HERE, 145, 803000, true);
975 
976   // Audio read #2.
977   Read(audio, FROM_HERE, 148, 826000, true);
978 
979   // Video read #1.
980   Read(video, FROM_HERE, 5425, 801000, true);
981 
982   // Video read #2.
983   Read(video, FROM_HERE, 1906, 834000, false);
984 }
985 
TEST_F(FFmpegDemuxerTest,CancelledSeek)986 TEST_F(FFmpegDemuxerTest, CancelledSeek) {
987   CreateDemuxer("bear-320x240.webm");
988   InitializeDemuxer();
989 
990   // Get our streams.
991   DemuxerStream* video = GetStream(DemuxerStream::VIDEO);
992   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
993   ASSERT_TRUE(video);
994   ASSERT_TRUE(audio);
995 
996   // Read a video packet and release it.
997   Read(video, FROM_HERE, 22084, 0, true);
998 
999   // Issue a simple forward seek, which should discard queued packets.
1000   WaitableMessageLoopEvent event;
1001   demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000),
1002                  event.GetPipelineStatusCB());
1003   // FFmpegDemuxer does not care what the previous seek time was when canceling.
1004   demuxer_->CancelPendingSeek(base::TimeDelta::FromSeconds(12345));
1005   event.RunAndWaitForStatus(PIPELINE_OK);
1006 }
1007 
TEST_F(FFmpegDemuxerTest,Stop)1008 TEST_F(FFmpegDemuxerTest, Stop) {
1009   // Tests that calling Read() on a stopped demuxer stream immediately deletes
1010   // the callback.
1011   CreateDemuxer("bear-320x240.webm");
1012   InitializeDemuxer();
1013 
1014   // Get our stream.
1015   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
1016   ASSERT_TRUE(audio);
1017 
1018   demuxer_->Stop();
1019 
1020   // Reads after being stopped are all EOS buffers.
1021   StrictMock<base::MockCallback<DemuxerStream::ReadCB>> callback;
1022   EXPECT_CALL(callback, Run(DemuxerStream::kOk, IsEndOfStreamBuffer()));
1023 
1024   // Attempt the read...
1025   audio->Read(callback.Get());
1026   task_environment_.RunUntilIdle();
1027 
1028   // Don't let the test call Stop() again.
1029   demuxer_.reset();
1030 }
1031 
1032 // Verify that seek works properly when the WebM cues data is at the start of
1033 // the file instead of at the end.
TEST_F(FFmpegDemuxerTest,SeekWithCuesBeforeFirstCluster)1034 TEST_F(FFmpegDemuxerTest, SeekWithCuesBeforeFirstCluster) {
1035   CreateDemuxer("bear-320x240-cues-in-front.webm");
1036   InitializeDemuxer();
1037 
1038   // Get our streams.
1039   DemuxerStream* video = GetStream(DemuxerStream::VIDEO);
1040   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
1041   ASSERT_TRUE(video);
1042   ASSERT_TRUE(audio);
1043 
1044   // Read a video packet and release it.
1045   Read(video, FROM_HERE, 22084, 0, true);
1046 
1047   // Issue a simple forward seek, which should discard queued packets.
1048   WaitableMessageLoopEvent event;
1049   demuxer_->Seek(base::TimeDelta::FromMicroseconds(2500000),
1050                  event.GetPipelineStatusCB());
1051   event.RunAndWaitForStatus(PIPELINE_OK);
1052 
1053   // Audio read #1.
1054   Read(audio, FROM_HERE, 40, 2403000, true);
1055 
1056   // Audio read #2.
1057   Read(audio, FROM_HERE, 42, 2406000, true);
1058 
1059   // Video read #1.
1060   Read(video, FROM_HERE, 5276, 2402000, true);
1061 
1062   // Video read #2.
1063   Read(video, FROM_HERE, 1740, 2436000, false);
1064 }
1065 
1066 // Ensure ID3v1 tag reading is disabled.  id3_test.mp3 has an ID3v1 tag with the
1067 // field "title" set to "sample for id3 test".
TEST_F(FFmpegDemuxerTest,NoID3TagData)1068 TEST_F(FFmpegDemuxerTest, NoID3TagData) {
1069   CreateDemuxer("id3_test.mp3");
1070   InitializeDemuxer();
1071   EXPECT_FALSE(av_dict_get(format_context()->metadata, "title", nullptr, 0));
1072 }
1073 
1074 // Ensure MP3 files with large image/video based ID3 tags demux okay.  FFmpeg
1075 // will hand us a video stream to the data which will likely be in a format we
1076 // don't accept as video; e.g. PNG.
TEST_F(FFmpegDemuxerTest,Mp3WithVideoStreamID3TagData)1077 TEST_F(FFmpegDemuxerTest, Mp3WithVideoStreamID3TagData) {
1078   CreateDemuxerWithStrictMediaLog("id3_png_test.mp3");
1079 
1080   EXPECT_MEDIA_LOG_PROPERTY(kBitrate, 1421305);
1081   EXPECT_MEDIA_LOG_PROPERTY(kStartTime, 0.0f);
1082   EXPECT_MEDIA_LOG_PROPERTY(kVideoTracks, std::vector<VideoDecoderConfig>{});
1083   EXPECT_MEDIA_LOG_PROPERTY_ANY_VALUE(kMaxDuration);
1084   EXPECT_MEDIA_LOG_PROPERTY_ANY_VALUE(kAudioTracks);
1085   EXPECT_MEDIA_LOG(SimpleCreatedFFmpegDemuxerStream("audio"));
1086   EXPECT_MEDIA_LOG(FailedToCreateValidDecoderConfigFromStream("video"));
1087 
1088   // TODO(wolenetz): Use a matcher that verifies more of the event parameters
1089   // than FoundStream. See https://crbug.com/749178.
1090   EXPECT_MEDIA_LOG(SkippingUnsupportedStream("video"));
1091   InitializeDemuxer();
1092 
1093   // Ensure the expected streams are present.
1094   EXPECT_FALSE(GetStream(DemuxerStream::VIDEO));
1095   EXPECT_TRUE(GetStream(DemuxerStream::AUDIO));
1096 }
1097 
1098 // Ensure a video with an unsupported audio track still results in the video
1099 // stream being demuxed. Because we disable the speex parser for ogg, the audio
1100 // track won't even show up to the demuxer.
1101 //
1102 // Android has no Theora support, so this test doesn't work.
1103 #if !defined(OS_ANDROID)
TEST_F(FFmpegDemuxerTest,UnsupportedAudioSupportedVideoDemux)1104 TEST_F(FFmpegDemuxerTest, UnsupportedAudioSupportedVideoDemux) {
1105   CreateDemuxerWithStrictMediaLog("speex_audio_vorbis_video.ogv");
1106 
1107   EXPECT_MEDIA_LOG_PROPERTY(kBitrate, 398289);
1108   EXPECT_MEDIA_LOG_PROPERTY(kStartTime, 0.0f);
1109   EXPECT_MEDIA_LOG_PROPERTY(kAudioTracks, std::vector<AudioDecoderConfig>{});
1110   EXPECT_MEDIA_LOG_PROPERTY_ANY_VALUE(kVideoTracks);
1111   EXPECT_MEDIA_LOG_PROPERTY_ANY_VALUE(kMaxDuration);
1112   EXPECT_MEDIA_LOG(SimpleCreatedFFmpegDemuxerStream("video"));
1113 
1114   // TODO(wolenetz): Use a matcher that verifies more of the event parameters
1115   // than FoundStream. See https://crbug.com/749178.
1116   InitializeDemuxer();
1117 
1118   // Ensure the expected streams are present.
1119   EXPECT_TRUE(GetStream(DemuxerStream::VIDEO));
1120   EXPECT_FALSE(GetStream(DemuxerStream::AUDIO));
1121 }
1122 #endif
1123 
1124 // Ensure a video with an unsupported video track still results in the audio
1125 // stream being demuxed.
TEST_F(FFmpegDemuxerTest,UnsupportedVideoSupportedAudioDemux)1126 TEST_F(FFmpegDemuxerTest, UnsupportedVideoSupportedAudioDemux) {
1127   CreateDemuxer("vorbis_audio_wmv_video.mkv");
1128   InitializeDemuxer();
1129 
1130   // Ensure the expected streams are present.
1131   EXPECT_FALSE(GetStream(DemuxerStream::VIDEO));
1132   EXPECT_TRUE(GetStream(DemuxerStream::AUDIO));
1133 }
1134 
1135 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
1136 // FFmpeg returns null data pointers when samples have zero size, leading to
1137 // mistakenly creating end of stream buffers http://crbug.com/169133
TEST_F(FFmpegDemuxerTest,MP4_ZeroStszEntry)1138 TEST_F(FFmpegDemuxerTest, MP4_ZeroStszEntry) {
1139   CreateDemuxer("bear-1280x720-zero-stsz-entry.mp4");
1140   InitializeDemuxer();
1141   ReadUntilEndOfStream(GetStream(DemuxerStream::AUDIO));
1142 }
1143 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
1144 
1145 class Mp3SeekFFmpegDemuxerTest
1146     : public FFmpegDemuxerTest,
1147       public testing::WithParamInterface<const char*> {};
TEST_P(Mp3SeekFFmpegDemuxerTest,TestFastSeek)1148 TEST_P(Mp3SeekFFmpegDemuxerTest, TestFastSeek) {
1149   // Init demxuer with given MP3 file parameter.
1150   CreateDemuxer(GetParam());
1151   InitializeDemuxer();
1152 
1153   // We read a bunch of bytes when we first open the file. Reset the count
1154   // here to just track the bytes read for the upcoming seek. This allows us
1155   // to use a more narrow threshold for passing the test.
1156   data_source_->reset_bytes_read_for_testing();
1157 
1158   FFmpegDemuxerStream* audio =
1159       static_cast<FFmpegDemuxerStream*>(GetStream(DemuxerStream::AUDIO));
1160   ASSERT_TRUE(audio);
1161 
1162   // Seek to near the end of the file
1163   WaitableMessageLoopEvent event;
1164   demuxer_->Seek(.9 * audio->duration(), event.GetPipelineStatusCB());
1165   event.RunAndWaitForStatus(PIPELINE_OK);
1166 
1167   // Verify that seeking to the end read only a small portion of the file.
1168   // Slow seeks that read sequentially up to the seek point will read too many
1169   // bytes and fail this check.
1170   int64_t file_size = 0;
1171   ASSERT_TRUE(data_source_->GetSize(&file_size));
1172   EXPECT_LT(data_source_->bytes_read_for_testing(), (file_size * .25));
1173 }
1174 
1175 // MP3s should seek quickly without sequentially reading up to the seek point.
1176 // VBR vs CBR and the presence/absence of TOC influence the seeking algorithm.
1177 // See http://crbug.com/530043 and FFmpeg flag AVFMT_FLAG_FAST_SEEK.
1178 INSTANTIATE_TEST_SUITE_P(All,
1179                          Mp3SeekFFmpegDemuxerTest,
1180                          ::testing::Values("bear-audio-10s-CBR-has-TOC.mp3",
1181                                            "bear-audio-10s-CBR-no-TOC.mp3",
1182                                            "bear-audio-10s-VBR-has-TOC.mp3",
1183                                            "bear-audio-10s-VBR-no-TOC.mp3"));
1184 
1185 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
ValidateAnnexB(DemuxerStream * stream,DemuxerStream::Status status,scoped_refptr<DecoderBuffer> buffer)1186 static void ValidateAnnexB(DemuxerStream* stream,
1187                            DemuxerStream::Status status,
1188                            scoped_refptr<DecoderBuffer> buffer) {
1189   EXPECT_EQ(status, DemuxerStream::kOk);
1190 
1191   if (buffer->end_of_stream()) {
1192     base::ThreadTaskRunnerHandle::Get()->PostTask(
1193         FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated());
1194     return;
1195   }
1196 
1197   std::vector<SubsampleEntry> subsamples;
1198 
1199   if (buffer->decrypt_config())
1200     subsamples = buffer->decrypt_config()->subsamples();
1201 
1202   bool is_valid =
1203       mp4::AVC::AnalyzeAnnexB(buffer->data(), buffer->data_size(), subsamples)
1204           .is_conformant.value_or(false);
1205   EXPECT_TRUE(is_valid);
1206 
1207   if (!is_valid) {
1208     LOG(ERROR) << "Buffer contains invalid Annex B data.";
1209     base::ThreadTaskRunnerHandle::Get()->PostTask(
1210         FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated());
1211     return;
1212   }
1213 
1214   stream->Read(base::BindOnce(&ValidateAnnexB, stream));
1215 }
1216 
TEST_F(FFmpegDemuxerTest,IsValidAnnexB)1217 TEST_F(FFmpegDemuxerTest, IsValidAnnexB) {
1218   const char* files[] = {"bear-1280x720-av_frag.mp4",
1219                          "bear-1280x720-av_with-aud-nalus_frag.mp4"};
1220 
1221   for (size_t i = 0; i < base::size(files); ++i) {
1222     DVLOG(1) << "Testing " << files[i];
1223     CreateDemuxer(files[i]);
1224     InitializeDemuxer();
1225 
1226     // Ensure the expected streams are present.
1227     DemuxerStream* stream = GetStream(DemuxerStream::VIDEO);
1228     ASSERT_TRUE(stream);
1229     stream->EnableBitstreamConverter();
1230 
1231     stream->Read(base::BindOnce(&ValidateAnnexB, stream));
1232     base::RunLoop().Run();
1233 
1234     demuxer_->Stop();
1235     demuxer_.reset();
1236     data_source_.reset();
1237   }
1238 }
1239 
TEST_F(FFmpegDemuxerTest,Rotate_Metadata_0)1240 TEST_F(FFmpegDemuxerTest, Rotate_Metadata_0) {
1241   CreateDemuxer("bear_rotate_0.mp4");
1242   InitializeDemuxer();
1243 
1244   DemuxerStream* stream = GetStream(DemuxerStream::VIDEO);
1245   ASSERT_TRUE(stream);
1246 
1247   const VideoDecoderConfig& video_config = stream->video_decoder_config();
1248   ASSERT_EQ(VIDEO_ROTATION_0, video_config.video_transformation().rotation);
1249 }
1250 
TEST_F(FFmpegDemuxerTest,Rotate_Metadata_90)1251 TEST_F(FFmpegDemuxerTest, Rotate_Metadata_90) {
1252   CreateDemuxer("bear_rotate_90.mp4");
1253   InitializeDemuxer();
1254 
1255   DemuxerStream* stream = GetStream(DemuxerStream::VIDEO);
1256   ASSERT_TRUE(stream);
1257 
1258   const VideoDecoderConfig& video_config = stream->video_decoder_config();
1259   ASSERT_EQ(VIDEO_ROTATION_90, video_config.video_transformation().rotation);
1260 }
1261 
TEST_F(FFmpegDemuxerTest,Rotate_Metadata_180)1262 TEST_F(FFmpegDemuxerTest, Rotate_Metadata_180) {
1263   CreateDemuxer("bear_rotate_180.mp4");
1264   InitializeDemuxer();
1265 
1266   DemuxerStream* stream = GetStream(DemuxerStream::VIDEO);
1267   ASSERT_TRUE(stream);
1268 
1269   const VideoDecoderConfig& video_config = stream->video_decoder_config();
1270   ASSERT_EQ(VIDEO_ROTATION_180, video_config.video_transformation().rotation);
1271 }
1272 
TEST_F(FFmpegDemuxerTest,Rotate_Metadata_270)1273 TEST_F(FFmpegDemuxerTest, Rotate_Metadata_270) {
1274   CreateDemuxer("bear_rotate_270.mp4");
1275   InitializeDemuxer();
1276 
1277   DemuxerStream* stream = GetStream(DemuxerStream::VIDEO);
1278   ASSERT_TRUE(stream);
1279 
1280   const VideoDecoderConfig& video_config = stream->video_decoder_config();
1281   ASSERT_EQ(VIDEO_ROTATION_270, video_config.video_transformation().rotation);
1282 }
1283 
TEST_F(FFmpegDemuxerTest,NaturalSizeWithoutPASP)1284 TEST_F(FFmpegDemuxerTest, NaturalSizeWithoutPASP) {
1285   CreateDemuxer("bear-640x360-non_square_pixel-without_pasp.mp4");
1286   InitializeDemuxer();
1287 
1288   DemuxerStream* stream = GetStream(DemuxerStream::VIDEO);
1289   ASSERT_TRUE(stream);
1290 
1291   const VideoDecoderConfig& video_config = stream->video_decoder_config();
1292   EXPECT_EQ(gfx::Size(639, 360), video_config.natural_size());
1293 }
1294 
TEST_F(FFmpegDemuxerTest,NaturalSizeWithPASP)1295 TEST_F(FFmpegDemuxerTest, NaturalSizeWithPASP) {
1296   CreateDemuxer("bear-640x360-non_square_pixel-with_pasp.mp4");
1297   InitializeDemuxer();
1298 
1299   DemuxerStream* stream = GetStream(DemuxerStream::VIDEO);
1300   ASSERT_TRUE(stream);
1301 
1302   const VideoDecoderConfig& video_config = stream->video_decoder_config();
1303   EXPECT_EQ(gfx::Size(639, 360), video_config.natural_size());
1304 }
1305 
TEST_F(FFmpegDemuxerTest,HEVC_in_MP4_container)1306 TEST_F(FFmpegDemuxerTest, HEVC_in_MP4_container) {
1307   CreateDemuxer("bear-hevc-frag.mp4");
1308 #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
1309   // HEVC is not supported by default media platform. Embedders who add support
1310   // must declare it via MediaClient.
1311   MockMediaClient media_client;
1312   SetMediaClient(&media_client);
1313 
1314   VideoColorSpace color_space(VideoColorSpace::PrimaryID::SMPTE170M,
1315                               VideoColorSpace::TransferID::SMPTE170M,
1316                               VideoColorSpace::MatrixID::SMPTE170M,
1317                               gfx::ColorSpace::RangeID::LIMITED);
1318   VideoType hevc_type = {VideoCodec::kCodecHEVC,
1319                          VideoCodecProfile::HEVCPROFILE_MAIN, 10, color_space};
1320   EXPECT_CALL(media_client, IsSupportedVideoType(Eq(hevc_type)))
1321       .WillRepeatedly(Return(true));
1322 
1323   InitializeDemuxer();
1324 
1325   DemuxerStream* video = GetStream(DemuxerStream::VIDEO);
1326   ASSERT_TRUE(video);
1327 
1328   Read(video, FROM_HERE, 3569, 66733, true);
1329   Read(video, FROM_HERE, 1042, 200200, false);
1330 
1331   SetMediaClient(nullptr);
1332 #else
1333   InitializeDemuxerAndExpectPipelineStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
1334 #endif
1335 }
1336 
TEST_F(FFmpegDemuxerTest,Read_AC3_Audio)1337 TEST_F(FFmpegDemuxerTest, Read_AC3_Audio) {
1338   CreateDemuxer("bear-ac3-only-frag.mp4");
1339 #if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
1340   // AC3 is not supported by default media platform. Embedders who add support
1341   // must declare it via MediaClient.
1342   MockMediaClient media_client;
1343   SetMediaClient(&media_client);
1344 
1345   AudioType ac3_type = {AudioCodec::kCodecAC3};
1346   EXPECT_CALL(media_client, IsSupportedAudioType(Eq(ac3_type)))
1347       .WillRepeatedly(Return(true));
1348 
1349   InitializeDemuxer();
1350 
1351   // Attempt a read from the audio stream and run the message loop until done.
1352   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
1353 
1354   // Read the first two frames and check that we are getting expected data
1355   Read(audio, FROM_HERE, 834, 0, true);
1356   Read(audio, FROM_HERE, 836, 34830, true);
1357 
1358   SetMediaClient(nullptr);
1359 #else
1360   InitializeDemuxerAndExpectPipelineStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
1361 #endif
1362 }
1363 
TEST_F(FFmpegDemuxerTest,Read_EAC3_Audio)1364 TEST_F(FFmpegDemuxerTest, Read_EAC3_Audio) {
1365   CreateDemuxer("bear-eac3-only-frag.mp4");
1366 #if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
1367   // EAC3 is not supported by default media platform. Embedders who add support
1368   // must declare it via MediaClient.
1369   MockMediaClient media_client;
1370   SetMediaClient(&media_client);
1371 
1372   AudioType eac3_type = {AudioCodec::kCodecEAC3};
1373   EXPECT_CALL(media_client, IsSupportedAudioType(Eq(eac3_type)))
1374       .WillRepeatedly(Return(true));
1375 
1376   InitializeDemuxer();
1377 
1378   // Attempt a read from the audio stream and run the message loop until done.
1379   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
1380 
1381   // Read the first two frames and check that we are getting expected data
1382   Read(audio, FROM_HERE, 870, 0, true);
1383   Read(audio, FROM_HERE, 872, 34830, true);
1384 
1385   SetMediaClient(nullptr);
1386 #else
1387   InitializeDemuxerAndExpectPipelineStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
1388 #endif
1389 }
1390 
TEST_F(FFmpegDemuxerTest,Read_Mp4_Media_Track_Info)1391 TEST_F(FFmpegDemuxerTest, Read_Mp4_Media_Track_Info) {
1392   CreateDemuxer("bear.mp4");
1393   InitializeDemuxer();
1394 
1395   EXPECT_EQ(media_tracks_->tracks().size(), 2u);
1396 
1397   const MediaTrack& audio_track = *(media_tracks_->tracks()[1]);
1398   EXPECT_EQ(audio_track.type(), MediaTrack::Audio);
1399   EXPECT_EQ(audio_track.bytestream_track_id(), 2);
1400   EXPECT_EQ(audio_track.kind().value(), "main");
1401   EXPECT_EQ(audio_track.label().value(), "SoundHandler");
1402   EXPECT_EQ(audio_track.language().value(), "und");
1403 
1404   const MediaTrack& video_track = *(media_tracks_->tracks()[0]);
1405   EXPECT_EQ(video_track.type(), MediaTrack::Video);
1406   EXPECT_EQ(video_track.bytestream_track_id(), 1);
1407   EXPECT_EQ(video_track.kind().value(), "main");
1408   EXPECT_EQ(video_track.label().value(), "VideoHandler");
1409   EXPECT_EQ(video_track.language().value(), "und");
1410 }
1411 
TEST_F(FFmpegDemuxerTest,Read_Mp4_Multiple_Tracks)1412 TEST_F(FFmpegDemuxerTest, Read_Mp4_Multiple_Tracks) {
1413   CreateDemuxer("bbb-320x240-2video-2audio.mp4");
1414   InitializeDemuxer();
1415 
1416   EXPECT_EQ(media_tracks_->tracks().size(), 4u);
1417 
1418   const MediaTrack& video_track = *(media_tracks_->tracks()[0]);
1419   EXPECT_EQ(video_track.type(), MediaTrack::Video);
1420   EXPECT_EQ(video_track.bytestream_track_id(), 1);
1421   EXPECT_EQ(video_track.kind().value(), "main");
1422   EXPECT_EQ(video_track.label().value(), "VideoHandler");
1423   EXPECT_EQ(video_track.language().value(), "und");
1424 
1425   const MediaTrack& audio_track = *(media_tracks_->tracks()[1]);
1426   EXPECT_EQ(audio_track.type(), MediaTrack::Audio);
1427   EXPECT_EQ(audio_track.bytestream_track_id(), 2);
1428   EXPECT_EQ(audio_track.kind().value(), "main");
1429   EXPECT_EQ(audio_track.label().value(), "SoundHandler");
1430   EXPECT_EQ(audio_track.language().value(), "und");
1431 
1432   const MediaTrack& video_track2 = *(media_tracks_->tracks()[2]);
1433   EXPECT_EQ(video_track2.type(), MediaTrack::Video);
1434   EXPECT_EQ(video_track2.bytestream_track_id(), 3);
1435   EXPECT_EQ(video_track2.kind().value(), "main");
1436   EXPECT_EQ(video_track2.label().value(), "VideoHandler");
1437   EXPECT_EQ(video_track2.language().value(), "und");
1438 
1439   const MediaTrack& audio_track2 = *(media_tracks_->tracks()[3]);
1440   EXPECT_EQ(audio_track2.type(), MediaTrack::Audio);
1441   EXPECT_EQ(audio_track2.bytestream_track_id(), 4);
1442   EXPECT_EQ(audio_track2.kind().value(), "main");
1443   EXPECT_EQ(audio_track2.label().value(), "SoundHandler");
1444   EXPECT_EQ(audio_track2.language().value(), "und");
1445 }
1446 
TEST_F(FFmpegDemuxerTest,Read_Mp4_Crbug657437)1447 TEST_F(FFmpegDemuxerTest, Read_Mp4_Crbug657437) {
1448   CreateDemuxer("crbug657437.mp4");
1449   InitializeDemuxer();
1450 }
1451 
TEST_F(FFmpegDemuxerTest,XHE_AAC)1452 TEST_F(FFmpegDemuxerTest, XHE_AAC) {
1453   CreateDemuxer("noise-xhe-aac.mp4");
1454   InitializeDemuxer();
1455 
1456   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
1457   ASSERT_TRUE(audio);
1458 
1459   EXPECT_EQ(audio->audio_decoder_config().profile(),
1460             AudioCodecProfile::kXHE_AAC);
1461 
1462   // ADTS bitstream conversion shouldn't be enabled for xHE-AAC since it can't
1463   // be represented with only two bits for the profile.
1464   audio->EnableBitstreamConverter();
1465   EXPECT_FALSE(HasBitstreamConverter(audio));
1466 
1467   // Even though FFmpeg can't decode xHE-AAC content, it should be demuxing it
1468   // just fine.
1469   Read(audio, FROM_HERE, 1796, 0, true);
1470 }
1471 
1472 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
1473 
TEST_F(FFmpegDemuxerTest,Read_Webm_Multiple_Tracks)1474 TEST_F(FFmpegDemuxerTest, Read_Webm_Multiple_Tracks) {
1475   CreateDemuxer("multitrack-3video-2audio.webm");
1476   InitializeDemuxer();
1477 
1478   EXPECT_EQ(media_tracks_->tracks().size(), 5u);
1479 
1480   const MediaTrack& video_track1 = *(media_tracks_->tracks()[0]);
1481   EXPECT_EQ(video_track1.type(), MediaTrack::Video);
1482   EXPECT_EQ(video_track1.bytestream_track_id(), 1);
1483 
1484   const MediaTrack& video_track2 = *(media_tracks_->tracks()[1]);
1485   EXPECT_EQ(video_track2.type(), MediaTrack::Video);
1486   EXPECT_EQ(video_track2.bytestream_track_id(), 2);
1487 
1488   const MediaTrack& video_track3 = *(media_tracks_->tracks()[2]);
1489   EXPECT_EQ(video_track3.type(), MediaTrack::Video);
1490   EXPECT_EQ(video_track3.bytestream_track_id(), 3);
1491 
1492   const MediaTrack& audio_track1 = *(media_tracks_->tracks()[3]);
1493   EXPECT_EQ(audio_track1.type(), MediaTrack::Audio);
1494   EXPECT_EQ(audio_track1.bytestream_track_id(), 4);
1495 
1496   const MediaTrack& audio_track2 = *(media_tracks_->tracks()[4]);
1497   EXPECT_EQ(audio_track2.type(), MediaTrack::Audio);
1498   EXPECT_EQ(audio_track2.bytestream_track_id(), 5);
1499 }
1500 
TEST_F(FFmpegDemuxerTest,Read_Webm_Media_Track_Info)1501 TEST_F(FFmpegDemuxerTest, Read_Webm_Media_Track_Info) {
1502   CreateDemuxer("bear.webm");
1503   InitializeDemuxer();
1504 
1505   EXPECT_EQ(media_tracks_->tracks().size(), 2u);
1506 
1507   const MediaTrack& video_track = *(media_tracks_->tracks()[0]);
1508   EXPECT_EQ(video_track.type(), MediaTrack::Video);
1509   EXPECT_EQ(video_track.bytestream_track_id(), 1);
1510   EXPECT_EQ(video_track.kind().value(), "main");
1511   EXPECT_EQ(video_track.label().value(), "");
1512   EXPECT_EQ(video_track.language().value(), "");
1513 
1514   const MediaTrack& audio_track = *(media_tracks_->tracks()[1]);
1515   EXPECT_EQ(audio_track.type(), MediaTrack::Audio);
1516   EXPECT_EQ(audio_track.bytestream_track_id(), 2);
1517   EXPECT_EQ(audio_track.kind().value(), "main");
1518   EXPECT_EQ(audio_track.label().value(), "");
1519   EXPECT_EQ(audio_track.language().value(), "");
1520 }
1521 
1522 // UTCDateToTime_* tests here assume FFmpegDemuxer's ExtractTimelineOffset
1523 // helper uses base::Time::FromUTCString() for conversion.
TEST_F(FFmpegDemuxerTest,UTCDateToTime_Valid)1524 TEST_F(FFmpegDemuxerTest, UTCDateToTime_Valid) {
1525   base::Time result;
1526   EXPECT_TRUE(
1527       base::Time::FromUTCString("2012-11-10T12:34:56.987654Z", &result));
1528 
1529   base::Time::Exploded exploded;
1530   result.UTCExplode(&exploded);
1531   EXPECT_TRUE(exploded.HasValidValues());
1532   EXPECT_EQ(2012, exploded.year);
1533   EXPECT_EQ(11, exploded.month);
1534   EXPECT_EQ(6, exploded.day_of_week);
1535   EXPECT_EQ(10, exploded.day_of_month);
1536   EXPECT_EQ(12, exploded.hour);
1537   EXPECT_EQ(34, exploded.minute);
1538   EXPECT_EQ(56, exploded.second);
1539   EXPECT_EQ(987, exploded.millisecond);
1540 
1541   // base::Time exploding operations round fractional milliseconds down, so
1542   // verify fractional milliseconds using a base::TimeDelta.
1543   base::Time without_fractional_ms;
1544   EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &without_fractional_ms));
1545   base::TimeDelta delta = result - without_fractional_ms;
1546   EXPECT_EQ(654, delta.InMicroseconds());
1547 }
1548 
TEST_F(FFmpegDemuxerTest,UTCDateToTime_Invalid)1549 TEST_F(FFmpegDemuxerTest, UTCDateToTime_Invalid) {
1550   const char* invalid_date_strings[] = {
1551       "",
1552       "12:34:56",
1553       "-- ::",
1554       "2012-11- 12:34:56",
1555       "2012--10 12:34:56",
1556       "-11-10 12:34:56",
1557       "2012-11 12:34:56",
1558       "ABCD-11-10 12:34:56",
1559       "2012-EF-10 12:34:56",
1560       "2012-11-GH 12:34:56",
1561       "2012-11-1012:34:56",
1562   };
1563 
1564   for (size_t i = 0; i < base::size(invalid_date_strings); ++i) {
1565     const char* date_string = invalid_date_strings[i];
1566     base::Time result;
1567     EXPECT_FALSE(base::Time::FromUTCString(date_string, &result))
1568         << "date_string '" << date_string << "'";
1569   }
1570 }
1571 
VerifyFlacStream(DemuxerStream * stream,int expected_bits_per_channel,ChannelLayout expected_channel_layout,int expected_samples_per_second,SampleFormat expected_sample_format)1572 static void VerifyFlacStream(DemuxerStream* stream,
1573                              int expected_bits_per_channel,
1574                              ChannelLayout expected_channel_layout,
1575                              int expected_samples_per_second,
1576                              SampleFormat expected_sample_format) {
1577   ASSERT_TRUE(stream);
1578   EXPECT_EQ(DemuxerStream::AUDIO, stream->type());
1579 
1580   const AudioDecoderConfig& audio_config = stream->audio_decoder_config();
1581   EXPECT_EQ(kCodecFLAC, audio_config.codec());
1582   EXPECT_EQ(expected_bits_per_channel, audio_config.bits_per_channel());
1583   EXPECT_EQ(expected_channel_layout, audio_config.channel_layout());
1584   EXPECT_EQ(expected_samples_per_second, audio_config.samples_per_second());
1585   EXPECT_EQ(expected_sample_format, audio_config.sample_format());
1586 }
1587 
TEST_F(FFmpegDemuxerTest,Read_Flac)1588 TEST_F(FFmpegDemuxerTest, Read_Flac) {
1589   CreateDemuxer("sfx.flac");
1590   InitializeDemuxer();
1591 
1592   // Video stream should not be present.
1593   EXPECT_EQ(nullptr, GetStream(DemuxerStream::VIDEO));
1594 
1595   VerifyFlacStream(GetStream(DemuxerStream::AUDIO), 32, CHANNEL_LAYOUT_MONO,
1596                    44100, kSampleFormatS32);
1597 }
1598 
TEST_F(FFmpegDemuxerTest,Read_Flac_Mp4)1599 TEST_F(FFmpegDemuxerTest, Read_Flac_Mp4) {
1600   CreateDemuxer("bear-flac.mp4");
1601   InitializeDemuxer();
1602 
1603   // Video stream should not be present.
1604   EXPECT_EQ(nullptr, GetStream(DemuxerStream::VIDEO));
1605 
1606   VerifyFlacStream(GetStream(DemuxerStream::AUDIO), 32, CHANNEL_LAYOUT_STEREO,
1607                    44100, kSampleFormatS32);
1608 }
1609 
TEST_F(FFmpegDemuxerTest,Read_Flac_192kHz_Mp4)1610 TEST_F(FFmpegDemuxerTest, Read_Flac_192kHz_Mp4) {
1611   CreateDemuxer("bear-flac-192kHz.mp4");
1612   InitializeDemuxer();
1613 
1614   // Video stream should not be present.
1615   EXPECT_EQ(nullptr, GetStream(DemuxerStream::VIDEO));
1616 
1617   VerifyFlacStream(GetStream(DemuxerStream::AUDIO), 32, CHANNEL_LAYOUT_STEREO,
1618                    192000, kSampleFormatS32);
1619 }
1620 
1621 // Verify that FFmpeg demuxer falls back to choosing disabled streams for
1622 // seeking if there's no suitable enabled stream found.
TEST_F(FFmpegDemuxerTest,Seek_FallbackToDisabledVideoStream)1623 TEST_F(FFmpegDemuxerTest, Seek_FallbackToDisabledVideoStream) {
1624   // Input has only video stream, no audio.
1625   CreateDemuxer("bear-320x240-video-only.webm");
1626   InitializeDemuxer();
1627   EXPECT_EQ(nullptr, GetStream(DemuxerStream::AUDIO));
1628   FFmpegDemuxerStream* vstream =
1629       static_cast<FFmpegDemuxerStream*>(GetStream(DemuxerStream::VIDEO));
1630   EXPECT_NE(nullptr, vstream);
1631   EXPECT_EQ(vstream, preferred_seeking_stream(base::TimeDelta()));
1632 
1633   // Now pretend that video stream got disabled, e.g. due to current tab going
1634   // into background.
1635   vstream->SetEnabled(false, base::TimeDelta());
1636   // Since there's no other enabled streams, the preferred seeking stream should
1637   // still be the video stream.
1638   EXPECT_EQ(vstream, preferred_seeking_stream(base::TimeDelta()));
1639 }
1640 
TEST_F(FFmpegDemuxerTest,Seek_FallbackToDisabledAudioStream)1641 TEST_F(FFmpegDemuxerTest, Seek_FallbackToDisabledAudioStream) {
1642   CreateDemuxer("bear-320x240-audio-only.webm");
1643   InitializeDemuxer();
1644   FFmpegDemuxerStream* astream =
1645       static_cast<FFmpegDemuxerStream*>(GetStream(DemuxerStream::AUDIO));
1646   EXPECT_NE(nullptr, astream);
1647   EXPECT_EQ(nullptr, GetStream(DemuxerStream::VIDEO));
1648   EXPECT_EQ(astream, preferred_seeking_stream(base::TimeDelta()));
1649 
1650   // Now pretend that audio stream got disabled.
1651   astream->SetEnabled(false, base::TimeDelta());
1652   // Since there's no other enabled streams, the preferred seeking stream should
1653   // still be the audio stream.
1654   EXPECT_EQ(astream, preferred_seeking_stream(base::TimeDelta()));
1655 }
1656 
1657 namespace {
QuitLoop(base::Closure quit_closure,DemuxerStream::Type type,const std::vector<DemuxerStream * > & streams)1658 void QuitLoop(base::Closure quit_closure,
1659               DemuxerStream::Type type,
1660               const std::vector<DemuxerStream*>& streams) {
1661   quit_closure.Run();
1662 }
1663 
DisableAndEnableDemuxerTracks(FFmpegDemuxer * demuxer,base::test::TaskEnvironment * task_environment)1664 void DisableAndEnableDemuxerTracks(
1665     FFmpegDemuxer* demuxer,
1666     base::test::TaskEnvironment* task_environment) {
1667   base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1668                             base::WaitableEvent::InitialState::NOT_SIGNALED);
1669   std::vector<MediaTrack::Id> audio_tracks;
1670   std::vector<MediaTrack::Id> video_tracks;
1671 
1672   base::RunLoop disable_video;
1673   demuxer->OnSelectedVideoTrackChanged(
1674       video_tracks, base::TimeDelta(),
1675       base::BindOnce(QuitLoop, disable_video.QuitClosure()));
1676   disable_video.Run();
1677 
1678   base::RunLoop disable_audio;
1679   demuxer->OnEnabledAudioTracksChanged(
1680       audio_tracks, base::TimeDelta(),
1681       base::BindOnce(QuitLoop, disable_audio.QuitClosure()));
1682   disable_audio.Run();
1683 
1684   base::RunLoop enable_video;
1685   video_tracks.push_back(MediaTrack::Id("1"));
1686   demuxer->OnSelectedVideoTrackChanged(
1687       video_tracks, base::TimeDelta(),
1688       base::BindOnce(QuitLoop, enable_video.QuitClosure()));
1689   enable_video.Run();
1690 
1691   base::RunLoop enable_audio;
1692   audio_tracks.push_back(MediaTrack::Id("2"));
1693   demuxer->OnEnabledAudioTracksChanged(
1694       audio_tracks, base::TimeDelta(),
1695       base::BindOnce(QuitLoop, enable_audio.QuitClosure()));
1696   enable_audio.Run();
1697 
1698   task_environment->RunUntilIdle();
1699 }
1700 
OnReadDoneExpectEos(DemuxerStream::Status status,const scoped_refptr<DecoderBuffer> buffer)1701 void OnReadDoneExpectEos(DemuxerStream::Status status,
1702                          const scoped_refptr<DecoderBuffer> buffer) {
1703   EXPECT_EQ(status, DemuxerStream::kOk);
1704   EXPECT_TRUE(buffer->end_of_stream());
1705 }
1706 }  // namespace
1707 
TEST_F(FFmpegDemuxerTest,StreamStatusNotifications)1708 TEST_F(FFmpegDemuxerTest, StreamStatusNotifications) {
1709   CreateDemuxer("bear-320x240.webm");
1710   InitializeDemuxer();
1711   FFmpegDemuxerStream* audio_stream =
1712       static_cast<FFmpegDemuxerStream*>(GetStream(DemuxerStream::AUDIO));
1713   EXPECT_NE(nullptr, audio_stream);
1714   FFmpegDemuxerStream* video_stream =
1715       static_cast<FFmpegDemuxerStream*>(GetStream(DemuxerStream::VIDEO));
1716   EXPECT_NE(nullptr, video_stream);
1717 
1718   // Verify stream status notifications delivery without pending read first.
1719   DisableAndEnableDemuxerTracks(demuxer_.get(), &task_environment_);
1720 
1721   // Verify that stream notifications are delivered properly when stream status
1722   // changes with a pending read. Call FlushBuffers before reading, to ensure
1723   // there is no buffers ready to be returned by the Read right away, thus
1724   // ensuring that status changes occur while an async read is pending.
1725 
1726   audio_stream->FlushBuffers(true);
1727   video_stream->FlushBuffers(true);
1728   audio_stream->Read(base::BindOnce(&OnReadDoneExpectEos));
1729   video_stream->Read(base::BindOnce(&OnReadDoneExpectEos));
1730 
1731   DisableAndEnableDemuxerTracks(demuxer_.get(), &task_environment_);
1732 }
1733 
TEST_F(FFmpegDemuxerTest,MultitrackMemoryUsage)1734 TEST_F(FFmpegDemuxerTest, MultitrackMemoryUsage) {
1735   CreateDemuxer("multitrack-3video-2audio.webm");
1736   InitializeDemuxer();
1737 
1738   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
1739 
1740   // Read from the audio stream to make sure FFmpegDemuxer buffers data for all
1741   // streams with available capacity, i.e all enabled streams. By default only
1742   // the first audio and the first video stream are enabled, so the memory usage
1743   // shouldn't be too high.
1744   Read(audio, FROM_HERE, 304, 0, true);
1745   EXPECT_EQ(22134, demuxer_->GetMemoryUsage());
1746 
1747   // Now enable all demuxer streams in the file and perform another read, this
1748   // will buffer the data for additional streams and memory usage will increase.
1749   std::vector<DemuxerStream*> streams = demuxer_->GetAllStreams();
1750   for (auto* stream : streams) {
1751     static_cast<FFmpegDemuxerStream*>(stream)->SetEnabled(true,
1752                                                           base::TimeDelta());
1753   }
1754   Read(audio, FROM_HERE, 166, 21000, true);
1755 
1756   // With newly enabled demuxer streams the amount of memory used by the demuxer
1757   // is much higher.
1758   EXPECT_EQ(156011, demuxer_->GetMemoryUsage());
1759 }
1760 
TEST_F(FFmpegDemuxerTest,SeekOnVideoTrackChangeWontSeekIfEmpty)1761 TEST_F(FFmpegDemuxerTest, SeekOnVideoTrackChangeWontSeekIfEmpty) {
1762   // We only care about video tracks.
1763   CreateDemuxer("bear-320x240-video-only.webm");
1764   InitializeDemuxer();
1765   std::vector<DemuxerStream*> streams;
1766   base::RunLoop loop;
1767 
1768   SeekOnVideoTrackChangePassthrough(
1769       base::TimeDelta(), base::BindOnce(QuitLoop, loop.QuitClosure()),
1770       DemuxerStream::VIDEO, streams);
1771 
1772   loop.Run();
1773 }
1774 
1775 }  // namespace media
1776