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

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 unittests Created 8 years, 4 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 bool InitDemuxerWithConfigChangeData() {
vrk (LEFT CHROMIUM) 2012/07/25 21:18:22 I think you should add a comment before this metho
360 scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm");
361 scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm");
362
363 EXPECT_CALL(*client_, DemuxerOpened(_));
364 demuxer_->Initialize(
365 &host_, CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744),
366 PIPELINE_OK));
367
368 if (AddId(kSourceId, true, true) != ChunkDemuxer::kOk)
369 return false;
370
371 // Append the whole bear1 file.
372 if (!AppendData(bear1->GetData(), bear1->GetDataSize()))
373 return false;
374 CheckExpectedRanges(kSourceId, "{ [0,2737) }");
375
376 // Append initialization segment for bear2
vrk (LEFT CHROMIUM) 2012/07/25 21:18:22 nit: period at the end
acolwell GONE FROM CHROMIUM 2012/07/25 23:39:23 Done.
377 // Note: Offsets here and below are derived from
378 // media/test/data/bear-640x360-manifest.js and
379 // media/test/data/bear-320x240-manifest.js which were
380 // generated from media/test/data/bear-640x360.webm and
381 // media/test/data/bear-320x240.webm respectively.
382 if (!AppendData(bear2->GetData(), 4459))
383 return false;
384
385 // Append a media segment that goes from [0.477000, 0.988000)
vrk (LEFT CHROMIUM) 2012/07/25 21:18:22 nit: period at end
acolwell GONE FROM CHROMIUM 2012/07/25 23:39:23 Done.
386 if (!AppendData(bear2->GetData() + 55173, 19021))
387 return false;
388 CheckExpectedRanges(kSourceId, "{ [0,1002) [1201,2737) }");
389
390 // Append initialization segment for bear1 & fill gap with [770-1197)
391 // segment.
392 if (!AppendData(bear1->GetData(), 4370) ||
393 !AppendData(bear1->GetData() + 72737, 28183)) {
394 return false;
395 }
396 CheckExpectedRanges(kSourceId, "{ [0,2737) }");
397
398 return demuxer_->EndOfStream(PIPELINE_OK);
399 }
400
359 void ShutdownDemuxer() { 401 void ShutdownDemuxer() {
360 if (demuxer_) { 402 if (demuxer_) {
361 EXPECT_CALL(*client_, DemuxerClosed()); 403 EXPECT_CALL(*client_, DemuxerClosed());
362 demuxer_->Shutdown(); 404 demuxer_->Shutdown();
363 } 405 }
364 } 406 }
365 407
366 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) { 408 void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) {
367 uint8 data[] = { 0x00 }; 409 uint8 data[] = { 0x00 };
368 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data)); 410 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, 566 MOCK_METHOD2(ReadDone, void(DemuxerStream::Status status,
525 const scoped_refptr<DecoderBuffer>&)); 567 const scoped_refptr<DecoderBuffer>&));
526 568
527 void ExpectRead(DemuxerStream* stream, int64 timestamp_in_ms) { 569 void ExpectRead(DemuxerStream* stream, int64 timestamp_in_ms) {
528 EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk, 570 EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk,
529 HasTimestamp(timestamp_in_ms))); 571 HasTimestamp(timestamp_in_ms)));
530 stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone, 572 stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone,
531 base::Unretained(this))); 573 base::Unretained(this)));
532 } 574 }
533 575
576 void ExpectConfigChanged(DemuxerStream* stream) {
577 EXPECT_CALL(*this, ReadDone(DemuxerStream::kConfigChanged, _));
578 stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone,
579 base::Unretained(this)));
580 }
581
534 MOCK_METHOD1(Checkpoint, void(int id)); 582 MOCK_METHOD1(Checkpoint, void(int id));
535 583
536 struct BufferTimestamps { 584 struct BufferTimestamps {
537 int video_time_ms; 585 int video_time_ms;
538 int audio_time_ms; 586 int audio_time_ms;
539 }; 587 };
540 static const int kSkip = -1; 588 static const int kSkip = -1;
541 589
542 // Test parsing a WebM file. 590 // Test parsing a WebM file.
543 // |filename| - The name of the file in media/test/data to parse. 591 // |filename| - The name of the file in media/test/data to parse.
(...skipping 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after
1794 demuxer_->GetStream(DemuxerStream::VIDEO); 1842 demuxer_->GetStream(DemuxerStream::VIDEO);
1795 1843
1796 GenerateExpectedReads(0, 4, audio, video); 1844 GenerateExpectedReads(0, 4, audio, video);
1797 GenerateExpectedReads(46, 66, 5, audio, video); 1845 GenerateExpectedReads(46, 66, 5, audio, video);
1798 1846
1799 EndOfStreamHelper end_of_stream_helper(demuxer_); 1847 EndOfStreamHelper end_of_stream_helper(demuxer_);
1800 end_of_stream_helper.RequestReads(); 1848 end_of_stream_helper.RequestReads();
1801 end_of_stream_helper.CheckIfReadDonesWereCalled(true); 1849 end_of_stream_helper.CheckIfReadDonesWereCalled(true);
1802 } 1850 }
1803 1851
1852 static void ConfigChangeReadDone(DemuxerStream::Status* status_out,
1853 scoped_refptr<DecoderBuffer>* buffer_out,
1854 DemuxerStream::Status status,
1855 const scoped_refptr<DecoderBuffer>& buffer) {
1856 *status_out = status;
1857 *buffer_out = buffer;
1858 }
1859
1860 static void ReadUntilNotOkOrEndOfStream(
1861 const scoped_refptr<DemuxerStream>& stream,
1862 DemuxerStream::Status* status,
1863 base::TimeDelta* last_timestamp) {
1864 scoped_refptr<DecoderBuffer> buffer;
1865
1866 *last_timestamp = kNoTimestamp();
1867 do {
1868 stream->Read(base::Bind(&ConfigChangeReadDone, status, &buffer));
1869 if (*status == DemuxerStream::kOk && !buffer->IsEndOfStream())
1870 *last_timestamp = buffer->GetTimestamp();
1871
1872 } while (*status == DemuxerStream::kOk && !buffer->IsEndOfStream());
1873 }
1874
1875 TEST_F(ChunkDemuxerTest, TestConfigChange) {
1876 InSequence s;
1877
1878 ASSERT_TRUE(InitDemuxerWithConfigChangeData());
1879
1880 scoped_refptr<DemuxerStream> stream =
1881 demuxer_->GetStream(DemuxerStream::VIDEO);
1882 DemuxerStream::Status status;
1883 base::TimeDelta last_timestamp;
1884
1885 // Fetch initial video config and verify it matches what we expect.
1886 const VideoDecoderConfig& video_config = stream->video_decoder_config();
1887 ASSERT_TRUE(video_config.IsValidConfig());
1888 EXPECT_EQ(video_config.natural_size().width(), 320);
1889 EXPECT_EQ(video_config.natural_size().height(), 240);
1890
1891 ReadUntilNotOkOrEndOfStream(stream, &status, &last_timestamp);
1892
1893 ASSERT_EQ(status, DemuxerStream::kConfigChanged);
1894 EXPECT_EQ(last_timestamp.InMilliseconds(), 467);
1895
1896 // Verify that another read will result in kConfigChanged being returned
1897 // again.
1898 ExpectConfigChanged(stream);
1899
1900 // Fetch the new decoder config.
1901 const VideoDecoderConfig& video_config2 = stream->video_decoder_config();
1902 ASSERT_TRUE(video_config2.IsValidConfig());
1903 EXPECT_EQ(video_config2.natural_size().width(), 640);
1904 EXPECT_EQ(video_config2.natural_size().height(), 360);
1905
1906 ExpectRead(stream, 501);
1907
1908 // Read until the next config change.
1909 ReadUntilNotOkOrEndOfStream(stream, &status, &last_timestamp);
1910 ASSERT_EQ(status, DemuxerStream::kConfigChanged);
1911 EXPECT_EQ(last_timestamp.InMilliseconds(), 767);
1912
1913 // Verify we get another ConfigChanged status.
1914 ExpectConfigChanged(stream);
1915
1916 // Get the new config and verify that it matches the first one.
1917 ASSERT_TRUE(video_config.Matches(stream->video_decoder_config()));
vrk (LEFT CHROMIUM) 2012/07/25 21:18:22 nit: In this test and below, maybe s/video_config/
acolwell GONE FROM CHROMIUM 2012/07/25 23:39:23 Done.
1918
1919 ExpectRead(stream, 801);
1920
1921 // Read until the end of the stream just to make sure there aren't any other
1922 // config changes.
1923 ReadUntilNotOkOrEndOfStream(stream, &status, &last_timestamp);
1924 ASSERT_EQ(status, DemuxerStream::kOk);
1925 }
1926
1927 TEST_F(ChunkDemuxerTest, TestConfigChange_Seek) {
1928 InSequence s;
1929
1930 ASSERT_TRUE(InitDemuxerWithConfigChangeData());
1931
1932 scoped_refptr<DemuxerStream> stream =
1933 demuxer_->GetStream(DemuxerStream::VIDEO);
1934
1935 // Fetch initial video config and verify it matches what we expect.
1936 const VideoDecoderConfig& video_config = stream->video_decoder_config();
1937 ASSERT_TRUE(video_config.IsValidConfig());
1938 EXPECT_EQ(video_config.natural_size().width(), 320);
1939 EXPECT_EQ(video_config.natural_size().height(), 240);
1940
1941 ExpectRead(stream, 0);
1942
1943 // Seek to a location with a different config.
1944 demuxer_->Seek(base::TimeDelta::FromMilliseconds(501),
1945 NewExpectedStatusCB(PIPELINE_OK));
1946
1947 // Verify that the config change is signalled.
1948 ExpectConfigChanged(stream);
1949
1950 // Fetch the new decoder config and verify it is what we expect.
1951 const VideoDecoderConfig& video_config2 = stream->video_decoder_config();
1952 ASSERT_TRUE(video_config2.IsValidConfig());
1953 EXPECT_EQ(video_config2.natural_size().width(), 640);
1954 EXPECT_EQ(video_config2.natural_size().height(), 360);
1955
1956 // Verify that Read() will return a buffer now.
1957 ExpectRead(stream, 501);
1958
1959 // Seek back to the beginning and verify we get another config change.
1960 demuxer_->Seek(base::TimeDelta::FromMilliseconds(0),
1961 NewExpectedStatusCB(PIPELINE_OK));
1962 ExpectConfigChanged(stream);
1963 ASSERT_TRUE(video_config.Matches(stream->video_decoder_config()));
1964 ExpectRead(stream, 0);
1965
1966 // Seek to a location that requires a config change and then
1967 // seek to a new location that has the same configuration as
1968 // the start of the file without a Read() in the middle.
1969 demuxer_->Seek(base::TimeDelta::FromMilliseconds(501),
1970 NewExpectedStatusCB(PIPELINE_OK));
1971 demuxer_->Seek(base::TimeDelta::FromMilliseconds(801),
1972 NewExpectedStatusCB(PIPELINE_OK));
1973
1974 // Verify that no config change is signalled.
1975 ExpectRead(stream, 801);
1976 ASSERT_TRUE(video_config.Matches(stream->video_decoder_config()));
1977 }
1978
1804 } // namespace media 1979 } // 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