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

Side by Side Diff: media/renderers/renderer_impl_unittest.cc

Issue 2605473002: Fix processing of multiple stream status changes by renderer (Closed)
Patch Set: CR feedback (use a single unified notification queue) Created 3 years, 11 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
« no previous file with comments | « media/renderers/renderer_impl.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 <stdint.h> 5 #include <stdint.h>
6 6
7 #include <memory> 7 #include <memory>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h" 13 #include "base/run_loop.h"
14 #include "base/test/simple_test_tick_clock.h" 14 #include "base/test/simple_test_tick_clock.h"
15 #include "base/threading/thread_task_runner_handle.h"
15 #include "media/base/gmock_callback_support.h" 16 #include "media/base/gmock_callback_support.h"
16 #include "media/base/mock_filters.h" 17 #include "media/base/mock_filters.h"
17 #include "media/base/test_helpers.h" 18 #include "media/base/test_helpers.h"
18 #include "media/renderers/renderer_impl.h" 19 #include "media/renderers/renderer_impl.h"
19 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
20 21
21 using ::testing::_; 22 using ::testing::_;
22 using ::testing::DoAll; 23 using ::testing::DoAll;
23 using ::testing::InSequence; 24 using ::testing::InSequence;
24 using ::testing::Mock; 25 using ::testing::Mock;
25 using ::testing::Return; 26 using ::testing::Return;
26 using ::testing::SaveArg; 27 using ::testing::SaveArg;
27 using ::testing::StrictMock; 28 using ::testing::StrictMock;
29 using ::testing::WithArg;
28 30
29 namespace media { 31 namespace media {
30 32
31 const int64_t kStartPlayingTimeInMs = 100; 33 const int64_t kStartPlayingTimeInMs = 100;
32 34
33 ACTION_P2(SetBufferingState, renderer_client, buffering_state) { 35 ACTION_P2(SetBufferingState, renderer_client, buffering_state) {
34 (*renderer_client)->OnBufferingStateChange(buffering_state); 36 (*renderer_client)->OnBufferingStateChange(buffering_state);
35 } 37 }
36 38
37 ACTION_P2(SetError, renderer_client, error) { 39 ACTION_P2(SetError, renderer_client, error) {
38 (*renderer_client)->OnError(error); 40 (*renderer_client)->OnError(error);
39 } 41 }
40 42
43 ACTION(PostCallback) {
44 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, arg0);
45 }
46
47 ACTION(PostQuitWhenIdle) {
48 base::ThreadTaskRunnerHandle::Get()->PostTask(
49 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
50 }
51
41 class RendererImplTest : public ::testing::Test { 52 class RendererImplTest : public ::testing::Test {
42 public: 53 public:
43 // Used for setting expectations on pipeline callbacks. Using a StrictMock 54 // Used for setting expectations on pipeline callbacks. Using a StrictMock
44 // also lets us test for missing callbacks. 55 // also lets us test for missing callbacks.
45 class CallbackHelper : public MockRendererClient { 56 class CallbackHelper : public MockRendererClient {
46 public: 57 public:
47 CallbackHelper() {} 58 CallbackHelper() {}
48 virtual ~CallbackHelper() {} 59 virtual ~CallbackHelper() {}
49 60
50 // Completion callbacks. 61 // Completion callbacks.
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 .WillOnce(SaveArg<0>(&audio_stream_status_change_cb)); 757 .WillOnce(SaveArg<0>(&audio_stream_status_change_cb));
747 EXPECT_CALL(*video_stream_, SetStreamStatusChangeCB(_)) 758 EXPECT_CALL(*video_stream_, SetStreamStatusChangeCB(_))
748 .WillOnce(SaveArg<0>(&video_stream_status_change_cb)); 759 .WillOnce(SaveArg<0>(&video_stream_status_change_cb));
749 SetAudioRendererInitializeExpectations(PIPELINE_OK); 760 SetAudioRendererInitializeExpectations(PIPELINE_OK);
750 SetVideoRendererInitializeExpectations(PIPELINE_OK); 761 SetVideoRendererInitializeExpectations(PIPELINE_OK);
751 InitializeAndExpect(PIPELINE_OK); 762 InitializeAndExpect(PIPELINE_OK);
752 Play(); 763 Play();
753 764
754 // Verify that DemuxerStream status changes cause the corresponding 765 // Verify that DemuxerStream status changes cause the corresponding
755 // audio/video renderer to be flushed and restarted. 766 // audio/video renderer to be flushed and restarted.
756 base::TimeDelta time0;
757 EXPECT_CALL(time_source_, StopTicking()); 767 EXPECT_CALL(time_source_, StopTicking());
758 EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(RunClosure<0>()); 768 EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(RunClosure<0>());
759 EXPECT_CALL(*audio_renderer_, StartPlaying()).Times(1); 769 EXPECT_CALL(*audio_renderer_, StartPlaying())
760 audio_stream_status_change_cb.Run(false, time0); 770 .Times(1)
771 .WillOnce(
772 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH));
773 audio_stream_status_change_cb.Run(false, base::TimeDelta());
761 774
762 EXPECT_CALL(*video_renderer_, Flush(_)).WillOnce(RunClosure<0>()); 775 EXPECT_CALL(*video_renderer_, Flush(_)).WillOnce(RunClosure<0>());
763 EXPECT_CALL(*video_renderer_, StartPlayingFrom(_)).Times(1); 776 EXPECT_CALL(*video_renderer_, StartPlayingFrom(_))
764 video_stream_status_change_cb.Run(false, time0); 777 .Times(1)
778 .WillOnce(DoAll(
779 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH),
780 PostQuitWhenIdle()));
781
782 video_stream_status_change_cb.Run(false, base::TimeDelta());
783 base::RunLoop().Run();
784 }
785
786 // Stream status changes are handled asynchronously by the renderer and may take
787 // some time to process. This test verifies that all status changes are
788 // processed correctly by the renderer even if status changes of the stream
789 // happen much faster than the renderer can process them. In that case the
790 // renderer may postpone processing status changes, but still must process all
791 // of them eventually.
792 TEST_F(RendererImplTest, PostponedStreamStatusNotificationHandling) {
793 CreateAudioAndVideoStream();
794
795 DemuxerStream::StreamStatusChangeCB audio_stream_status_change_cb;
796 DemuxerStream::StreamStatusChangeCB video_stream_status_change_cb;
797 EXPECT_CALL(*audio_stream_, SetStreamStatusChangeCB(_))
798 .WillOnce(SaveArg<0>(&audio_stream_status_change_cb));
799 EXPECT_CALL(*video_stream_, SetStreamStatusChangeCB(_))
800 .WillOnce(SaveArg<0>(&video_stream_status_change_cb));
801 SetAudioRendererInitializeExpectations(PIPELINE_OK);
802 SetVideoRendererInitializeExpectations(PIPELINE_OK);
803 InitializeAndExpect(PIPELINE_OK);
804 Play();
805
806 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
807 .Times(2);
808
809 EXPECT_CALL(time_source_, StopTicking()).Times(2);
810 EXPECT_CALL(time_source_, StartTicking()).Times(2);
811 EXPECT_CALL(*audio_renderer_, Flush(_))
812 .Times(2)
813 .WillRepeatedly(DoAll(
814 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_NOTHING),
815 WithArg<0>(PostCallback())));
816 EXPECT_CALL(*audio_renderer_, StartPlaying())
817 .Times(2)
818 .WillOnce(
819 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH))
820 .WillOnce(DoAll(
821 SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH),
822 PostQuitWhenIdle()));
823 // The first stream status change will be processed immediately. Each status
824 // change processing involves Flush + StartPlaying when the Flush is done. The
825 // Flush operation is async in this case, so the second status change will be
826 // postponed by renderer until after processing the first one is finished. But
827 // we must still get two pairs of Flush/StartPlaying calls eventually.
828 audio_stream_status_change_cb.Run(false, base::TimeDelta());
829 audio_stream_status_change_cb.Run(true, base::TimeDelta());
830 base::RunLoop().Run();
831
832 EXPECT_CALL(*video_renderer_, Flush(_))
833 .Times(2)
834 .WillRepeatedly(DoAll(
835 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_NOTHING),
836 WithArg<0>(PostCallback())));
837 EXPECT_CALL(*video_renderer_, StartPlayingFrom(base::TimeDelta()))
838 .Times(2)
839 .WillOnce(
840 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH))
841 .WillOnce(DoAll(
842 SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH),
843 PostQuitWhenIdle()));
844 // The first stream status change will be processed immediately. Each status
845 // change processing involves Flush + StartPlaying when the Flush is done. The
846 // Flush operation is async in this case, so the second status change will be
847 // postponed by renderer until after processing the first one is finished. But
848 // we must still get two pairs of Flush/StartPlaying calls eventually.
849 video_stream_status_change_cb.Run(false, base::TimeDelta());
850 video_stream_status_change_cb.Run(true, base::TimeDelta());
851 base::RunLoop().Run();
765 } 852 }
766 853
767 } // namespace media 854 } // namespace media
OLDNEW
« no previous file with comments | « media/renderers/renderer_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698