15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/logging.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/decrypt_config.h"
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "media/base/media_log.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/mock_demuxer_host.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/test_helpers.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/ffmpeg/ffmpeg_common.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/ffmpeg_demuxer.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/file_data_source.h"
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "media/formats/mp4/avc.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/webm/webm_crypto_helpers.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::AnyNumber;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::DoAll;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::Exactly;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::InSequence;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Invoke;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::NotNull;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Return;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::SaveArg;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::SetArgPointee;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::StrictMock;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::WithArgs;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::_;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MATCHER(IsEndOfStreamBuffer,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string(negation ? "isn't" : "is") + " end of stream") {
42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return arg->end_of_stream();
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void EosOnReadDone(bool* got_eos_buffer,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          DemuxerStream::Status status,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const scoped_refptr<DecoderBuffer>& buffer) {
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(status, DemuxerStream::kOk);
52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (buffer->end_of_stream()) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *got_eos_buffer = true;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_TRUE(buffer->data());
58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_GT(buffer->data_size(), 0);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *got_eos_buffer = false;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fixture class to facilitate writing tests.  Takes care of setting up the
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FFmpeg, pipeline and filter host mocks.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FFmpegDemuxerTest : public testing::Test {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FFmpegDemuxerTest() {}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~FFmpegDemuxerTest() {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (demuxer_) {
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      WaitableMessageLoopEvent event;
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      demuxer_->Stop(event.GetClosure());
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      event.RunAndWait();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateDemuxer(const std::string& name) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!demuxer_);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber());
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateDataSource(name);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    Demuxer::NeedKeyCB need_key_cb =
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&FFmpegDemuxerTest::NeedKeyCB, base::Unretained(this));
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    demuxer_.reset(new FFmpegDemuxer(message_loop_.message_loop_proxy(),
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                     data_source_.get(),
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                     need_key_cb,
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                     new MediaLog()));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(CheckPoint, void(int v));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
952f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  void InitializeDemuxerText(bool enable_text) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(host_, SetDuration(_));
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WaitableMessageLoopEvent event;
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), enable_text);
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event.RunAndWaitForStatus(PIPELINE_OK);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void InitializeDemuxer() {
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    InitializeDemuxerText(false);
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(OnReadDoneCalled, void(int, int64));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verifies that |buffer| has a specific |size| and |timestamp|.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |location| simply indicates where the call to this function was made.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This makes it easier to track down where test failures occur.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnReadDone(const tracked_objects::Location& location,
1122f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                  int size, int64 timestampInMicroseconds,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  DemuxerStream::Status status,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const scoped_refptr<DecoderBuffer>& buffer) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string location_str;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    location.Write(true, false, &location_str);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    location_str += "\n";
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(location_str);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(status, DemuxerStream::kOk);
1202f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    OnReadDoneCalled(size, timestampInMicroseconds);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(buffer.get() != NULL);
122ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_EQ(size, buffer->data_size());
1232f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    EXPECT_EQ(base::TimeDelta::FromMicroseconds(timestampInMicroseconds),
1242f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)              buffer->timestamp());
1252f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_EQ(&message_loop_, base::MessageLoop::current());
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DemuxerStream::ReadCB NewReadCB(const tracked_objects::Location& location,
1312f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                                  int size, int64 timestampInMicroseconds) {
1322f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    EXPECT_CALL(*this, OnReadDoneCalled(size, timestampInMicroseconds));
1332f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    return base::Bind(&FFmpegDemuxerTest::OnReadDone, base::Unretained(this),
1342f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                      location, size, timestampInMicroseconds);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(xhwang): This is a workaround of the issue that move-only parameters
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // are not supported in mocked methods. Remove this when the issue is fixed
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (http://code.google.com/p/googletest/issues/detail?id=395) or when we use
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // std::string instead of scoped_ptr<uint8[]> (http://crbug.com/130689).
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD3(NeedKeyCBMock, void(const std::string& type,
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   const uint8* init_data, int init_data_size));
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void NeedKeyCB(const std::string& type,
144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 const std::vector<uint8>& init_data) {
145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const uint8* init_data_ptr = init_data.empty() ? NULL : &init_data[0];
146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    NeedKeyCBMock(type, init_data_ptr, init_data.size());
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Accessor to demuxer internals.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_duration_known(bool duration_known) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    demuxer_->duration_known_ = duration_known;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsStreamStopped(DemuxerStream::Type type) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DemuxerStream* stream = demuxer_->GetStream(type);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(stream);
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return !static_cast<FFmpegDemuxerStream*>(stream)->demuxer_;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fixture members.
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<FileDataSource> data_source_;
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<FFmpegDemuxer> demuxer_;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StrictMock<MockDemuxerHost> host_;
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop_;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AVFormatContext* format_context() {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return demuxer_->glue_->format_context();
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ReadUntilEndOfStream(DemuxerStream* stream) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool got_eos_buffer = false;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kMaxBuffers = 170;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; !got_eos_buffer && i < kMaxBuffers; i++) {
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      stream->Read(base::Bind(&EosOnReadDone, &got_eos_buffer));
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      message_loop_.Run();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(got_eos_buffer);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CreateDataSource(const std::string& name) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!data_source_);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath file_path;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &file_path));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_path = file_path.Append(FILE_PATH_LITERAL("media"))
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .Append(FILE_PATH_LITERAL("test"))
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .Append(FILE_PATH_LITERAL("data"))
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .AppendASCII(name);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    data_source_.reset(new FileDataSource());
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(data_source_->Initialize(file_path));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate avformat_open_input() failing.
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateDemuxer("ten_byte_file");
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitableMessageLoopEvent event;
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), true);
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  event.RunAndWaitForStatus(DEMUXER_ERROR_COULD_NOT_OPEN);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(acolwell): Uncomment this test when we discover a file that passes
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// avformat_open_input(), but has avformat_find_stream_info() fail.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) {
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//  ("find_stream_info_fail.webm");
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  demuxer_->Initialize(
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE));
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//  message_loop_.RunUntilIdle();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open a file with no streams whatsoever.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("no_streams.webm");
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitableMessageLoopEvent event;
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), true);
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open a file containing streams but none of which are audio/video streams.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("no_audio_video.webm");
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitableMessageLoopEvent event;
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), true);
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_Successful) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("bear-320x240.webm");
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeDemuxer();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video stream should be present.
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(stream);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(DemuxerStream::VIDEO, stream->type());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const VideoDecoderConfig& video_config = stream->video_decoder_config();
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kCodecVP8, video_config.codec());
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(VideoFrame::YV12, video_config.format());
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(320, video_config.coded_size().width());
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(240, video_config.coded_size().height());
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, video_config.visible_rect().x());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, video_config.visible_rect().y());
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(320, video_config.visible_rect().width());
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(240, video_config.visible_rect().height());
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(320, video_config.natural_size().width());
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(240, video_config.natural_size().height());
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(video_config.extra_data());
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, video_config.extra_data_size());
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio stream should be present.
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  stream = demuxer_->GetStream(DemuxerStream::AUDIO);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(stream);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(DemuxerStream::AUDIO, stream->type());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const AudioDecoderConfig& audio_config = stream->audio_decoder_config();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kCodecVorbis, audio_config.codec());
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(32, audio_config.bits_per_channel());
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CHANNEL_LAYOUT_STEREO, audio_config.channel_layout());
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(44100, audio_config.samples_per_second());
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kSampleFormatPlanarF32, audio_config.sample_format());
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_config.extra_data());
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(audio_config.extra_data_size(), 0u);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unknown stream should never be present.
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN));
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_Multitrack) {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open a file containing the following streams:
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   Stream #0: Video (VP8)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   Stream #1: Audio (Vorbis)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   Stream #2: Subtitles (SRT)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   Stream #3: Video (Theora)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   Stream #4: Audio (16-bit signed little endian PCM)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should only pick the first audio/video streams we come across.
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("bear-320x240-multitrack.webm");
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeDemuxer();
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video stream should be VP8.
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(stream);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(DemuxerStream::VIDEO, stream->type());
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kCodecVP8, stream->video_decoder_config().codec());
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio stream should be Vorbis.
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  stream = demuxer_->GetStream(DemuxerStream::AUDIO);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(stream);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(DemuxerStream::AUDIO, stream->type());
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec());
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unknown stream should never be present.
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN));
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_MultitrackText) {
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Open a file containing the following streams:
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //   Stream #0: Video (VP8)
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //   Stream #1: Audio (Vorbis)
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //   Stream #2: Text (WebVTT)
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateDemuxer("bear-vp8-webvtt.webm");
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DemuxerStream* text_stream = NULL;
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _))
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .WillOnce(SaveArg<0>(&text_stream));
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeDemuxerText(true);
314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(text_stream);
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::TEXT, text_stream->type());
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Video stream should be VP8.
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(stream);
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::VIDEO, stream->type());
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(kCodecVP8, stream->video_decoder_config().codec());
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Audio stream should be Vorbis.
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  stream = demuxer_->GetStream(DemuxerStream::AUDIO);
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(stream);
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::AUDIO, stream->type());
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec());
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Unknown stream should never be present.
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN));
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_Encrypted) {
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, NeedKeyCBMock(kWebMEncryptInitDataType, NotNull(),
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   DecryptConfig::kDecryptionKeySize))
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(Exactly(2));
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateDemuxer("bear-320x240-av_enc-av.webm");
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeDemuxer();
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_Audio) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We test that on a successful audio packet read.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("bear-320x240.webm");
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeDemuxer();
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt a read from the audio stream and run the message loop until done.
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  audio->Read(NewReadCB(FROM_HERE, 29, 0));
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  audio->Read(NewReadCB(FROM_HERE, 27, 3000));
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_Video) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We test that on a successful video packet read.
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("bear-320x240.webm");
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeDemuxer();
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt a read from the video stream and run the message loop until done.
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video->Read(NewReadCB(FROM_HERE, 22084, 0));
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video->Read(NewReadCB(FROM_HERE, 1057, 33000));
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_Text) {
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // We test that on a successful text packet read.
374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateDemuxer("bear-vp8-webvtt.webm");
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DemuxerStream* text_stream = NULL;
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _))
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .WillOnce(SaveArg<0>(&text_stream));
378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeDemuxerText(true);
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(text_stream);
380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::TEXT, text_stream->type());
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  text_stream->Read(NewReadCB(FROM_HERE, 31, 0));
383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message_loop_.Run();
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  text_stream->Read(NewReadCB(FROM_HERE, 19, 500000));
386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message_loop_.Run();
387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3892f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_VideoNonZeroStart) {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the start time is the first timestamp of the video and audio stream.
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("nonzero-start-time.webm");
3922f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  InitializeDemuxer();
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt a read from the video stream and run the message loop until done.
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3982f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  // Check first buffer in video stream.
3992f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  video->Read(NewReadCB(FROM_HERE, 5636, 400000));
4002f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  message_loop_.Run();
401f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
4022f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  // Check first buffer in audio stream.
4032f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  audio->Read(NewReadCB(FROM_HERE, 165, 396000));
4042f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  message_loop_.Run();
405f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
4062f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  // Verify that the start time is equal to the lowest timestamp (ie the audio).
4072f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  EXPECT_EQ(demuxer_->GetStartTime().InMicroseconds(), 396000);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_EndOfStream) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that end of stream buffers are created.
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("bear-320x240.webm");
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeDemuxer();
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::AUDIO));
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_EndOfStreamText) {
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Verify that end of stream buffers are created.
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateDemuxer("bear-vp8-webvtt.webm");
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DemuxerStream* text_stream = NULL;
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _))
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .WillOnce(SaveArg<0>(&text_stream));
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeDemuxerText(true);
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(text_stream);
425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::TEXT, text_stream->type());
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool got_eos_buffer = false;
428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int kMaxBuffers = 10;
429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (int i = 0; !got_eos_buffer && i < kMaxBuffers; i++) {
430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    text_stream->Read(base::Bind(&EosOnReadDone, &got_eos_buffer));
431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    message_loop_.Run();
432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(got_eos_buffer);
435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that end of stream buffers are created.
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateDemuxer("bear-320x240.webm");
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeDemuxer();
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_duration_known(false);
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2767)));
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::AUDIO));
4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::VIDEO));
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration_VideoOnly) {
4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify that end of stream buffers are created.
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CreateDemuxer("bear-320x240-video-only.webm");
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitializeDemuxer();
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  set_duration_known(false);
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2703)));
4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::VIDEO));
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration_AudioOnly) {
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify that end of stream buffers are created.
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CreateDemuxer("bear-320x240-audio-only.webm");
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitializeDemuxer();
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  set_duration_known(false);
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2767)));
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::AUDIO));
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration_UnsupportedStream) {
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify that end of stream buffers are created and we don't crash
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // if there are streams in the file that we don't support.
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CreateDemuxer("vorbis_audio_wmv_video.mkv");
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitializeDemuxer();
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  set_duration_known(false);
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(1014)));
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::AUDIO));
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Seek) {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We're testing that the demuxer frees all queued packets when it receives
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a Seek().
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("bear-320x240.webm");
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeDemuxer();
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get our streams.
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(video);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(audio);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read a video packet and release it.
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video->Read(NewReadCB(FROM_HERE, 22084, 0));
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue a simple forward seek, which should discard queued packets.
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitableMessageLoopEvent event;
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000),
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 event.GetPipelineStatusCB());
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  event.RunAndWaitForStatus(PIPELINE_OK);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio read #1.
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  audio->Read(NewReadCB(FROM_HERE, 145, 803000));
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio read #2.
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  audio->Read(NewReadCB(FROM_HERE, 148, 826000));
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video read #1.
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video->Read(NewReadCB(FROM_HERE, 5425, 801000));
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video read #2.
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video->Read(NewReadCB(FROM_HERE, 1906, 834000));
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, SeekText) {
515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // We're testing that the demuxer frees all queued packets when it receives
516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // a Seek().
517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateDemuxer("bear-vp8-webvtt.webm");
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DemuxerStream* text_stream = NULL;
519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _))
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .WillOnce(SaveArg<0>(&text_stream));
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeDemuxerText(true);
522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(text_stream);
523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::TEXT, text_stream->type());
524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Get our streams.
526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(video);
529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(audio);
530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Read a text packet and release it.
532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  text_stream->Read(NewReadCB(FROM_HERE, 31, 0));
533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message_loop_.Run();
534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Issue a simple forward seek, which should discard queued packets.
536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WaitableMessageLoopEvent event;
537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000),
538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 event.GetPipelineStatusCB());
539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event.RunAndWaitForStatus(PIPELINE_OK);
540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Audio read #1.
542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  audio->Read(NewReadCB(FROM_HERE, 145, 803000));
543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message_loop_.Run();
544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Audio read #2.
546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  audio->Read(NewReadCB(FROM_HERE, 148, 826000));
547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message_loop_.Run();
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Video read #1.
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  video->Read(NewReadCB(FROM_HERE, 5425, 801000));
551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message_loop_.Run();
552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Video read #2.
554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  video->Read(NewReadCB(FROM_HERE, 1906, 834000));
555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message_loop_.Run();
556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Text read #1.
558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  text_stream->Read(NewReadCB(FROM_HERE, 19, 500000));
559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message_loop_.Run();
560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Text read #2.
562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  text_stream->Read(NewReadCB(FROM_HERE, 19, 1000000));
563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message_loop_.Run();
564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockReadCB {
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockReadCB() {}
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ~MockReadCB() {}
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(Run, void(DemuxerStream::Status status,
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const scoped_refptr<DecoderBuffer>& buffer));
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockReadCB);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Stop) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tests that calling Read() on a stopped demuxer stream immediately deletes
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the callback.
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("bear-320x240.webm");
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeDemuxer();
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get our stream.
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(audio);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  WaitableMessageLoopEvent event;
5883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  demuxer_->Stop(event.GetClosure());
5893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  event.RunAndWait();
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Reads after being stopped are all EOS buffers.
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StrictMock<MockReadCB> callback;
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(callback, Run(DemuxerStream::kOk, IsEndOfStreamBuffer()));
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt the read...
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  audio->Read(base::Bind(&MockReadCB::Run, base::Unretained(&callback)));
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.RunUntilIdle();
5983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Don't let the test call Stop() again.
6003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  demuxer_.reset();
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that seek works properly when the WebM cues data is at the start of
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the file instead of at the end.
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, SeekWithCuesBeforeFirstCluster) {
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("bear-320x240-cues-in-front.webm");
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeDemuxer();
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get our streams.
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(video);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(audio);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read a video packet and release it.
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video->Read(NewReadCB(FROM_HERE, 22084, 0));
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue a simple forward seek, which should discard queued packets.
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitableMessageLoopEvent event;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Seek(base::TimeDelta::FromMicroseconds(2500000),
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 event.GetPipelineStatusCB());
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  event.RunAndWaitForStatus(PIPELINE_OK);
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio read #1.
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  audio->Read(NewReadCB(FROM_HERE, 40, 2403000));
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio read #2.
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  audio->Read(NewReadCB(FROM_HERE, 42, 2406000));
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video read #1.
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video->Read(NewReadCB(FROM_HERE, 5276, 2402000));
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video read #2.
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video->Read(NewReadCB(FROM_HERE, 1740, 2436000));
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.Run();
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure ID3v1 tag reading is disabled.  id3_test.mp3 has an ID3v1 tag with the
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// field "title" set to "sample for id3 test".
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, NoID3TagData) {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("id3_test.mp3");
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeDemuxer();
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(av_dict_get(format_context()->metadata, "title", NULL, 0));
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
65023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure MP3 files with large image/video based ID3 tags demux okay.  FFmpeg
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will hand us a video stream to the data which will likely be in a format we
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// don't accept as video; e.g. PNG.
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Mp3WithVideoStreamID3TagData) {
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("id3_png_test.mp3");
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeDemuxer();
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the expected streams are present.
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::VIDEO));
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(demuxer_->GetStream(DemuxerStream::AUDIO));
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
66423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure a video with an unsupported audio track still results in the video
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stream being demuxed.
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, UnsupportedAudioSupportedVideoDemux) {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("speex_audio_vorbis_video.ogv");
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeDemuxer();
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the expected streams are present.
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(demuxer_->GetStream(DemuxerStream::VIDEO));
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::AUDIO));
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure a video with an unsupported video track still results in the audio
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stream being demuxed.
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, UnsupportedVideoSupportedAudioDemux) {
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDemuxer("vorbis_audio_wmv_video.mkv");
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeDemuxer();
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the expected streams are present.
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::VIDEO));
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(demuxer_->GetStream(DemuxerStream::AUDIO));
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS)
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// FFmpeg returns null data pointers when samples have zero size, leading to
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// mistakenly creating end of stream buffers http://crbug.com/169133
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, MP4_ZeroStszEntry) {
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateDemuxer("bear-1280x720-zero-stsz-entry.mp4");
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeDemuxer();
6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::AUDIO));
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
696010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
697010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
698010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)static void ValidateAnnexB(DemuxerStream* stream,
699010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           DemuxerStream::Status status,
700010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           const scoped_refptr<DecoderBuffer>& buffer) {
701010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(status, DemuxerStream::kOk);
702010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
703010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (buffer->end_of_stream()) {
704010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
705010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
706010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
707010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
708010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
709010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  bool is_valid =
710010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      mp4::AVC::IsValidAnnexB(buffer->data(), buffer->data_size());
711010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_TRUE(is_valid);
712010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
713010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!is_valid) {
714010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    LOG(ERROR) << "Buffer contains invalid Annex B data.";
715010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
716010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
717010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
718010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
719010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
720010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  stream->Read(base::Bind(&ValidateAnnexB, stream));
721010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)};
722010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
723010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, IsValidAnnexB) {
724010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const char* files[] = {
725010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    "bear-1280x720-av_frag.mp4",
726010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    "bear-1280x720-av_with-aud-nalus_frag.mp4"
727010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  };
728010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
729010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < arraysize(files); ++i) {
730010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    DVLOG(1) << "Testing " << files[i];
731010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    CreateDemuxer(files[i]);
732010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    InitializeDemuxer();
733010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
734010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Ensure the expected streams are present.
735010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
736010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ASSERT_TRUE(stream);
737010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    stream->EnableBitstreamConverter();
738010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
739010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    stream->Read(base::Bind(&ValidateAnnexB, stream));
740010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    message_loop_.Run();
741010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
742010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    WaitableMessageLoopEvent event;
743010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    demuxer_->Stop(event.GetClosure());
744010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    event.RunAndWait();
745010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    demuxer_.reset();
746010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    data_source_.reset();
747010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
748010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
749010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
75023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
753