Index: media/filters/chunk_demuxer_unittest.cc |
diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc |
index 770f28423be05d6bf4cccd8e9d1c18aa38ff5971..04356e09ac01d06cffa993461c0a8b85d7297f89 100644 |
--- a/media/filters/chunk_demuxer_unittest.cc |
+++ b/media/filters/chunk_demuxer_unittest.cc |
@@ -397,60 +397,138 @@ class ChunkDemuxerTest : public ::testing::Test { |
timecode, end_timecode, track_number, block_duration)); |
} |
- // |cluster_description| - A space delimited string of buffer info that |
- // is used to construct a cluster. Each buffer info is a timestamp in |
- // milliseconds and optionally followed by a 'K' to indicate that a buffer |
- // should be marked as a keyframe. For example "0K 30 60" should constuct |
- // a cluster with 3 blocks: a keyframe with timestamp 0 and 2 non-keyframes |
- // at 30ms and 60ms. |
- void AppendSingleStreamCluster(const std::string& source_id, int track_number, |
- const std::string& cluster_description) { |
+ struct BlockInfo { |
+ BlockInfo() |
+ : track_number(0), |
+ timestamp_in_ms(0), |
+ flags(0), |
+ duration(0) { |
+ } |
+ |
+ BlockInfo(int tn, int ts, int f, int d) |
+ : track_number(tn), |
+ timestamp_in_ms(ts), |
+ flags(f), |
+ duration(d) { |
+ } |
+ |
+ int track_number; |
+ int timestamp_in_ms; |
+ int flags; |
+ int duration; |
+ |
+ bool operator< (const BlockInfo& rhs) const { |
+ return timestamp_in_ms < rhs.timestamp_in_ms; |
+ } |
+ }; |
+ |
+ // |track_number| - The track number to place in |
+ // |blocks_description| - A space delimited string of block info that |
wolenetz
2014/07/08 22:45:34
nit: s/blocks_description/block_descriptions/ here
acolwell GONE FROM CHROMIUM
2014/07/08 23:01:04
Done.
|
+ // is used to populate |blocks|. Each block info has a timestamp in |
+ // milliseconds and optionally followed by a 'K' to indicate that a block |
+ // should be marked as a keyframe. For example "0K 30 60" should populate |
+ // |blocks| with 3 BlockInfo objects: a keyframe with timestamp 0 and 2 |
+ // non-keyframes at 30ms and 60ms. |
+ void ParseBlockDescription(int track_number, |
wolenetz
2014/07/08 22:45:34
nit: s/tion/tions/
acolwell GONE FROM CHROMIUM
2014/07/08 23:01:04
Done.
|
+ const std::string blocks_description, |
+ std::vector<BlockInfo>* blocks) { |
std::vector<std::string> timestamps; |
- base::SplitString(cluster_description, ' ', ×tamps); |
+ base::SplitString(blocks_description, ' ', ×tamps); |
- ClusterBuilder cb; |
- std::vector<uint8> data(10); |
for (size_t i = 0; i < timestamps.size(); ++i) { |
std::string timestamp_str = timestamps[i]; |
- int block_flags = 0; |
+ BlockInfo block_info; |
+ block_info.track_number = track_number; |
+ block_info.flags = 0; |
+ block_info.duration = 0; |
+ |
if (EndsWith(timestamp_str, "K", true)) { |
- block_flags = kWebMFlagKeyframe; |
+ block_info.flags = kWebMFlagKeyframe; |
// Remove the "K" off of the token. |
timestamp_str = timestamp_str.substr(0, timestamps[i].length() - 1); |
} |
- int timestamp_in_ms; |
- CHECK(base::StringToInt(timestamp_str, ×tamp_in_ms)); |
- |
- if (i == 0) |
- cb.SetClusterTimecode(timestamp_in_ms); |
+ CHECK(base::StringToInt(timestamp_str, &block_info.timestamp_in_ms)); |
if (track_number == kTextTrackNum || |
track_number == kAlternateTextTrackNum) { |
- cb.AddBlockGroup(track_number, timestamp_in_ms, kTextBlockDuration, |
- block_flags, &data[0], data.size()); |
+ block_info.duration = kTextBlockDuration; |
+ ASSERT_EQ(kWebMFlagKeyframe, block_info.flags) |
+ << "Text block with timestamp " << block_info.timestamp_in_ms |
+ << " was not marked as a keyframe." |
+ << " All text blocks must be keyframes"; |
+ } |
+ |
+ blocks->push_back(block_info); |
+ } |
+ } |
+ |
+ scoped_ptr<Cluster> GenerateCluster(const std::vector<BlockInfo>& blocks, |
+ bool unknown_size) { |
+ DCHECK_GT(blocks.size(), 0u); |
+ ClusterBuilder cb; |
+ |
+ std::vector<uint8> data(10); |
+ for (size_t i = 0; i < blocks.size(); ++i) { |
+ if (i == 0) |
+ cb.SetClusterTimecode(blocks[i].timestamp_in_ms); |
+ |
+ if (blocks[i].duration) { |
+ if (blocks[i].track_number == kVideoTrackNum) { |
+ AddVideoBlockGroup(&cb, |
+ blocks[i].track_number, blocks[i].timestamp_in_ms, |
+ blocks[i].duration, blocks[i].flags); |
+ } else { |
+ cb.AddBlockGroup(blocks[i].track_number, blocks[i].timestamp_in_ms, |
+ blocks[i].duration, blocks[i].flags, |
+ &data[0], data.size()); |
+ } |
} else { |
- cb.AddSimpleBlock(track_number, timestamp_in_ms, block_flags, |
+ cb.AddSimpleBlock(blocks[i].track_number, blocks[i].timestamp_in_ms, |
+ blocks[i].flags, |
&data[0], data.size()); |
} |
} |
- AppendCluster(source_id, cb.Finish()); |
+ |
+ return unknown_size ? cb.FinishWithUnknownSize() : cb.Finish(); |
+ } |
+ |
+ scoped_ptr<Cluster> GenerateCluster( |
+ std::priority_queue<BlockInfo> block_queue, |
+ bool unknown_size) { |
+ std::vector<BlockInfo> blocks(block_queue.size()); |
+ for (size_t i = block_queue.size() - 1; !block_queue.empty(); --i) { |
+ blocks[i] = block_queue.top(); |
+ block_queue.pop(); |
+ } |
+ |
+ return GenerateCluster(blocks, unknown_size); |
+ } |
+ |
+ // |block_descriptions| - The block descriptions used to construct the |
+ // cluster. See the documentation for ParseBlockDescription() for details on |
+ // the string format. |
+ void AppendSingleStreamCluster(const std::string& source_id, int track_number, |
+ const std::string& block_descriptions) { |
+ std::vector<BlockInfo> blocks; |
+ ParseBlockDescription(track_number, block_descriptions, &blocks); |
+ AppendCluster(source_id, GenerateCluster(blocks, false)); |
} |
struct MuxedStreamInfo { |
MuxedStreamInfo() |
: track_number(0), |
- cluster_description("") |
+ block_descriptions("") |
{} |
- MuxedStreamInfo(int track_num, const char* cluster_desc) |
+ MuxedStreamInfo(int track_num, const char* block_desc) |
: track_number(track_num), |
- cluster_description(cluster_desc) { |
+ block_descriptions(block_desc) { |
} |
int track_number; |
- // The cluster description passed to AppendSingleStreamCluster(). |
+ // The block description passed to ParseBlockDescription(). |
// See the documentation for that method for details on the string format. |
- const char* cluster_description; |
+ const char* block_descriptions; |
}; |
void AppendMuxedCluster(const MuxedStreamInfo& msi_1, |
@@ -472,11 +550,17 @@ class ChunkDemuxerTest : public ::testing::Test { |
} |
void AppendMuxedCluster(const std::vector<MuxedStreamInfo> msi) { |
+ std::priority_queue<BlockInfo> block_queue; |
for (size_t i = 0; i < msi.size(); ++i) { |
- AppendSingleStreamCluster(kSourceId, |
- msi[i].track_number, |
- msi[i].cluster_description); |
+ std::vector<BlockInfo> track_blocks; |
+ ParseBlockDescription(msi[i].track_number, msi[i].block_descriptions, |
+ &track_blocks); |
+ |
+ for (size_t j = 0; j < track_blocks.size(); ++j) |
+ block_queue.push(track_blocks[j]); |
} |
+ |
+ AppendCluster(kSourceId, GenerateCluster(block_queue, false)); |
} |
void AppendData(const std::string& source_id, |
@@ -724,14 +808,14 @@ class ChunkDemuxerTest : public ::testing::Test { |
int size = 10; |
wolenetz
2014/07/08 22:45:34
nit: remove unused size and data locals.
acolwell GONE FROM CHROMIUM
2014/07/08 23:01:04
Done.
|
scoped_ptr<uint8[]> data(new uint8[size]); |
- ClusterBuilder cb; |
- cb.SetClusterTimecode(std::min(first_audio_timecode, first_video_timecode)); |
+ std::priority_queue<BlockInfo> block_queue; |
if (block_count == 1) { |
- cb.AddBlockGroup(kAudioTrackNum, first_audio_timecode, |
- kAudioBlockDuration, kWebMFlagKeyframe, |
- data.get(), size); |
- return cb.Finish(); |
+ block_queue.push(BlockInfo(kAudioTrackNum, |
+ first_audio_timecode, |
+ kWebMFlagKeyframe, |
+ kAudioBlockDuration)); |
+ return GenerateCluster(block_queue, unknown_size); |
} |
int audio_timecode = first_audio_timecode; |
@@ -742,33 +826,34 @@ class ChunkDemuxerTest : public ::testing::Test { |
uint8 video_flag = kWebMFlagKeyframe; |
for (int i = 0; i < block_count - 2; i++) { |
if (audio_timecode <= video_timecode) { |
- cb.AddSimpleBlock(kAudioTrackNum, audio_timecode, kWebMFlagKeyframe, |
- data.get(), size); |
+ block_queue.push(BlockInfo(kAudioTrackNum, |
+ audio_timecode, |
+ kWebMFlagKeyframe, |
+ 0)); |
audio_timecode += kAudioBlockDuration; |
continue; |
} |
- cb.AddSimpleBlock(kVideoTrackNum, video_timecode, video_flag, data.get(), |
- size); |
+ block_queue.push(BlockInfo(kVideoTrackNum, |
+ video_timecode, |
+ video_flag, |
+ 0)); |
video_timecode += kVideoBlockDuration; |
video_flag = 0; |
} |
// Make the last 2 blocks BlockGroups so that they don't get delayed by the |
// block duration calculation logic. |
- if (audio_timecode <= video_timecode) { |
- cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration, |
- kWebMFlagKeyframe, data.get(), size); |
- AddVideoBlockGroup(&cb, kVideoTrackNum, video_timecode, |
- kVideoBlockDuration, video_flag); |
- } else { |
- AddVideoBlockGroup(&cb, kVideoTrackNum, video_timecode, |
- kVideoBlockDuration, video_flag); |
- cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration, |
- kWebMFlagKeyframe, data.get(), size); |
- } |
+ block_queue.push(BlockInfo(kAudioTrackNum, |
+ audio_timecode, |
+ kWebMFlagKeyframe, |
+ kAudioBlockDuration)); |
+ block_queue.push(BlockInfo(kVideoTrackNum, |
+ video_timecode, |
+ video_flag, |
+ kVideoBlockDuration)); |
- return unknown_size ? cb.FinishWithUnknownSize() : cb.Finish(); |
+ return GenerateCluster(block_queue, unknown_size); |
} |
scoped_ptr<Cluster> GenerateSingleStreamCluster(int timecode, |
@@ -1290,21 +1375,19 @@ TEST_F(ChunkDemuxerTest, InitSegmentSetsNeedRandomAccessPointFlag) { |
AppendMuxedCluster( |
MuxedStreamInfo(kAudioTrackNum, "0 23K"), |
MuxedStreamInfo(kVideoTrackNum, "0 30K"), |
- MuxedStreamInfo(kTextTrackNum, "0 40K")); |
- CheckExpectedRanges(kSourceId, "{ [30,46) }"); |
+ MuxedStreamInfo(kTextTrackNum, "25K 40K")); |
+ CheckExpectedRanges(kSourceId, "{ [23,46) }"); |
AppendInitSegment(HAS_TEXT | HAS_AUDIO | HAS_VIDEO); |
AppendMuxedCluster( |
MuxedStreamInfo(kAudioTrackNum, "46 69K"), |
MuxedStreamInfo(kVideoTrackNum, "60 90K"), |
- MuxedStreamInfo(kTextTrackNum, "80 90K")); |
- CheckExpectedRanges(kSourceId, "{ [30,92) }"); |
+ MuxedStreamInfo(kTextTrackNum, "80K 90K")); |
+ CheckExpectedRanges(kSourceId, "{ [23,92) }"); |
CheckExpectedBuffers(audio_stream, "23 69"); |
CheckExpectedBuffers(video_stream, "30 90"); |
- |
- // WebM parser marks all text buffers as keyframes. |
- CheckExpectedBuffers(text_stream, "0 40 80 90"); |
+ CheckExpectedBuffers(text_stream, "25 40 80 90"); |
} |
// Make sure that the demuxer reports an error if Shutdown() |
@@ -2468,7 +2551,6 @@ TEST_F(ChunkDemuxerTest, GetBufferedRanges_EndOfStream) { |
// Append and remove data so that the 2 streams' end ranges do not overlap. |
- EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(246))); |
EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(398))); |
AppendMuxedCluster( |
MuxedStreamInfo(kAudioTrackNum, "200K 223K"), |
@@ -3353,7 +3435,7 @@ TEST_F(ChunkDemuxerTest, AppendWindow_Text) { |
// Verify that text cues that start outside the window are not included |
// in the buffer. Also verify that cues that extend beyond the |
// window are not included. |
- CheckExpectedRanges(kSourceId, "{ [120,270) }"); |
+ CheckExpectedRanges(kSourceId, "{ [100,270) }"); |
CheckExpectedBuffers(video_stream, "120 150 180 210 240"); |
CheckExpectedBuffers(text_stream, "100"); |
@@ -3365,7 +3447,7 @@ TEST_F(ChunkDemuxerTest, AppendWindow_Text) { |
MuxedStreamInfo(kVideoTrackNum, |
"360 390 420K 450 480 510 540K 570 600 630K"), |
MuxedStreamInfo(kTextTrackNum, "400K 500K 600K 700K" )); |
- CheckExpectedRanges(kSourceId, "{ [120,270) [420,630) }"); |
+ CheckExpectedRanges(kSourceId, "{ [100,270) [400,630) }"); |
// Seek to the new range and verify that the expected buffers are returned. |
Seek(base::TimeDelta::FromMilliseconds(420)); |
@@ -3498,7 +3580,7 @@ TEST_F(ChunkDemuxerTest, SeekCompletesWithoutTextCues) { |
message_loop_.RunUntilIdle(); |
EXPECT_TRUE(text_read_done); |
- // NOTE: we start at 175 here because the buffer at 125 was returned |
+ // NOTE: we start at 275 here because the buffer at 225 was returned |
// to the pending read initiated above. |
CheckExpectedBuffers(text_stream, "275 325"); |