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

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

Issue 20123002: Add Chromium-side support for SourceBuffer.appendWindowStart and SourceBuffer.appendWindowEnd. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase and remove URL in comment to make presubmit happy. Created 7 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/mp4/mp4_stream_parser.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 <algorithm> 5 #include <algorithm>
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_split.h"
11 #include "base/strings/string_util.h"
9 #include "media/base/audio_decoder_config.h" 12 #include "media/base/audio_decoder_config.h"
10 #include "media/base/decoder_buffer.h" 13 #include "media/base/decoder_buffer.h"
11 #include "media/base/decrypt_config.h" 14 #include "media/base/decrypt_config.h"
12 #include "media/base/mock_demuxer_host.h" 15 #include "media/base/mock_demuxer_host.h"
13 #include "media/base/test_data_util.h" 16 #include "media/base/test_data_util.h"
14 #include "media/base/test_helpers.h" 17 #include "media/base/test_helpers.h"
15 #include "media/filters/chunk_demuxer.h" 18 #include "media/filters/chunk_demuxer.h"
16 #include "media/webm/cluster_builder.h" 19 #include "media/webm/cluster_builder.h"
17 #include "media/webm/webm_constants.h" 20 #include "media/webm/webm_constants.h"
18 #include "media/webm/webm_crypto_helpers.h" 21 #include "media/webm/webm_crypto_helpers.h"
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 AppendData(kSourceId, data, length); 285 AppendData(kSourceId, data, length);
283 } 286 }
284 287
285 void AppendCluster(int timecode, int block_count) { 288 void AppendCluster(int timecode, int block_count) {
286 scoped_ptr<Cluster> cluster(GenerateCluster(timecode, block_count)); 289 scoped_ptr<Cluster> cluster(GenerateCluster(timecode, block_count));
287 AppendData(kSourceId, cluster->data(), cluster->size()); 290 AppendData(kSourceId, cluster->data(), cluster->size());
288 } 291 }
289 292
290 void AppendSingleStreamCluster(const std::string& source_id, int track_number, 293 void AppendSingleStreamCluster(const std::string& source_id, int track_number,
291 int timecode, int block_count) { 294 int timecode, int block_count) {
292 static const int kVideoTrackNum = 1;
293 static const int kAudioTrackNum = 2;
294
295 static const int kAudioBlockDuration = 23;
296 static const int kVideoBlockDuration = 33;
297
298 int block_duration = 0; 295 int block_duration = 0;
299 switch(track_number) { 296 switch(track_number) {
300 case kVideoTrackNum: 297 case kVideoTrackNum:
301 block_duration = kVideoBlockDuration; 298 block_duration = kVideoBlockDuration;
302 break; 299 break;
303 case kAudioTrackNum: 300 case kAudioTrackNum:
304 block_duration = kAudioBlockDuration; 301 block_duration = kAudioBlockDuration;
305 break; 302 break;
306 } 303 }
307 ASSERT_NE(block_duration, 0); 304 ASSERT_NE(block_duration, 0);
308 int end_timecode = timecode + block_count * block_duration; 305 int end_timecode = timecode + block_count * block_duration;
309 scoped_ptr<Cluster> cluster(GenerateSingleStreamCluster( 306 scoped_ptr<Cluster> cluster(GenerateSingleStreamCluster(
310 timecode, end_timecode, track_number, block_duration)); 307 timecode, end_timecode, track_number, block_duration));
311 AppendData(source_id, cluster->data(), cluster->size()); 308 AppendData(source_id, cluster->data(), cluster->size());
312 } 309 }
313 310
311 void AppendSingleStreamCluster(const std::string& source_id, int track_number,
312 const std::string& cluster_description) {
313 std::vector<std::string> timestamps;
314 base::SplitString(cluster_description, ' ', &timestamps);
315
316 ClusterBuilder cb;
317 std::vector<uint8> data(10);
318 for (size_t i = 0; i < timestamps.size(); ++i) {
319 std::string timestamp_str = timestamps[i];
320 int block_flags = 0;
321 if (EndsWith(timestamp_str, "K", true)) {
322 block_flags = kWebMFlagKeyframe;
323 // Remove the "K" off of the token.
324 timestamp_str = timestamp_str.substr(0, timestamps[i].length() - 1);
325 }
326 int timestamp_in_ms;
327 CHECK(base::StringToInt(timestamp_str, &timestamp_in_ms));
328
329 if (i == 0)
330 cb.SetClusterTimecode(timestamp_in_ms);
331
332 cb.AddSimpleBlock(track_number, timestamp_in_ms, block_flags,
333 &data[0], data.size());
334 }
335 scoped_ptr<Cluster> cluster(cb.Finish());
336 AppendData(source_id, cluster->data(), cluster->size());
337 }
314 338
315 void AppendData(const std::string& source_id, 339 void AppendData(const std::string& source_id,
316 const uint8* data, size_t length) { 340 const uint8* data, size_t length) {
317 EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber()); 341 EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber());
318 demuxer_->AppendData(source_id, data, length); 342 demuxer_->AppendData(source_id, data, length);
319 } 343 }
320 344
321 void AppendDataInPieces(const uint8* data, size_t length) { 345 void AppendDataInPieces(const uint8* data, size_t length) {
322 AppendDataInPieces(data, length, 7); 346 AppendDataInPieces(data, length, 7);
323 } 347 }
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 message_loop_.RunUntilIdle(); 750 message_loop_.RunUntilIdle();
727 } 751 }
728 752
729 void ExpectConfigChanged(DemuxerStream::Type type) { 753 void ExpectConfigChanged(DemuxerStream::Type type) {
730 EXPECT_CALL(*this, ReadDone(DemuxerStream::kConfigChanged, _)); 754 EXPECT_CALL(*this, ReadDone(DemuxerStream::kConfigChanged, _));
731 demuxer_->GetStream(type)->Read(base::Bind( 755 demuxer_->GetStream(type)->Read(base::Bind(
732 &ChunkDemuxerTest::ReadDone, base::Unretained(this))); 756 &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
733 message_loop_.RunUntilIdle(); 757 message_loop_.RunUntilIdle();
734 } 758 }
735 759
760 void CheckExpectedBuffers(DemuxerStream* stream,
761 const std::string& expected) {
762 std::vector<std::string> timestamps;
763 base::SplitString(expected, ' ', &timestamps);
764 std::stringstream ss;
765 for (size_t i = 0; i < timestamps.size(); ++i) {
766 DemuxerStream::Status status;
767 scoped_refptr<DecoderBuffer> buffer;
768 stream->Read(base::Bind(&ChunkDemuxerTest::StoreStatusAndBuffer,
769 base::Unretained(this), &status, &buffer));
770 base::MessageLoop::current()->RunUntilIdle();
771 if (status != DemuxerStream::kOk || buffer->end_of_stream())
772 break;
773
774 if (i > 0)
775 ss << " ";
776 ss << buffer->timestamp().InMilliseconds();
777 }
778 EXPECT_EQ(expected, ss.str());
779 }
780
736 MOCK_METHOD1(Checkpoint, void(int id)); 781 MOCK_METHOD1(Checkpoint, void(int id));
737 782
738 struct BufferTimestamps { 783 struct BufferTimestamps {
739 int video_time_ms; 784 int video_time_ms;
740 int audio_time_ms; 785 int audio_time_ms;
741 }; 786 };
742 static const int kSkip = -1; 787 static const int kSkip = -1;
743 788
744 // Test parsing a WebM file. 789 // Test parsing a WebM file.
745 // |filename| - The name of the file in media/test/data to parse. 790 // |filename| - The name of the file in media/test/data to parse.
(...skipping 1917 matching lines...) Expand 10 before | Expand all | Expand 10 after
2663 EXPECT_CALL(*this, DemuxerOpened()); 2708 EXPECT_CALL(*this, DemuxerOpened());
2664 demuxer_->Initialize( 2709 demuxer_->Initialize(
2665 &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_OK)); 2710 &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_OK));
2666 2711
2667 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, true, true)); 2712 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, true, true));
2668 2713
2669 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0), 2714 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0),
2670 base::TimeDelta::FromMilliseconds(1)); 2715 base::TimeDelta::FromMilliseconds(1));
2671 } 2716 }
2672 2717
2718 TEST_F(ChunkDemuxerTest, AppendWindow) {
2719 ASSERT_TRUE(InitDemuxer(false, true));
2720 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
2721
2722 // Set the append window to [20,280).
2723 demuxer_->SetAppendWindowStart(kSourceId,
2724 base::TimeDelta::FromMilliseconds(20));
2725 demuxer_->SetAppendWindowEnd(kSourceId,
2726 base::TimeDelta::FromMilliseconds(280));
2727
2728 // Append a cluster that starts before and ends after the append window.
2729 AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
2730 "0K 30 60 90 120K 150 180 210 240K 270 300 330K");
2731
2732 // Verify that GOPs that start outside the window are not included
2733 // in the buffer. Also verify that buffers that extend beyond the
2734 // window are not included.
2735 CheckExpectedRanges(kSourceId, "{ [120,300) }");
2736 CheckExpectedBuffers(stream, "120 150 180 210 240 270");
2737
2738 // Extend the append window to [20,650).
2739 demuxer_->SetAppendWindowEnd(kSourceId,
2740 base::TimeDelta::FromMilliseconds(650));
2741
2742 // Append more data and verify that adding buffers start at the next
2743 // keyframe.
2744 AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
2745 "360 390 420K 450 480 510 540K 570 600 630K");
2746 CheckExpectedRanges(kSourceId, "{ [120,300) [420,660) }");
2747 }
2748
2673 } // namespace media 2749 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/chunk_demuxer.cc ('k') | media/mp4/mp4_stream_parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698