OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // The bulk of this file is support code; sorry about that. Here's an overview | 5 // The bulk of this file is support code; sorry about that. Here's an overview |
6 // to hopefully help readers of this code: | 6 // to hopefully help readers of this code: |
7 // - RenderingHelper is charged with interacting with X11, EGL, and GLES2. | 7 // - RenderingHelper is charged with interacting with X11, EGL, and GLES2. |
8 // - ClientState is an enum for the state of the decode client used by the test. | 8 // - ClientState is an enum for the state of the decode client used by the test. |
9 // - ClientStateNotification is a barrier abstraction that allows the test code | 9 // - ClientStateNotification is a barrier abstraction that allows the test code |
10 // to be written sequentially and wait for the decode client to see certain | 10 // to be written sequentially and wait for the decode client to see certain |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 const gfx::Size& dimensions, | 414 const gfx::Size& dimensions, |
415 VideoDecodeAccelerator::MemoryType type); | 415 VideoDecodeAccelerator::MemoryType type); |
416 virtual void DismissPictureBuffer(int32 picture_buffer_id); | 416 virtual void DismissPictureBuffer(int32 picture_buffer_id); |
417 virtual void PictureReady(const media::Picture& picture); | 417 virtual void PictureReady(const media::Picture& picture); |
418 // Simple state changes. | 418 // Simple state changes. |
419 virtual void NotifyInitializeDone(); | 419 virtual void NotifyInitializeDone(); |
420 virtual void NotifyEndOfStream(); | 420 virtual void NotifyEndOfStream(); |
421 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id); | 421 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id); |
422 virtual void NotifyFlushDone(); | 422 virtual void NotifyFlushDone(); |
423 virtual void NotifyResetDone(); | 423 virtual void NotifyResetDone(); |
424 virtual void NotifyDestroyDone(); | |
425 virtual void NotifyError(VideoDecodeAccelerator::Error error); | 424 virtual void NotifyError(VideoDecodeAccelerator::Error error); |
426 | 425 |
427 // Simple getters for inspecting the state of the Client. | 426 // Simple getters for inspecting the state of the Client. |
428 ClientState state() { return state_; } | 427 ClientState state() { return state_; } |
429 VideoDecodeAccelerator::Error error() { return error_; } | 428 VideoDecodeAccelerator::Error error() { return error_; } |
430 int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; } | 429 int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; } |
431 int num_decoded_frames() { return num_decoded_frames_; } | 430 int num_decoded_frames() { return num_decoded_frames_; } |
432 EGLDisplay egl_display() { return rendering_helper_->egl_display(); } | 431 EGLDisplay egl_display() { return rendering_helper_->egl_display(); } |
433 EGLContext egl_context() { return rendering_helper_->egl_context(); } | 432 EGLContext egl_context() { return rendering_helper_->egl_context(); } |
434 double frames_per_second(); | 433 double frames_per_second(); |
435 bool decoder_deleted() { return !decoder_.get(); } | 434 bool decoder_deleted() { return !decoder_; } |
436 | 435 |
437 private: | 436 private: |
438 typedef std::map<int, media::GLESBuffer*> PictureBufferById; | 437 typedef std::map<int, media::GLESBuffer*> PictureBufferById; |
439 | 438 |
440 void SetState(ClientState new_state); | 439 void SetState(ClientState new_state); |
441 | 440 |
442 // Delete the associated OMX decoder helper. | 441 // Delete the associated OMX decoder helper. |
443 void DeleteDecoder(); | 442 void DeleteDecoder(); |
444 | 443 |
445 // Compute & return in |*end_pos| the end position for the next batch of NALUs | 444 // Compute & return in |*end_pos| the end position for the next batch of NALUs |
446 // to ship to the decoder (based on |start_pos| & |num_NALUs_per_decode_|). | 445 // to ship to the decoder (based on |start_pos| & |num_NALUs_per_decode_|). |
447 void GetRangeForNextNALUs(size_t start_pos, size_t* end_pos); | 446 void GetRangeForNextNALUs(size_t start_pos, size_t* end_pos); |
448 | 447 |
449 // Request decode of the next batch of NALUs in the encoded data. | 448 // Request decode of the next batch of NALUs in the encoded data. |
450 void DecodeNextNALUs(); | 449 void DecodeNextNALUs(); |
451 | 450 |
452 RenderingHelper* rendering_helper_; | 451 RenderingHelper* rendering_helper_; |
453 int rendering_window_id_; | 452 int rendering_window_id_; |
454 const std::string* encoded_data_; | 453 const std::string* encoded_data_; |
455 const int num_NALUs_per_decode_; | 454 const int num_NALUs_per_decode_; |
456 size_t encoded_data_next_pos_to_decode_; | 455 size_t encoded_data_next_pos_to_decode_; |
457 int next_bitstream_buffer_id_; | 456 int next_bitstream_buffer_id_; |
458 ClientStateNotification* note_; | 457 ClientStateNotification* note_; |
459 scoped_ptr<OmxVideoDecodeAccelerator> decoder_; | 458 scoped_refptr<OmxVideoDecodeAccelerator> decoder_; |
460 int delete_decoder_state_; | 459 int delete_decoder_state_; |
461 ClientState state_; | 460 ClientState state_; |
462 VideoDecodeAccelerator::Error error_; | 461 VideoDecodeAccelerator::Error error_; |
463 int num_decoded_frames_; | 462 int num_decoded_frames_; |
464 int num_done_bitstream_buffers_; | 463 int num_done_bitstream_buffers_; |
465 PictureBufferById picture_buffers_by_id_; | 464 PictureBufferById picture_buffers_by_id_; |
466 base::TimeTicks initialize_done_ticks_; | 465 base::TimeTicks initialize_done_ticks_; |
467 base::TimeTicks last_frame_delivered_ticks_; | 466 base::TimeTicks last_frame_delivered_ticks_; |
468 }; | 467 }; |
469 | 468 |
470 EglRenderingVDAClient::EglRenderingVDAClient(RenderingHelper* rendering_helper, | 469 EglRenderingVDAClient::EglRenderingVDAClient(RenderingHelper* rendering_helper, |
471 int rendering_window_id, | 470 int rendering_window_id, |
472 ClientStateNotification* note, | 471 ClientStateNotification* note, |
473 std::string* encoded_data, | 472 std::string* encoded_data, |
474 int num_NALUs_per_decode, | 473 int num_NALUs_per_decode, |
475 int delete_decoder_state) | 474 int delete_decoder_state) |
476 : rendering_helper_(rendering_helper), | 475 : rendering_helper_(rendering_helper), |
477 rendering_window_id_(rendering_window_id), | 476 rendering_window_id_(rendering_window_id), |
478 encoded_data_(encoded_data), num_NALUs_per_decode_(num_NALUs_per_decode), | 477 encoded_data_(encoded_data), num_NALUs_per_decode_(num_NALUs_per_decode), |
479 encoded_data_next_pos_to_decode_(0), next_bitstream_buffer_id_(0), | 478 encoded_data_next_pos_to_decode_(0), next_bitstream_buffer_id_(0), |
480 note_(note), delete_decoder_state_(delete_decoder_state), | 479 note_(note), delete_decoder_state_(delete_decoder_state), |
481 state_(CS_CREATED), | 480 state_(CS_CREATED), |
482 error_(VideoDecodeAccelerator::VIDEODECODERERROR_NONE), | 481 error_(VideoDecodeAccelerator::VIDEODECODERERROR_NONE), |
483 num_decoded_frames_(0), num_done_bitstream_buffers_(0) { | 482 num_decoded_frames_(0), num_done_bitstream_buffers_(0) { |
484 CHECK_GT(num_NALUs_per_decode, 0); | 483 CHECK_GT(num_NALUs_per_decode, 0); |
485 } | 484 } |
486 | 485 |
487 EglRenderingVDAClient::~EglRenderingVDAClient() { | 486 EglRenderingVDAClient::~EglRenderingVDAClient() { |
488 CHECK(!decoder_.get()); | 487 CHECK(decoder_deleted()); |
489 STLDeleteValues(&picture_buffers_by_id_); | 488 STLDeleteValues(&picture_buffers_by_id_); |
490 SetState(CS_DESTROYED); | 489 SetState(CS_DESTROYED); |
491 } | 490 } |
492 | 491 |
493 void EglRenderingVDAClient::CreateDecoder() { | 492 void EglRenderingVDAClient::CreateDecoder() { |
494 CHECK(!decoder_.get()); | 493 CHECK(decoder_deleted()); |
495 decoder_.reset(new OmxVideoDecodeAccelerator(this)); | 494 decoder_ = new OmxVideoDecodeAccelerator(this); |
496 decoder_->SetEglState(egl_display(), egl_context()); | 495 decoder_->SetEglState(egl_display(), egl_context()); |
497 SetState(CS_DECODER_SET); | 496 SetState(CS_DECODER_SET); |
498 if (!decoder_.get()) | 497 if (decoder_deleted()) |
499 return; | 498 return; |
500 | 499 |
501 // Configure the decoder. | 500 // Configure the decoder. |
502 int32 config_array[] = { | 501 int32 config_array[] = { |
503 media::VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_FOURCC, | 502 media::VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_FOURCC, |
504 media::VIDEOCODECFOURCC_H264, | 503 media::VIDEOCODECFOURCC_H264, |
505 media::VIDEOATTRIBUTEKEY_VIDEOCOLORFORMAT, media::VIDEOCOLORFORMAT_RGBA, | 504 media::VIDEOATTRIBUTEKEY_VIDEOCOLORFORMAT, media::VIDEOCOLORFORMAT_RGBA, |
506 }; | 505 }; |
507 std::vector<uint32> config( | 506 std::vector<uint32> config( |
508 config_array, config_array + arraysize(config_array)); | 507 config_array, config_array + arraysize(config_array)); |
509 CHECK(decoder_->Initialize(config)); | 508 CHECK(decoder_->Initialize(config)); |
510 } | 509 } |
511 | 510 |
512 | 511 |
513 void EglRenderingVDAClient::ProvidePictureBuffers( | 512 void EglRenderingVDAClient::ProvidePictureBuffers( |
514 uint32 requested_num_of_buffers, | 513 uint32 requested_num_of_buffers, |
515 const gfx::Size& dimensions, | 514 const gfx::Size& dimensions, |
516 VideoDecodeAccelerator::MemoryType type) { | 515 VideoDecodeAccelerator::MemoryType type) { |
517 if (!decoder_.get()) | 516 if (decoder_deleted()) |
518 return; | 517 return; |
519 CHECK_EQ(type, VideoDecodeAccelerator::PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE); | 518 CHECK_EQ(type, VideoDecodeAccelerator::PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE); |
520 std::vector<media::GLESBuffer> buffers; | 519 std::vector<media::GLESBuffer> buffers; |
521 CHECK_EQ(dimensions.width(), kFrameWidth); | 520 CHECK_EQ(dimensions.width(), kFrameWidth); |
522 CHECK_EQ(dimensions.height(), kFrameHeight); | 521 CHECK_EQ(dimensions.height(), kFrameHeight); |
523 | 522 |
524 for (uint32 i = 0; i < requested_num_of_buffers; ++i) { | 523 for (uint32 i = 0; i < requested_num_of_buffers; ++i) { |
525 uint32 id = picture_buffers_by_id_.size(); | 524 uint32 id = picture_buffers_by_id_.size(); |
526 GLuint texture_id; | 525 GLuint texture_id; |
527 base::WaitableEvent done(false, false); | 526 base::WaitableEvent done(false, false); |
(...skipping 15 matching lines...) Expand all Loading... |
543 DCHECK(it != picture_buffers_by_id_.end()); | 542 DCHECK(it != picture_buffers_by_id_.end()); |
544 rendering_helper_->DeleteTexture(it->second->texture_id()); | 543 rendering_helper_->DeleteTexture(it->second->texture_id()); |
545 delete it->second; | 544 delete it->second; |
546 picture_buffers_by_id_.erase(it); | 545 picture_buffers_by_id_.erase(it); |
547 } | 546 } |
548 | 547 |
549 void EglRenderingVDAClient::PictureReady(const media::Picture& picture) { | 548 void EglRenderingVDAClient::PictureReady(const media::Picture& picture) { |
550 // We shouldn't be getting pictures delivered after Reset has completed. | 549 // We shouldn't be getting pictures delivered after Reset has completed. |
551 DCHECK_LT(state_, CS_RESET); | 550 DCHECK_LT(state_, CS_RESET); |
552 | 551 |
553 if (!decoder_.get()) | 552 if (decoder_deleted()) |
554 return; | 553 return; |
555 last_frame_delivered_ticks_ = base::TimeTicks::Now(); | 554 last_frame_delivered_ticks_ = base::TimeTicks::Now(); |
556 | 555 |
557 // Because we feed the decoder a limited number of NALUs at a time, we can be | 556 // Because we feed the decoder a limited number of NALUs at a time, we can be |
558 // sure that the bitstream buffer from which a frame comes has a limited | 557 // sure that the bitstream buffer from which a frame comes has a limited |
559 // range. Assert that. | 558 // range. Assert that. |
560 CHECK_GE((picture.bitstream_buffer_id() + 1) * num_NALUs_per_decode_, | 559 CHECK_GE((picture.bitstream_buffer_id() + 1) * num_NALUs_per_decode_, |
561 num_decoded_frames_); | 560 num_decoded_frames_); |
562 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); | 561 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); |
563 ++num_decoded_frames_; | 562 ++num_decoded_frames_; |
(...skipping 16 matching lines...) Expand all Loading... |
580 SetState(CS_DONE); | 579 SetState(CS_DONE); |
581 } | 580 } |
582 | 581 |
583 void EglRenderingVDAClient::NotifyEndOfBitstreamBuffer( | 582 void EglRenderingVDAClient::NotifyEndOfBitstreamBuffer( |
584 int32 bitstream_buffer_id) { | 583 int32 bitstream_buffer_id) { |
585 ++num_done_bitstream_buffers_; | 584 ++num_done_bitstream_buffers_; |
586 DecodeNextNALUs(); | 585 DecodeNextNALUs(); |
587 } | 586 } |
588 | 587 |
589 void EglRenderingVDAClient::NotifyFlushDone() { | 588 void EglRenderingVDAClient::NotifyFlushDone() { |
590 if (!decoder_.get()) | 589 if (decoder_deleted()) |
591 return; | 590 return; |
592 SetState(CS_FLUSHED); | 591 SetState(CS_FLUSHED); |
593 if (!decoder_.get()) | 592 if (decoder_deleted()) |
594 return; | 593 return; |
595 decoder_->Reset(); | 594 decoder_->Reset(); |
596 } | 595 } |
597 | 596 |
598 void EglRenderingVDAClient::NotifyResetDone() { | 597 void EglRenderingVDAClient::NotifyResetDone() { |
599 if (!decoder_.get()) | 598 if (decoder_deleted()) |
600 return; | 599 return; |
601 SetState(CS_RESET); | 600 SetState(CS_RESET); |
602 if (!decoder_.get()) | 601 if (!decoder_deleted()) |
603 return; | 602 DeleteDecoder(); |
604 decoder_->Destroy(); | |
605 } | |
606 | |
607 void EglRenderingVDAClient::NotifyDestroyDone() { | |
608 SetState(CS_DESTROYED); | |
609 } | 603 } |
610 | 604 |
611 void EglRenderingVDAClient::NotifyError(VideoDecodeAccelerator::Error error) { | 605 void EglRenderingVDAClient::NotifyError(VideoDecodeAccelerator::Error error) { |
612 SetState(CS_ERROR); | 606 SetState(CS_ERROR); |
613 error_ = error; | 607 error_ = error; |
614 } | 608 } |
615 | 609 |
616 static bool LookingAtNAL(const std::string& encoded, size_t pos) { | 610 static bool LookingAtNAL(const std::string& encoded, size_t pos) { |
617 return pos + 3 < encoded.size() && | 611 return pos + 3 < encoded.size() && |
618 encoded[pos] == 0 && encoded[pos + 1] == 0 && | 612 encoded[pos] == 0 && encoded[pos + 1] == 0 && |
619 encoded[pos + 2] == 0 && encoded[pos + 3] == 1; | 613 encoded[pos + 2] == 0 && encoded[pos + 3] == 1; |
620 } | 614 } |
621 | 615 |
622 void EglRenderingVDAClient::SetState(ClientState new_state) { | 616 void EglRenderingVDAClient::SetState(ClientState new_state) { |
623 note_->Notify(new_state); | 617 note_->Notify(new_state); |
624 state_ = new_state; | 618 state_ = new_state; |
625 if (new_state == delete_decoder_state_) | 619 if (new_state == delete_decoder_state_) { |
| 620 CHECK(!decoder_deleted()); |
626 DeleteDecoder(); | 621 DeleteDecoder(); |
| 622 } |
627 } | 623 } |
628 | 624 |
629 void EglRenderingVDAClient::DeleteDecoder() { | 625 void EglRenderingVDAClient::DeleteDecoder() { |
630 decoder_.reset(); | 626 if (decoder_deleted()) |
| 627 return; |
| 628 decoder_->Destroy(); |
| 629 decoder_ = NULL; |
631 // Cascade through the rest of the states to simplify test code below. | 630 // Cascade through the rest of the states to simplify test code below. |
632 for (int i = state_ + 1; i < CS_MAX; ++i) | 631 for (int i = state_ + 1; i < CS_MAX; ++i) |
633 SetState(static_cast<ClientState>(i)); | 632 SetState(static_cast<ClientState>(i)); |
634 } | 633 } |
635 | 634 |
636 void EglRenderingVDAClient::GetRangeForNextNALUs( | 635 void EglRenderingVDAClient::GetRangeForNextNALUs( |
637 size_t start_pos, size_t* end_pos) { | 636 size_t start_pos, size_t* end_pos) { |
638 *end_pos = start_pos; | 637 *end_pos = start_pos; |
639 CHECK(LookingAtNAL(*encoded_data_, start_pos)); | 638 CHECK(LookingAtNAL(*encoded_data_, start_pos)); |
640 for (int i = 0; i < num_NALUs_per_decode_; ++i) { | 639 for (int i = 0; i < num_NALUs_per_decode_; ++i) { |
641 *end_pos += 4; | 640 *end_pos += 4; |
642 while (*end_pos + 3 < encoded_data_->size() && | 641 while (*end_pos + 3 < encoded_data_->size() && |
643 !LookingAtNAL(*encoded_data_, *end_pos)) { | 642 !LookingAtNAL(*encoded_data_, *end_pos)) { |
644 ++*end_pos; | 643 ++*end_pos; |
645 } | 644 } |
646 if (*end_pos + 3 >= encoded_data_->size()) { | 645 if (*end_pos + 3 >= encoded_data_->size()) { |
647 *end_pos = encoded_data_->size(); | 646 *end_pos = encoded_data_->size(); |
648 return; | 647 return; |
649 } | 648 } |
650 } | 649 } |
651 } | 650 } |
652 | 651 |
653 void EglRenderingVDAClient::DecodeNextNALUs() { | 652 void EglRenderingVDAClient::DecodeNextNALUs() { |
654 if (!decoder_.get()) | 653 if (decoder_deleted()) |
655 return; | 654 return; |
656 if (encoded_data_next_pos_to_decode_ == encoded_data_->size()) { | 655 if (encoded_data_next_pos_to_decode_ == encoded_data_->size()) { |
657 decoder_->Flush(); | 656 decoder_->Flush(); |
658 return; | 657 return; |
659 } | 658 } |
660 size_t start_pos = encoded_data_next_pos_to_decode_; | 659 size_t start_pos = encoded_data_next_pos_to_decode_; |
661 size_t end_pos; | 660 size_t end_pos; |
662 GetRangeForNextNALUs(start_pos, &end_pos); | 661 GetRangeForNextNALUs(start_pos, &end_pos); |
663 | 662 |
664 // Populate the shared memory buffer w/ the NALU, duplicate its handle, and | 663 // Populate the shared memory buffer w/ the NALU, duplicate its handle, and |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
806 ¬es)); | 805 ¬es)); |
807 rendering_thread.message_loop()->PostTask( | 806 rendering_thread.message_loop()->PostTask( |
808 FROM_HERE, | 807 FROM_HERE, |
809 base::Bind(&RenderingHelper::UnInitialize, | 808 base::Bind(&RenderingHelper::UnInitialize, |
810 base::Unretained(&rendering_helper), | 809 base::Unretained(&rendering_helper), |
811 &done)); | 810 &done)); |
812 done.Wait(); | 811 done.Wait(); |
813 rendering_thread.Stop(); | 812 rendering_thread.Stop(); |
814 }; | 813 }; |
815 | 814 |
816 // TODO(fischman): Remove DISABLED_ prefix when ~OVDA can tear down OMX | |
817 // synchronously (http://crosbug.com/p/4869). | |
818 INSTANTIATE_TEST_CASE_P( | 815 INSTANTIATE_TEST_CASE_P( |
819 DISABLED_TearDownTiming, OmxVideoDecodeAcceleratorTest, | 816 TearDownTiming, OmxVideoDecodeAcceleratorTest, |
820 ::testing::Values( | 817 ::testing::Values( |
821 MakeTuple(1, 1, CS_DECODER_SET), MakeTuple(1, 1, CS_INITIALIZED), | 818 MakeTuple(1, 1, CS_DECODER_SET), MakeTuple(1, 1, CS_INITIALIZED), |
822 MakeTuple(1, 1, CS_FLUSHED), MakeTuple(1, 1, CS_RESET), | 819 MakeTuple(1, 1, CS_FLUSHED), MakeTuple(1, 1, CS_RESET), |
823 MakeTuple(1, 1, static_cast<ClientState>(-1)), | 820 MakeTuple(1, 1, static_cast<ClientState>(-1)), |
824 MakeTuple(1, 1, static_cast<ClientState>(-10)), | 821 MakeTuple(1, 1, static_cast<ClientState>(-10)), |
825 MakeTuple(1, 1, static_cast<ClientState>(-100)))); | 822 MakeTuple(1, 1, static_cast<ClientState>(-100)))); |
826 | 823 |
827 // TODO(fischman): using 2nd param of 16 and higher below breaks decode - visual | 824 // TODO(fischman): using 2nd param of 16 and higher below breaks decode - visual |
828 // artifacts are introduced as well as spurious frames are delivered (more | 825 // artifacts are introduced as well as spurious frames are delivered (more |
829 // pictures are returned than NALUs are fed to the decoder). Increase the "15" | 826 // pictures are returned than NALUs are fed to the decoder). Increase the "15" |
830 // below when http://code.google.com/p/chrome-os-partner/issues/detail?id=4378 | 827 // below when http://code.google.com/p/chrome-os-partner/issues/detail?id=4378 |
831 // is fixed. | 828 // is fixed. |
832 INSTANTIATE_TEST_CASE_P( | 829 INSTANTIATE_TEST_CASE_P( |
833 DecodeVariations, OmxVideoDecodeAcceleratorTest, | 830 DecodeVariations, OmxVideoDecodeAcceleratorTest, |
834 ::testing::Values( | 831 ::testing::Values( |
835 MakeTuple(1, 1, CS_DESTROYED), MakeTuple(1, 3, CS_DESTROYED), | 832 MakeTuple(1, 1, CS_RESET), MakeTuple(1, 3, CS_RESET), |
836 MakeTuple(2, 1, CS_DESTROYED), MakeTuple(3, 1, CS_DESTROYED), | 833 MakeTuple(2, 1, CS_RESET), MakeTuple(3, 1, CS_RESET), |
837 MakeTuple(5, 1, CS_DESTROYED), MakeTuple(8, 1, CS_DESTROYED), | 834 MakeTuple(5, 1, CS_RESET), MakeTuple(8, 1, CS_RESET), |
838 MakeTuple(15, 1, CS_DESTROYED))); | 835 MakeTuple(15, 1, CS_RESET))); |
839 | 836 |
840 // TODO(fischman, vrk): add more tests! In particular: | 837 // TODO(fischman, vrk): add more tests! In particular: |
841 // - Test life-cycle: Seek/Stop/Pause/Play/RePlay for a single decoder. | 838 // - Test life-cycle: Seek/Stop/Pause/Play/RePlay for a single decoder. |
842 // - Test alternate configurations | 839 // - Test alternate configurations |
843 // - Test failure conditions. | 840 // - Test failure conditions. |
844 // - Test frame size changes mid-stream | 841 // - Test frame size changes mid-stream |
845 | 842 |
846 } // namespace | 843 } // namespace |
OLD | NEW |