Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: media/filters/chunk_demuxer_unittest.cc

Issue 10696182: Add config change handling to SourceBufferStream & ChunkDemuxer (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added copyright headers to manifest files Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/filters/chunk_demuxer.cc ('k') | media/filters/source_buffer_stream.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/bind.h" 5 #include "base/bind.h"
6 #include "media/base/audio_decoder_config.h" 6 #include "media/base/audio_decoder_config.h"
7 #include "media/base/decoder_buffer.h" 7 #include "media/base/decoder_buffer.h"
8 #include "media/base/mock_callback.h" 8 #include "media/base/mock_callback.h"
9 #include "media/base/mock_demuxer_host.h" 9 #include "media/base/mock_demuxer_host.h"
10 #include "media/base/test_data_util.h" 10 #include "media/base/test_data_util.h"
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 demuxer_->Initialize( 349 demuxer_->Initialize(
350 &host_, CreateInitDoneCB( 350 &host_, CreateInitDoneCB(
351 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN)); 351 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN));
352 352
353 if (AddId(kSourceId, true, true) != ChunkDemuxer::kOk) 353 if (AddId(kSourceId, true, true) != ChunkDemuxer::kOk)
354 return false; 354 return false;
355 355
356 return AppendInitSegment(true, true, false); 356 return AppendInitSegment(true, true, false);
357 } 357 }
358 358
359 // Initializes the demuxer with data from 2 files with different
360 // decoder configurations. This is used to test the decoder config change
361 // logic.
362 //
363 // bear-320x240.webm VideoDecoderConfig returns 320x240 for its natural_size()
364 // bear-640x360.webm VideoDecoderConfig returns 640x360 for its natural_size()
365 // The resulting video stream returns data from each file for the following
366 // time ranges.
367 // bear-320x240.webm : [0-501) [801-2737)
368 // bear-640x360.webm : [501-801)
369 //
370 // bear-320x240.webm AudioDecoderConfig returns 3863 for its extra_data_size()
371 // bear-640x360.webm AudioDecoderConfig returns 3935 for its extra_data_size()
372 // The resulting audio stream returns data from each file for the following
373 // time ranges.
374 // bear-320x240.webm : [0-464) [779-2737)
375 // bear-640x360.webm : [477-756)
376 bool InitDemuxerWithConfigChangeData() {
377 scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm");
378 scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm");
379
380 EXPECT_CALL(*client_, DemuxerOpened(_));
381 demuxer_->Initialize(
382 &host_, CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744),
383 PIPELINE_OK));
384
385 if (AddId(kSourceId, true, true) != ChunkDemuxer::kOk)
386 return false;
387
388 // Append the whole bear1 file.
389 if (!AppendData(bear1->GetData(), bear1->GetDataSize()))
390 return false;
391 CheckExpectedRanges(kSourceId, "{ [0,2737) }");
392
393 // Append initialization segment for bear2.
394 // Note: Offsets here and below are derived from
395 // media/test/data/bear-640x360-manifest.js and
396 // media/test/data/bear-320x240-manifest.js which were
397 // generated from media/test/data/bear-640x360.webm and
398 // media/test/data/bear-320x240.webm respectively.
399 if (!AppendData(bear2->GetData(), 4459))
400 return false;
401
402 // Append a media segment that goes from [0.477000, 0.988000).
403 if (!AppendData(bear2->GetData() + 55173, 19021))
404 return false;
405 CheckExpectedRanges(kSourceId, "{ [0,1002) [1201,2737) }");
406
407 // Append initialization segment for bear1 & fill gap with [770-1197)
408 // segment.
409 if (!AppendData(bear1->GetData(), 4370) ||
410 !AppendData(bear1->GetData() + 72737, 28183)) {
411 return false;
412 }
413 CheckExpectedRanges(kSourceId, "{ [0,2737) }");
414
415 return demuxer_->EndOfStream(PIPELINE_OK);
416 }
417
359 void ShutdownDemuxer() { 418 void ShutdownDemuxer() {
360 if (demuxer_) { 419 if (demuxer_) {
361 EXPECT_CALL(*client_, DemuxerClosed()); 420 EXPECT_CALL(*client_, DemuxerClosed());
362 demuxer_->Shutdown(); 421 demuxer_->Shutdown();
363 } 422 }
364 } 423 }
365 424
366 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) { 425 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) {
367 uint8 data[] = { 0x00 }; 426 uint8 data[] = { 0x00 };
368 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data)); 427 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data));
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 MOCK_METHOD2(ReadDone, void(DemuxerStream::Status status, 583 MOCK_METHOD2(ReadDone, void(DemuxerStream::Status status,
525 const scoped_refptr<DecoderBuffer>&)); 584 const scoped_refptr<DecoderBuffer>&));
526 585
527 void ExpectRead(DemuxerStream* stream, int64 timestamp_in_ms) { 586 void ExpectRead(DemuxerStream* stream, int64 timestamp_in_ms) {
528 EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk, 587 EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk,
529 HasTimestamp(timestamp_in_ms))); 588 HasTimestamp(timestamp_in_ms)));
530 stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone, 589 stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone,
531 base::Unretained(this))); 590 base::Unretained(this)));
532 } 591 }
533 592
593 void ExpectConfigChanged(DemuxerStream* stream) {
594 EXPECT_CALL(*this, ReadDone(DemuxerStream::kConfigChanged, _));
595 stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone,
596 base::Unretained(this)));
597 }
598
534 MOCK_METHOD1(Checkpoint, void(int id)); 599 MOCK_METHOD1(Checkpoint, void(int id));
535 600
536 struct BufferTimestamps { 601 struct BufferTimestamps {
537 int video_time_ms; 602 int video_time_ms;
538 int audio_time_ms; 603 int audio_time_ms;
539 }; 604 };
540 static const int kSkip = -1; 605 static const int kSkip = -1;
541 606
542 // Test parsing a WebM file. 607 // Test parsing a WebM file.
543 // |filename| - The name of the file in media/test/data to parse. 608 // |filename| - The name of the file in media/test/data to parse.
(...skipping 1265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1809 demuxer_->GetStream(DemuxerStream::VIDEO); 1874 demuxer_->GetStream(DemuxerStream::VIDEO);
1810 1875
1811 GenerateExpectedReads(0, 4, audio, video); 1876 GenerateExpectedReads(0, 4, audio, video);
1812 GenerateExpectedReads(46, 66, 5, audio, video); 1877 GenerateExpectedReads(46, 66, 5, audio, video);
1813 1878
1814 EndOfStreamHelper end_of_stream_helper(demuxer_); 1879 EndOfStreamHelper end_of_stream_helper(demuxer_);
1815 end_of_stream_helper.RequestReads(); 1880 end_of_stream_helper.RequestReads();
1816 end_of_stream_helper.CheckIfReadDonesWereCalled(true); 1881 end_of_stream_helper.CheckIfReadDonesWereCalled(true);
1817 } 1882 }
1818 1883
1884 static void ConfigChangeReadDone(DemuxerStream::Status* status_out,
1885 scoped_refptr<DecoderBuffer>* buffer_out,
1886 DemuxerStream::Status status,
1887 const scoped_refptr<DecoderBuffer>& buffer) {
1888 *status_out = status;
1889 *buffer_out = buffer;
1890 }
1891
1892 static void ReadUntilNotOkOrEndOfStream(
1893 const scoped_refptr<DemuxerStream>& stream,
1894 DemuxerStream::Status* status,
1895 base::TimeDelta* last_timestamp) {
1896 scoped_refptr<DecoderBuffer> buffer;
1897
1898 *last_timestamp = kNoTimestamp();
1899 do {
1900 stream->Read(base::Bind(&ConfigChangeReadDone, status, &buffer));
1901 if (*status == DemuxerStream::kOk && !buffer->IsEndOfStream())
1902 *last_timestamp = buffer->GetTimestamp();
1903
1904 } while (*status == DemuxerStream::kOk && !buffer->IsEndOfStream());
1905 }
1906
1907 TEST_F(ChunkDemuxerTest, TestConfigChange_Video) {
1908 InSequence s;
1909
1910 ASSERT_TRUE(InitDemuxerWithConfigChangeData());
1911
1912 scoped_refptr<DemuxerStream> stream =
1913 demuxer_->GetStream(DemuxerStream::VIDEO);
1914 DemuxerStream::Status status;
1915 base::TimeDelta last_timestamp;
1916
1917 // Fetch initial video config and verify it matches what we expect.
1918 const VideoDecoderConfig& video_config_1 = stream->video_decoder_config();
1919 ASSERT_TRUE(video_config_1.IsValidConfig());
1920 EXPECT_EQ(video_config_1.natural_size().width(), 320);
1921 EXPECT_EQ(video_config_1.natural_size().height(), 240);
1922
1923 ExpectRead(stream, 0);
1924
1925 ReadUntilNotOkOrEndOfStream(stream, &status, &last_timestamp);
1926
1927 ASSERT_EQ(status, DemuxerStream::kConfigChanged);
1928 EXPECT_EQ(last_timestamp.InMilliseconds(), 467);
1929
1930 // Verify that another read will result in kConfigChanged being returned
1931 // again.
1932 ExpectConfigChanged(stream);
1933
1934 // Fetch the new decoder config.
1935 const VideoDecoderConfig& video_config_2 = stream->video_decoder_config();
1936 ASSERT_TRUE(video_config_2.IsValidConfig());
1937 EXPECT_EQ(video_config_2.natural_size().width(), 640);
1938 EXPECT_EQ(video_config_2.natural_size().height(), 360);
1939
1940 ExpectRead(stream, 501);
1941
1942 // Read until the next config change.
1943 ReadUntilNotOkOrEndOfStream(stream, &status, &last_timestamp);
1944 ASSERT_EQ(status, DemuxerStream::kConfigChanged);
1945 EXPECT_EQ(last_timestamp.InMilliseconds(), 767);
1946
1947 // Verify we get another ConfigChanged status.
1948 ExpectConfigChanged(stream);
1949
1950 // Get the new config and verify that it matches the first one.
1951 ASSERT_TRUE(video_config_1.Matches(stream->video_decoder_config()));
1952
1953 ExpectRead(stream, 801);
1954
1955 // Read until the end of the stream just to make sure there aren't any other
1956 // config changes.
1957 ReadUntilNotOkOrEndOfStream(stream, &status, &last_timestamp);
1958 ASSERT_EQ(status, DemuxerStream::kOk);
1959 }
1960
1961 TEST_F(ChunkDemuxerTest, TestConfigChange_Audio) {
1962 InSequence s;
1963
1964 ASSERT_TRUE(InitDemuxerWithConfigChangeData());
1965
1966 scoped_refptr<DemuxerStream> stream =
1967 demuxer_->GetStream(DemuxerStream::AUDIO);
1968 DemuxerStream::Status status;
1969 base::TimeDelta last_timestamp;
1970
1971 // Fetch initial audio config and verify it matches what we expect.
1972 const AudioDecoderConfig& audio_config_1 = stream->audio_decoder_config();
1973 ASSERT_TRUE(audio_config_1.IsValidConfig());
1974 EXPECT_EQ(audio_config_1.samples_per_second(), 44100);
1975 EXPECT_EQ(audio_config_1.extra_data_size(), 3863u);
1976
1977 ExpectRead(stream, 0);
1978
1979 ReadUntilNotOkOrEndOfStream(stream, &status, &last_timestamp);
1980
1981 ASSERT_EQ(status, DemuxerStream::kConfigChanged);
1982 EXPECT_EQ(last_timestamp.InMilliseconds(), 464);
1983
1984 // Verify that another read will result in kConfigChanged being returned
1985 // again.
1986 ExpectConfigChanged(stream);
1987
1988 // Fetch the new decoder config.
1989 const AudioDecoderConfig& audio_config_2 = stream->audio_decoder_config();
1990 ASSERT_TRUE(audio_config_2.IsValidConfig());
1991 EXPECT_EQ(audio_config_2.samples_per_second(), 44100);
1992 EXPECT_EQ(audio_config_2.extra_data_size(), 3935u);
1993
1994 ExpectRead(stream, 477);
1995
1996 // Read until the next config change.
1997 ReadUntilNotOkOrEndOfStream(stream, &status, &last_timestamp);
1998 ASSERT_EQ(status, DemuxerStream::kConfigChanged);
1999 EXPECT_EQ(last_timestamp.InMilliseconds(), 756);
2000
2001 // Verify we get another ConfigChanged status.
2002 ExpectConfigChanged(stream);
2003
2004 // Get the new config and verify that it matches the first one.
2005 ASSERT_TRUE(audio_config_1.Matches(stream->audio_decoder_config()));
2006
2007 ExpectRead(stream, 779);
2008
2009 // Read until the end of the stream just to make sure there aren't any other
2010 // config changes.
2011 ReadUntilNotOkOrEndOfStream(stream, &status, &last_timestamp);
2012 ASSERT_EQ(status, DemuxerStream::kOk);
2013 }
2014
2015 TEST_F(ChunkDemuxerTest, TestConfigChange_Seek) {
2016 InSequence s;
2017
2018 ASSERT_TRUE(InitDemuxerWithConfigChangeData());
2019
2020 scoped_refptr<DemuxerStream> stream =
2021 demuxer_->GetStream(DemuxerStream::VIDEO);
2022
2023 // Fetch initial video config and verify it matches what we expect.
2024 const VideoDecoderConfig& video_config_1 = stream->video_decoder_config();
2025 ASSERT_TRUE(video_config_1.IsValidConfig());
2026 EXPECT_EQ(video_config_1.natural_size().width(), 320);
2027 EXPECT_EQ(video_config_1.natural_size().height(), 240);
2028
2029 ExpectRead(stream, 0);
2030
2031 // Seek to a location with a different config.
2032 demuxer_->Seek(base::TimeDelta::FromMilliseconds(501),
2033 NewExpectedStatusCB(PIPELINE_OK));
2034
2035 // Verify that the config change is signalled.
2036 ExpectConfigChanged(stream);
2037
2038 // Fetch the new decoder config and verify it is what we expect.
2039 const VideoDecoderConfig& video_config_2 = stream->video_decoder_config();
2040 ASSERT_TRUE(video_config_2.IsValidConfig());
2041 EXPECT_EQ(video_config_2.natural_size().width(), 640);
2042 EXPECT_EQ(video_config_2.natural_size().height(), 360);
2043
2044 // Verify that Read() will return a buffer now.
2045 ExpectRead(stream, 501);
2046
2047 // Seek back to the beginning and verify we get another config change.
2048 demuxer_->Seek(base::TimeDelta::FromMilliseconds(0),
2049 NewExpectedStatusCB(PIPELINE_OK));
2050 ExpectConfigChanged(stream);
2051 ASSERT_TRUE(video_config_1.Matches(stream->video_decoder_config()));
2052 ExpectRead(stream, 0);
2053
2054 // Seek to a location that requires a config change and then
2055 // seek to a new location that has the same configuration as
2056 // the start of the file without a Read() in the middle.
2057 demuxer_->Seek(base::TimeDelta::FromMilliseconds(501),
2058 NewExpectedStatusCB(PIPELINE_OK));
2059 demuxer_->Seek(base::TimeDelta::FromMilliseconds(801),
2060 NewExpectedStatusCB(PIPELINE_OK));
2061
2062 // Verify that no config change is signalled.
2063 ExpectRead(stream, 801);
2064 ASSERT_TRUE(video_config_1.Matches(stream->video_decoder_config()));
2065 }
2066
1819 } // namespace media 2067 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/chunk_demuxer.cc ('k') | media/filters/source_buffer_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698