OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |