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

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

Issue 13813016: Remove reference counting from media::Demuxer and friends. (Closed) Base URL: http://git.chromium.org/chromium/src.git@vd_scoped
Patch Set: Created 7 years, 8 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
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 "media/filters/pipeline_integration_test_base.h" 5 #include "media/filters/pipeline_integration_test_base.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 223
224 // Helper class that emulates calls made on the ChunkDemuxer by the 224 // Helper class that emulates calls made on the ChunkDemuxer by the
225 // Media Source API. 225 // Media Source API.
226 class MockMediaSource { 226 class MockMediaSource {
227 public: 227 public:
228 MockMediaSource(const std::string& filename, const std::string& mimetype, 228 MockMediaSource(const std::string& filename, const std::string& mimetype,
229 int initial_append_size) 229 int initial_append_size)
230 : file_path_(GetTestDataFilePath(filename)), 230 : file_path_(GetTestDataFilePath(filename)),
231 current_position_(0), 231 current_position_(0),
232 initial_append_size_(initial_append_size), 232 initial_append_size_(initial_append_size),
233 mimetype_(mimetype) { 233 mimetype_(mimetype),
234 chunk_demuxer_ = new ChunkDemuxer( 234 chunk_demuxer_(new ChunkDemuxer(
235 base::Bind(&MockMediaSource::DemuxerOpened, base::Unretained(this)), 235 base::Bind(&MockMediaSource::DemuxerOpened,
236 base::Bind(&MockMediaSource::DemuxerNeedKey, base::Unretained(this)), 236 base::Unretained(this)),
237 LogCB()); 237 base::Bind(&MockMediaSource::DemuxerNeedKey,
238 base::Unretained(this)),
239 LogCB())),
240 owned_chunk_demuxer_(chunk_demuxer_) {
238 241
239 file_data_ = ReadTestDataFile(filename); 242 file_data_ = ReadTestDataFile(filename);
240 243
241 if (initial_append_size_ == kAppendWholeFile) 244 if (initial_append_size_ == kAppendWholeFile)
242 initial_append_size_ = file_data_->GetDataSize(); 245 initial_append_size_ = file_data_->GetDataSize();
243 246
244 DCHECK_GT(initial_append_size_, 0); 247 DCHECK_GT(initial_append_size_, 0);
245 DCHECK_LE(initial_append_size_, file_data_->GetDataSize()); 248 DCHECK_LE(initial_append_size_, file_data_->GetDataSize());
246 } 249 }
247 250
248 virtual ~MockMediaSource() {} 251 virtual ~MockMediaSource() {}
249 252
250 const scoped_refptr<ChunkDemuxer>& demuxer() const { return chunk_demuxer_; } 253 scoped_ptr<Demuxer> GetDemuxer() { return owned_chunk_demuxer_.Pass(); }
251 254
252 void set_need_key_cb(const NeedKeyCB& need_key_cb) { 255 void set_need_key_cb(const NeedKeyCB& need_key_cb) {
253 need_key_cb_ = need_key_cb; 256 need_key_cb_ = need_key_cb;
254 } 257 }
255 258
256 void Seek(int new_position, int seek_append_size) { 259 void Seek(int new_position, int seek_append_size) {
257 chunk_demuxer_->StartWaitingForSeek(); 260 chunk_demuxer_->StartWaitingForSeek();
258 261
259 chunk_demuxer_->Abort(kSourceId); 262 chunk_demuxer_->Abort(kSourceId);
260 263
261 DCHECK_GE(new_position, 0); 264 DCHECK_GE(new_position, 0);
262 DCHECK_LT(new_position, file_data_->GetDataSize()); 265 DCHECK_LT(new_position, file_data_->GetDataSize());
263 current_position_ = new_position; 266 current_position_ = new_position;
264 267
265 AppendData(seek_append_size); 268 AppendData(seek_append_size);
266 } 269 }
267 270
268 void AppendData(int size) { 271 void AppendData(int size) {
269 DCHECK(chunk_demuxer_.get()); 272 DCHECK(chunk_demuxer_);
270 DCHECK_LT(current_position_, file_data_->GetDataSize()); 273 DCHECK_LT(current_position_, file_data_->GetDataSize());
271 DCHECK_LE(current_position_ + size, file_data_->GetDataSize()); 274 DCHECK_LE(current_position_ + size, file_data_->GetDataSize());
272 chunk_demuxer_->AppendData( 275 chunk_demuxer_->AppendData(
273 kSourceId, file_data_->GetData() + current_position_, size); 276 kSourceId, file_data_->GetData() + current_position_, size);
274 current_position_ += size; 277 current_position_ += size;
275 } 278 }
276 279
277 void AppendAtTime(const base::TimeDelta& timestampOffset, 280 void AppendAtTime(const base::TimeDelta& timestampOffset,
278 const uint8* pData, int size) { 281 const uint8* pData, int size) {
279 CHECK(chunk_demuxer_->SetTimestampOffset(kSourceId, timestampOffset)); 282 CHECK(chunk_demuxer_->SetTimestampOffset(kSourceId, timestampOffset));
280 chunk_demuxer_->AppendData(kSourceId, pData, size); 283 chunk_demuxer_->AppendData(kSourceId, pData, size);
281 CHECK(chunk_demuxer_->SetTimestampOffset(kSourceId, base::TimeDelta())); 284 CHECK(chunk_demuxer_->SetTimestampOffset(kSourceId, base::TimeDelta()));
282 } 285 }
283 286
284 void EndOfStream() { 287 void EndOfStream() {
285 chunk_demuxer_->EndOfStream(PIPELINE_OK); 288 chunk_demuxer_->EndOfStream(PIPELINE_OK);
286 } 289 }
287 290
288 void Abort() { 291 void Abort() {
289 if (!chunk_demuxer_.get()) 292 if (!chunk_demuxer_)
290 return; 293 return;
291 chunk_demuxer_->Shutdown(); 294 chunk_demuxer_->Shutdown();
292 chunk_demuxer_ = NULL; 295 chunk_demuxer_ = NULL;
293 } 296 }
294 297
295 void DemuxerOpened() { 298 void DemuxerOpened() {
296 MessageLoop::current()->PostTask( 299 MessageLoop::current()->PostTask(
297 FROM_HERE, base::Bind(&MockMediaSource::DemuxerOpenedTask, 300 FROM_HERE, base::Bind(&MockMediaSource::DemuxerOpenedTask,
298 base::Unretained(this))); 301 base::Unretained(this)));
299 } 302 }
(...skipping 19 matching lines...) Expand all
319 need_key_cb_.Run( 322 need_key_cb_.Run(
320 std::string(), std::string(), type, init_data.Pass(), init_data_size); 323 std::string(), std::string(), type, init_data.Pass(), init_data_size);
321 } 324 }
322 325
323 private: 326 private:
324 base::FilePath file_path_; 327 base::FilePath file_path_;
325 scoped_refptr<DecoderBuffer> file_data_; 328 scoped_refptr<DecoderBuffer> file_data_;
326 int current_position_; 329 int current_position_;
327 int initial_append_size_; 330 int initial_append_size_;
328 std::string mimetype_; 331 std::string mimetype_;
329 scoped_refptr<ChunkDemuxer> chunk_demuxer_; 332 ChunkDemuxer* chunk_demuxer_;
333 scoped_ptr<Demuxer> owned_chunk_demuxer_;
330 NeedKeyCB need_key_cb_; 334 NeedKeyCB need_key_cb_;
331 }; 335 };
332 336
333 class PipelineIntegrationTest 337 class PipelineIntegrationTest
334 : public testing::Test, 338 : public testing::Test,
335 public PipelineIntegrationTestBase { 339 public PipelineIntegrationTestBase {
336 public: 340 public:
337 void StartPipelineWithMediaSource(MockMediaSource* source) { 341 void StartPipelineWithMediaSource(MockMediaSource* source) {
338 EXPECT_CALL(*this, OnBufferingState(Pipeline::kHaveMetadata)) 342 EXPECT_CALL(*this, OnBufferingState(Pipeline::kHaveMetadata))
339 .Times(AtMost(1)); 343 .Times(AtMost(1));
340 EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted)) 344 EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted))
341 .Times(AtMost(1)); 345 .Times(AtMost(1));
342 pipeline_->Start( 346 pipeline_->Start(
343 CreateFilterCollection(source->demuxer(), NULL), 347 CreateFilterCollection(source->GetDemuxer(), NULL),
344 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)), 348 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
345 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)), 349 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
346 QuitOnStatusCB(PIPELINE_OK), 350 QuitOnStatusCB(PIPELINE_OK),
347 base::Bind(&PipelineIntegrationTest::OnBufferingState, 351 base::Bind(&PipelineIntegrationTest::OnBufferingState,
348 base::Unretained(this)), 352 base::Unretained(this)),
349 base::Closure()); 353 base::Closure());
350 354
351 message_loop_.Run(); 355 message_loop_.Run();
352 } 356 }
353 357
354 void StartPipelineWithEncryptedMedia( 358 void StartPipelineWithEncryptedMedia(
355 MockMediaSource* source, 359 MockMediaSource* source,
356 FakeEncryptedMedia* encrypted_media) { 360 FakeEncryptedMedia* encrypted_media) {
357 EXPECT_CALL(*this, OnBufferingState(Pipeline::kHaveMetadata)) 361 EXPECT_CALL(*this, OnBufferingState(Pipeline::kHaveMetadata))
358 .Times(AtMost(1)); 362 .Times(AtMost(1));
359 EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted)) 363 EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted))
360 .Times(AtMost(1)); 364 .Times(AtMost(1));
361 pipeline_->Start( 365 pipeline_->Start(
362 CreateFilterCollection(source->demuxer(), encrypted_media->decryptor()), 366 CreateFilterCollection(source->GetDemuxer(),
367 encrypted_media->decryptor()),
363 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)), 368 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
364 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)), 369 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
365 QuitOnStatusCB(PIPELINE_OK), 370 QuitOnStatusCB(PIPELINE_OK),
366 base::Bind(&PipelineIntegrationTest::OnBufferingState, 371 base::Bind(&PipelineIntegrationTest::OnBufferingState,
367 base::Unretained(this)), 372 base::Unretained(this)),
368 base::Closure()); 373 base::Closure());
369 374
370 source->set_need_key_cb(base::Bind(&FakeEncryptedMedia::NeedKey, 375 source->set_need_key_cb(base::Bind(&FakeEncryptedMedia::NeedKey,
371 base::Unretained(encrypted_media))); 376 base::Unretained(encrypted_media)));
372 377
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 557
553 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); 558 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
554 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); 559 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
555 // The second video was not added, so its time has not been added. 560 // The second video was not added, so its time has not been added.
556 EXPECT_EQ(k320WebMFileDurationMs, 561 EXPECT_EQ(k320WebMFileDurationMs,
557 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); 562 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
558 563
559 Play(); 564 Play();
560 565
561 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError()); 566 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
562 source.Abort(); 567 // XXX this is use after free because pipeline destroys demuxers on error
scherkus (not reviewing) 2013/04/17 17:21:59 FYI
568 // source.Abort();
563 } 569 }
564 570
565 // Config changes from clear to encrypted are not currently supported. 571 // Config changes from clear to encrypted are not currently supported.
566 TEST_F(PipelineIntegrationTest, 572 TEST_F(PipelineIntegrationTest,
567 MediaSource_ConfigChange_EncryptedThenClear_WebM) { 573 MediaSource_ConfigChange_EncryptedThenClear_WebM) {
568 MockMediaSource source("bear-320x240-16x9-aspect-av_enc-av.webm", kWebM, 574 MockMediaSource source("bear-320x240-16x9-aspect-av_enc-av.webm", kWebM,
569 kAppendWholeFile); 575 kAppendWholeFile);
570 FakeEncryptedMedia encrypted_media(new KeyProvidingApp()); 576 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
571 StartPipelineWithEncryptedMedia(&source, &encrypted_media); 577 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
572 578
573 scoped_refptr<DecoderBuffer> second_file = 579 scoped_refptr<DecoderBuffer> second_file =
574 ReadTestDataFile("bear-640x360.webm"); 580 ReadTestDataFile("bear-640x360.webm");
575 581
576 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec), 582 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
577 second_file->GetData(), second_file->GetDataSize()); 583 second_file->GetData(), second_file->GetDataSize());
578 584
579 source.EndOfStream(); 585 source.EndOfStream();
580 586
581 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); 587 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
582 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); 588 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
583 // The second video was not added, so its time has not been added. 589 // The second video was not added, so its time has not been added.
584 EXPECT_EQ(k320WebMFileDurationMs, 590 EXPECT_EQ(k320WebMFileDurationMs,
585 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); 591 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
586 592
587 Play(); 593 Play();
588 594
589 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError()); 595 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
590 source.Abort(); 596 // XXX this is use after free because pipeline destroys demuxers on error
scherkus (not reviewing) 2013/04/17 17:21:59 FYI
597 // source.Abort();
591 } 598 }
592 599
593 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS) 600 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS)
594 TEST_F(PipelineIntegrationTest, MediaSource_ConfigChange_MP4) { 601 TEST_F(PipelineIntegrationTest, MediaSource_ConfigChange_MP4) {
595 MockMediaSource source("bear-640x360-av_frag.mp4", kMP4, kAppendWholeFile); 602 MockMediaSource source("bear-640x360-av_frag.mp4", kMP4, kAppendWholeFile);
596 StartPipelineWithMediaSource(&source); 603 StartPipelineWithMediaSource(&source);
597 604
598 scoped_refptr<DecoderBuffer> second_file = 605 scoped_refptr<DecoderBuffer> second_file =
599 ReadTestDataFile("bear-1280x720-av_frag.mp4"); 606 ReadTestDataFile("bear-1280x720-av_frag.mp4");
600 607
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 671
665 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); 672 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
666 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); 673 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
667 // The second video was not added, so its time has not been added. 674 // The second video was not added, so its time has not been added.
668 EXPECT_EQ(k640IsoFileDurationMs, 675 EXPECT_EQ(k640IsoFileDurationMs,
669 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); 676 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
670 677
671 Play(); 678 Play();
672 679
673 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError()); 680 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
674 source.Abort(); 681 // XXX this is use after free because pipeline destroys demuxers on error
scherkus (not reviewing) 2013/04/17 17:21:59 FYI
682 // source.Abort();
675 } 683 }
676 684
677 // Config changes from encrypted to clear are not currently supported. 685 // Config changes from encrypted to clear are not currently supported.
678 TEST_F(PipelineIntegrationTest, 686 TEST_F(PipelineIntegrationTest,
679 MediaSource_ConfigChange_EncryptedThenClear_MP4_CENC) { 687 MediaSource_ConfigChange_EncryptedThenClear_MP4_CENC) {
680 MockMediaSource source("bear-640x360-v_frag-cenc.mp4", 688 MockMediaSource source("bear-640x360-v_frag-cenc.mp4",
681 kMP4Video, kAppendWholeFile); 689 kMP4Video, kAppendWholeFile);
682 FakeEncryptedMedia encrypted_media(new KeyProvidingApp()); 690 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
683 StartPipelineWithEncryptedMedia(&source, &encrypted_media); 691 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
684 692
685 scoped_refptr<DecoderBuffer> second_file = 693 scoped_refptr<DecoderBuffer> second_file =
686 ReadTestDataFile("bear-1280x720-av_frag.mp4"); 694 ReadTestDataFile("bear-1280x720-av_frag.mp4");
687 695
688 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec), 696 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
689 second_file->GetData(), second_file->GetDataSize()); 697 second_file->GetData(), second_file->GetDataSize());
690 698
691 source.EndOfStream(); 699 source.EndOfStream();
692 700
693 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); 701 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
694 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); 702 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
695 // The second video was not added, so its time has not been added. 703 // The second video was not added, so its time has not been added.
696 EXPECT_EQ(k640IsoCencFileDurationMs, 704 EXPECT_EQ(k640IsoCencFileDurationMs,
697 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); 705 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
698 706
699 Play(); 707 Play();
700 708
701 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError()); 709 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
702 source.Abort(); 710 // XXX this is use after free because pipeline destroys demuxers on error
scherkus (not reviewing) 2013/04/17 17:21:59 FYI
711 // source.Abort();
703 } 712 }
704 713
705 // Verify files which change configuration midstream fail gracefully. 714 // Verify files which change configuration midstream fail gracefully.
706 TEST_F(PipelineIntegrationTest, MidStreamConfigChangesFail) { 715 TEST_F(PipelineIntegrationTest, MidStreamConfigChangesFail) {
707 ASSERT_TRUE(Start( 716 ASSERT_TRUE(Start(
708 GetTestDataFilePath("midstream_config_change.mp3"), PIPELINE_OK)); 717 GetTestDataFilePath("midstream_config_change.mp3"), PIPELINE_OK));
709 Play(); 718 Play();
710 ASSERT_EQ(WaitUntilEndedOrError(), PIPELINE_ERROR_DECODE); 719 ASSERT_EQ(WaitUntilEndedOrError(), PIPELINE_ERROR_DECODE);
711 } 720 }
712 721
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 // back. 926 // back.
918 // Disabled since it might crash or corrupt heap, see http://crbug.com/173333 927 // Disabled since it might crash or corrupt heap, see http://crbug.com/173333
919 TEST_F(PipelineIntegrationTest, DISABLED_BasicPlayback_VP9_Opus_WebM) { 928 TEST_F(PipelineIntegrationTest, DISABLED_BasicPlayback_VP9_Opus_WebM) {
920 ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp9-opus.webm"), 929 ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp9-opus.webm"),
921 PIPELINE_OK)); 930 PIPELINE_OK));
922 Play(); 931 Play();
923 ASSERT_TRUE(WaitUntilOnEnded()); 932 ASSERT_TRUE(WaitUntilOnEnded());
924 } 933 }
925 934
926 } // namespace media 935 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698