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

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

Issue 321233004: MSE: Remap single text track number changes in frame processor (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixes a couple nits Created 6 years, 6 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/frame_processor_base.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" 9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_split.h" 10 #include "base/strings/string_split.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 // The size of TrackEntry element in test file "webm_vp8_track_entry" starts at 59 // The size of TrackEntry element in test file "webm_vp8_track_entry" starts at
60 // index 1 and spans 8 bytes. 60 // index 1 and spans 8 bytes.
61 const int kVideoTrackSizeOffset = 1; 61 const int kVideoTrackSizeOffset = 1;
62 const int kVideoTrackSizeWidth = 8; 62 const int kVideoTrackSizeWidth = 8;
63 const int kVideoTrackEntryHeaderSize = 63 const int kVideoTrackEntryHeaderSize =
64 kVideoTrackSizeOffset + kVideoTrackSizeWidth; 64 kVideoTrackSizeOffset + kVideoTrackSizeWidth;
65 65
66 const int kVideoTrackNum = 1; 66 const int kVideoTrackNum = 1;
67 const int kAudioTrackNum = 2; 67 const int kAudioTrackNum = 2;
68 const int kTextTrackNum = 3; 68 const int kTextTrackNum = 3;
69 const int kAlternateTextTrackNum = 4;
69 70
70 const int kAudioBlockDuration = 23; 71 const int kAudioBlockDuration = 23;
71 const int kVideoBlockDuration = 33; 72 const int kVideoBlockDuration = 33;
72 const int kTextBlockDuration = 100; 73 const int kTextBlockDuration = 100;
73 const int kBlockSize = 10; 74 const int kBlockSize = 10;
74 75
75 const char kSourceId[] = "SourceId"; 76 const char kSourceId[] = "SourceId";
76 const char kDefaultFirstClusterRange[] = "{ [0,46) }"; 77 const char kDefaultFirstClusterRange[] = "{ [0,46) }";
77 const int kDefaultFirstClusterEndTimestamp = 66; 78 const int kDefaultFirstClusterEndTimestamp = 66;
78 const int kDefaultSecondClusterEndTimestamp = 132; 79 const int kDefaultSecondClusterEndTimestamp = 132;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this)); 172 base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this));
172 demuxer_.reset( 173 demuxer_.reset(
173 new ChunkDemuxer(open_cb, need_key_cb, base::Bind(&LogFunc), true)); 174 new ChunkDemuxer(open_cb, need_key_cb, base::Bind(&LogFunc), true));
174 } 175 }
175 176
176 virtual ~ChunkDemuxerTest() { 177 virtual ~ChunkDemuxerTest() {
177 ShutdownDemuxer(); 178 ShutdownDemuxer();
178 } 179 }
179 180
180 void CreateInitSegment(int stream_flags, 181 void CreateInitSegment(int stream_flags,
181 bool is_audio_encrypted, bool is_video_encrypted, 182 bool is_audio_encrypted,
183 bool is_video_encrypted,
182 scoped_ptr<uint8[]>* buffer, 184 scoped_ptr<uint8[]>* buffer,
183 int* size) { 185 int* size) {
186 CreateInitSegmentInternal(
187 stream_flags, is_audio_encrypted, is_video_encrypted, buffer, false,
188 size);
189 }
190
191 void CreateInitSegmentWithAlternateTextTrackNum(int stream_flags,
192 bool is_audio_encrypted,
193 bool is_video_encrypted,
194 scoped_ptr<uint8[]>* buffer,
195 int* size) {
196 DCHECK(stream_flags & HAS_TEXT);
197 CreateInitSegmentInternal(
198 stream_flags, is_audio_encrypted, is_video_encrypted, buffer, true,
199 size);
200 }
201
202 void CreateInitSegmentInternal(int stream_flags,
203 bool is_audio_encrypted,
204 bool is_video_encrypted,
205 scoped_ptr<uint8[]>* buffer,
206 bool use_alternate_text_track_id,
207 int* size) {
184 bool has_audio = (stream_flags & HAS_AUDIO) != 0; 208 bool has_audio = (stream_flags & HAS_AUDIO) != 0;
185 bool has_video = (stream_flags & HAS_VIDEO) != 0; 209 bool has_video = (stream_flags & HAS_VIDEO) != 0;
186 bool has_text = (stream_flags & HAS_TEXT) != 0; 210 bool has_text = (stream_flags & HAS_TEXT) != 0;
187 scoped_refptr<DecoderBuffer> ebml_header; 211 scoped_refptr<DecoderBuffer> ebml_header;
188 scoped_refptr<DecoderBuffer> info; 212 scoped_refptr<DecoderBuffer> info;
189 scoped_refptr<DecoderBuffer> audio_track_entry; 213 scoped_refptr<DecoderBuffer> audio_track_entry;
190 scoped_refptr<DecoderBuffer> video_track_entry; 214 scoped_refptr<DecoderBuffer> video_track_entry;
191 scoped_refptr<DecoderBuffer> audio_content_encodings; 215 scoped_refptr<DecoderBuffer> audio_content_encodings;
192 scoped_refptr<DecoderBuffer> video_content_encodings; 216 scoped_refptr<DecoderBuffer> video_content_encodings;
193 scoped_refptr<DecoderBuffer> text_track_entry; 217 scoped_refptr<DecoderBuffer> text_track_entry;
(...skipping 22 matching lines...) Expand all
216 } 240 }
217 } 241 }
218 242
219 if (has_text) { 243 if (has_text) {
220 // TODO(matthewjheaney): create an abstraction to do 244 // TODO(matthewjheaney): create an abstraction to do
221 // this (http://crbug/321454). 245 // this (http://crbug/321454).
222 // We need it to also handle the creation of multiple text tracks. 246 // We need it to also handle the creation of multiple text tracks.
223 // 247 //
224 // This is the track entry for a text track, 248 // This is the track entry for a text track,
225 // TrackEntry [AE], size=30 249 // TrackEntry [AE], size=30
226 // TrackNum [D7], size=1, val=3 250 // TrackNum [D7], size=1, val=3 (or 4 if use_alternate_text_track_id)
227 // TrackUID [73] [C5], size=1, value=3 251 // TrackUID [73] [C5], size=1, value=3 (must remain constant for same
252 // track, even if TrackNum changes)
228 // TrackType [83], size=1, val=0x11 253 // TrackType [83], size=1, val=0x11
229 // CodecId [86], size=18, val="D_WEBVTT/SUBTITLES" 254 // CodecId [86], size=18, val="D_WEBVTT/SUBTITLES"
230 const char str[] = "\xAE\x9E\xD7\x81\x03\x73\xC5\x81\x03" 255 char str[] = "\xAE\x9E\xD7\x81\x03\x73\xC5\x81\x03"
231 "\x83\x81\x11\x86\x92" 256 "\x83\x81\x11\x86\x92"
232 "D_WEBVTT/SUBTITLES"; 257 "D_WEBVTT/SUBTITLES";
258 DCHECK_EQ(str[4], kTextTrackNum);
259 if (use_alternate_text_track_id)
260 str[4] = kAlternateTextTrackNum;
261
233 const int len = strlen(str); 262 const int len = strlen(str);
234 DCHECK_EQ(len, 32); 263 DCHECK_EQ(len, 32);
235 const uint8* const buf = reinterpret_cast<const uint8*>(str); 264 const uint8* const buf = reinterpret_cast<const uint8*>(str);
236 text_track_entry = DecoderBuffer::CopyFrom(buf, len); 265 text_track_entry = DecoderBuffer::CopyFrom(buf, len);
237 tracks_element_size += text_track_entry->data_size(); 266 tracks_element_size += text_track_entry->data_size();
238 } 267 }
239 268
240 *size = ebml_header->data_size() + info->data_size() + 269 *size = ebml_header->data_size() + info->data_size() +
241 kTracksHeaderSize + tracks_element_size; 270 kTracksHeaderSize + tracks_element_size;
242 271
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 void AppendSingleStreamCluster(const std::string& source_id, int track_number, 380 void AppendSingleStreamCluster(const std::string& source_id, int track_number,
352 int timecode, int block_count) { 381 int timecode, int block_count) {
353 int block_duration = 0; 382 int block_duration = 0;
354 switch (track_number) { 383 switch (track_number) {
355 case kVideoTrackNum: 384 case kVideoTrackNum:
356 block_duration = kVideoBlockDuration; 385 block_duration = kVideoBlockDuration;
357 break; 386 break;
358 case kAudioTrackNum: 387 case kAudioTrackNum:
359 block_duration = kAudioBlockDuration; 388 block_duration = kAudioBlockDuration;
360 break; 389 break;
361 case kTextTrackNum: 390 case kTextTrackNum: // Fall-through.
391 case kAlternateTextTrackNum:
362 block_duration = kTextBlockDuration; 392 block_duration = kTextBlockDuration;
363 break; 393 break;
364 } 394 }
365 ASSERT_NE(block_duration, 0); 395 ASSERT_NE(block_duration, 0);
366 int end_timecode = timecode + block_count * block_duration; 396 int end_timecode = timecode + block_count * block_duration;
367 AppendCluster(source_id, 397 AppendCluster(source_id,
368 GenerateSingleStreamCluster( 398 GenerateSingleStreamCluster(
369 timecode, end_timecode, track_number, block_duration)); 399 timecode, end_timecode, track_number, block_duration));
370 } 400 }
371 401
(...skipping 17 matching lines...) Expand all
389 block_flags = kWebMFlagKeyframe; 419 block_flags = kWebMFlagKeyframe;
390 // Remove the "K" off of the token. 420 // Remove the "K" off of the token.
391 timestamp_str = timestamp_str.substr(0, timestamps[i].length() - 1); 421 timestamp_str = timestamp_str.substr(0, timestamps[i].length() - 1);
392 } 422 }
393 int timestamp_in_ms; 423 int timestamp_in_ms;
394 CHECK(base::StringToInt(timestamp_str, &timestamp_in_ms)); 424 CHECK(base::StringToInt(timestamp_str, &timestamp_in_ms));
395 425
396 if (i == 0) 426 if (i == 0)
397 cb.SetClusterTimecode(timestamp_in_ms); 427 cb.SetClusterTimecode(timestamp_in_ms);
398 428
399 if (track_number == kTextTrackNum) { 429 if (track_number == kTextTrackNum ||
430 track_number == kAlternateTextTrackNum) {
400 cb.AddBlockGroup(track_number, timestamp_in_ms, kTextBlockDuration, 431 cb.AddBlockGroup(track_number, timestamp_in_ms, kTextBlockDuration,
401 block_flags, &data[0], data.size()); 432 block_flags, &data[0], data.size());
402 } else { 433 } else {
403 cb.AddSimpleBlock(track_number, timestamp_in_ms, block_flags, 434 cb.AddSimpleBlock(track_number, timestamp_in_ms, block_flags,
404 &data[0], data.size()); 435 &data[0], data.size());
405 } 436 }
406 } 437 }
407 AppendCluster(source_id, cb.Finish()); 438 AppendCluster(source_id, cb.Finish());
408 } 439 }
409 440
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 ->supports_partial_append_window_trimming()); 1171 ->supports_partial_append_window_trimming());
1141 } else { 1172 } else {
1142 EXPECT_FALSE(video_stream); 1173 EXPECT_FALSE(video_stream);
1143 } 1174 }
1144 1175
1145 ShutdownDemuxer(); 1176 ShutdownDemuxer();
1146 demuxer_.reset(); 1177 demuxer_.reset();
1147 } 1178 }
1148 } 1179 }
1149 1180
1181 TEST_P(ChunkDemuxerTest, SingleTextTrackIdChange) {
1182 // Test with 1 video stream, 1 audio, and 1 text stream. Send a second init
1183 // segment in which the text track ID changes. Verify appended buffers before
1184 // and after the second init segment map to the same underlying track buffers.
1185 CreateNewDemuxer();
1186 DemuxerStream* text_stream = NULL;
1187 TextTrackConfig text_config;
1188 EXPECT_CALL(host_, AddTextStream(_, _))
1189 .WillOnce(DoAll(SaveArg<0>(&text_stream),
1190 SaveArg<1>(&text_config)));
1191 ASSERT_TRUE(InitDemuxerWithEncryptionInfo(
1192 HAS_TEXT | HAS_AUDIO | HAS_VIDEO, false, false));
1193 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
1194 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
1195 ASSERT_TRUE(audio_stream);
1196 ASSERT_TRUE(video_stream);
1197 ASSERT_TRUE(text_stream);
1198
1199 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K 23K");
1200 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0K 30");
1201 AppendSingleStreamCluster(kSourceId, kTextTrackNum, "10K");
1202 CheckExpectedRanges(kSourceId, "{ [0,46) }");
1203
1204 scoped_ptr<uint8[]> info_tracks;
1205 int info_tracks_size = 0;
1206 CreateInitSegmentWithAlternateTextTrackNum(HAS_TEXT | HAS_AUDIO | HAS_VIDEO,
1207 false, false,
1208 &info_tracks, &info_tracks_size);
1209 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size,
1210 append_window_start_for_next_append_,
1211 append_window_end_for_next_append_,
1212 &timestamp_offset_map_[kSourceId]);
1213
1214 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "46K 69K");
1215 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "60K");
1216 AppendSingleStreamCluster(kSourceId, kAlternateTextTrackNum, "45K");
1217
1218 CheckExpectedRanges(kSourceId, "{ [0,92) }");
1219 CheckExpectedBuffers(audio_stream, "0 23 46 69");
1220 CheckExpectedBuffers(video_stream, "0 30 60");
1221 CheckExpectedBuffers(text_stream, "10 45");
1222
1223 ShutdownDemuxer();
1224 }
1225
1150 // Make sure that the demuxer reports an error if Shutdown() 1226 // Make sure that the demuxer reports an error if Shutdown()
1151 // is called before all the initialization segments are appended. 1227 // is called before all the initialization segments are appended.
1152 TEST_P(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) { 1228 TEST_P(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) {
1153 EXPECT_CALL(*this, DemuxerOpened()); 1229 EXPECT_CALL(*this, DemuxerOpened());
1154 demuxer_->Initialize( 1230 demuxer_->Initialize(
1155 &host_, CreateInitDoneCB( 1231 &host_, CreateInitDoneCB(
1156 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); 1232 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true);
1157 1233
1158 EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); 1234 EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk);
1159 EXPECT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk); 1235 EXPECT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk);
(...skipping 2182 matching lines...) Expand 10 before | Expand all | Expand 10 after
3342 CheckExpectedBuffers(audio_stream, "160 180"); 3418 CheckExpectedBuffers(audio_stream, "160 180");
3343 CheckExpectedBuffers(video_stream, "180 210"); 3419 CheckExpectedBuffers(video_stream, "180 210");
3344 } 3420 }
3345 3421
3346 // Generate two sets of tests: one using FrameProcessor, and one using 3422 // Generate two sets of tests: one using FrameProcessor, and one using
3347 // LegacyFrameProcessor. 3423 // LegacyFrameProcessor.
3348 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, ChunkDemuxerTest, Values(false)); 3424 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, ChunkDemuxerTest, Values(false));
3349 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, ChunkDemuxerTest, Values(true)); 3425 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, ChunkDemuxerTest, Values(true));
3350 3426
3351 } // namespace media 3427 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/chunk_demuxer.cc ('k') | media/filters/frame_processor_base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698