OLD | NEW |
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 <vector> | 5 #include <vector> |
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/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/test/simple_test_tick_clock.h" | 10 #include "base/test/simple_test_tick_clock.h" |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 if (start_status == PIPELINE_OK) { | 201 if (start_status == PIPELINE_OK) { |
202 EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_)); | 202 EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_)); |
203 | 203 |
204 if (audio_stream_) { | 204 if (audio_stream_) { |
205 EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f)); | 205 EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f)); |
206 EXPECT_CALL(*audio_renderer_, SetVolume(1.0f)); | 206 EXPECT_CALL(*audio_renderer_, SetVolume(1.0f)); |
207 | 207 |
208 // Startup sequence. | 208 // Startup sequence. |
209 EXPECT_CALL(*audio_renderer_, Preroll(base::TimeDelta(), _)) | 209 EXPECT_CALL(*audio_renderer_, Preroll(base::TimeDelta(), _)) |
210 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 210 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
211 EXPECT_CALL(*audio_renderer_, Play(_)) | 211 EXPECT_CALL(*audio_renderer_, Play()); |
212 .WillOnce(RunClosure<0>()); | |
213 } | 212 } |
214 EXPECT_CALL(callbacks_, OnPrerollCompleted()); | 213 EXPECT_CALL(callbacks_, OnPrerollCompleted()); |
215 } | 214 } |
216 | 215 |
217 pipeline_->Start( | 216 pipeline_->Start( |
218 filter_collection_.Pass(), | 217 filter_collection_.Pass(), |
219 base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), | 218 base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), |
220 base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)), | 219 base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)), |
221 base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)), | 220 base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)), |
222 base::Bind(&CallbackHelper::OnMetadata, base::Unretained(&callbacks_)), | 221 base::Bind(&CallbackHelper::OnMetadata, base::Unretained(&callbacks_)), |
(...skipping 29 matching lines...) Expand all Loading... |
252 FakeTextTrackStream* text_stream() { | 251 FakeTextTrackStream* text_stream() { |
253 return text_stream_.get(); | 252 return text_stream_.get(); |
254 } | 253 } |
255 | 254 |
256 void ExpectSeek(const base::TimeDelta& seek_time) { | 255 void ExpectSeek(const base::TimeDelta& seek_time) { |
257 // Every filter should receive a call to Seek(). | 256 // Every filter should receive a call to Seek(). |
258 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) | 257 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
259 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 258 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
260 | 259 |
261 if (audio_stream_) { | 260 if (audio_stream_) { |
262 EXPECT_CALL(*audio_renderer_, Pause(_)) | 261 EXPECT_CALL(*audio_renderer_, Pause()); |
263 .WillOnce(RunClosure<0>()); | |
264 EXPECT_CALL(*audio_renderer_, Flush(_)) | 262 EXPECT_CALL(*audio_renderer_, Flush(_)) |
265 .WillOnce(RunClosure<0>()); | 263 .WillOnce(RunClosure<0>()); |
266 EXPECT_CALL(*audio_renderer_, Preroll(seek_time, _)) | 264 EXPECT_CALL(*audio_renderer_, Preroll(seek_time, _)) |
267 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 265 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
268 EXPECT_CALL(*audio_renderer_, SetPlaybackRate(_)); | 266 EXPECT_CALL(*audio_renderer_, SetPlaybackRate(_)); |
269 EXPECT_CALL(*audio_renderer_, SetVolume(_)); | 267 EXPECT_CALL(*audio_renderer_, SetVolume(_)); |
270 EXPECT_CALL(*audio_renderer_, Play(_)) | 268 EXPECT_CALL(*audio_renderer_, Play()); |
271 .WillOnce(RunClosure<0>()); | |
272 } | 269 } |
273 | 270 |
274 if (video_stream_) { | 271 if (video_stream_) { |
275 EXPECT_CALL(*video_renderer_, Pause(_)) | 272 EXPECT_CALL(*video_renderer_, Pause(_)) |
276 .WillOnce(RunClosure<0>()); | 273 .WillOnce(RunClosure<0>()); |
277 EXPECT_CALL(*video_renderer_, Flush(_)) | 274 EXPECT_CALL(*video_renderer_, Flush(_)) |
278 .WillOnce(RunClosure<0>()); | 275 .WillOnce(RunClosure<0>()); |
279 EXPECT_CALL(*video_renderer_, Preroll(seek_time, _)) | 276 EXPECT_CALL(*video_renderer_, Preroll(seek_time, _)) |
280 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 277 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
281 EXPECT_CALL(*video_renderer_, SetPlaybackRate(_)); | 278 EXPECT_CALL(*video_renderer_, SetPlaybackRate(_)); |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 InitializePipeline(PIPELINE_OK); | 659 InitializePipeline(PIPELINE_OK); |
663 | 660 |
664 float playback_rate = 1.0f; | 661 float playback_rate = 1.0f; |
665 EXPECT_CALL(*audio_renderer_, SetPlaybackRate(playback_rate)); | 662 EXPECT_CALL(*audio_renderer_, SetPlaybackRate(playback_rate)); |
666 pipeline_->SetPlaybackRate(playback_rate); | 663 pipeline_->SetPlaybackRate(playback_rate); |
667 message_loop_.RunUntilIdle(); | 664 message_loop_.RunUntilIdle(); |
668 | 665 |
669 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 666 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
670 | 667 |
671 // Preroll() isn't called as the demuxer errors out first. | 668 // Preroll() isn't called as the demuxer errors out first. |
672 EXPECT_CALL(*audio_renderer_, Pause(_)) | 669 EXPECT_CALL(*audio_renderer_, Pause()); |
673 .WillOnce(RunClosure<0>()); | |
674 EXPECT_CALL(*audio_renderer_, Flush(_)) | 670 EXPECT_CALL(*audio_renderer_, Flush(_)) |
675 .WillOnce(RunClosure<0>()); | 671 .WillOnce(RunClosure<0>()); |
676 EXPECT_CALL(*audio_renderer_, Stop(_)) | 672 EXPECT_CALL(*audio_renderer_, Stop(_)) |
677 .WillOnce(RunClosure<0>()); | 673 .WillOnce(RunClosure<0>()); |
678 | 674 |
679 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) | 675 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
680 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); | 676 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); |
681 EXPECT_CALL(*demuxer_, Stop(_)) | 677 EXPECT_CALL(*demuxer_, Stop(_)) |
682 .WillOnce(RunClosure<0>()); | 678 .WillOnce(RunClosure<0>()); |
683 | 679 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 | 713 |
718 // Trigger additional requests on the pipeline during tear down from error. | 714 // Trigger additional requests on the pipeline during tear down from error. |
719 base::Callback<void(PipelineStatus)> cb = base::Bind( | 715 base::Callback<void(PipelineStatus)> cb = base::Bind( |
720 &TestNoCallsAfterError, pipeline_.get(), &message_loop_); | 716 &TestNoCallsAfterError, pipeline_.get(), &message_loop_); |
721 ON_CALL(callbacks_, OnError(_)) | 717 ON_CALL(callbacks_, OnError(_)) |
722 .WillByDefault(Invoke(&cb, &base::Callback<void(PipelineStatus)>::Run)); | 718 .WillByDefault(Invoke(&cb, &base::Callback<void(PipelineStatus)>::Run)); |
723 | 719 |
724 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 720 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
725 | 721 |
726 // Seek() isn't called as the demuxer errors out first. | 722 // Seek() isn't called as the demuxer errors out first. |
727 EXPECT_CALL(*audio_renderer_, Pause(_)) | 723 EXPECT_CALL(*audio_renderer_, Pause()); |
728 .WillOnce(RunClosure<0>()); | |
729 EXPECT_CALL(*audio_renderer_, Flush(_)) | 724 EXPECT_CALL(*audio_renderer_, Flush(_)) |
730 .WillOnce(RunClosure<0>()); | 725 .WillOnce(RunClosure<0>()); |
731 EXPECT_CALL(*audio_renderer_, Stop(_)) | 726 EXPECT_CALL(*audio_renderer_, Stop(_)) |
732 .WillOnce(RunClosure<0>()); | 727 .WillOnce(RunClosure<0>()); |
733 | 728 |
734 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) | 729 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
735 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); | 730 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); |
736 EXPECT_CALL(*demuxer_, Stop(_)) | 731 EXPECT_CALL(*demuxer_, Stop(_)) |
737 .WillOnce(RunClosure<0>()); | 732 .WillOnce(RunClosure<0>()); |
738 | 733 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 803 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
809 | 804 |
810 // Arrange to trigger a time update while the demuxer is in the middle of | 805 // Arrange to trigger a time update while the demuxer is in the middle of |
811 // seeking. This update should be ignored by the pipeline and the clock should | 806 // seeking. This update should be ignored by the pipeline and the clock should |
812 // not get updated. | 807 // not get updated. |
813 base::Closure closure = base::Bind(&RunTimeCB, audio_time_cb_, 300, 700); | 808 base::Closure closure = base::Bind(&RunTimeCB, audio_time_cb_, 300, 700); |
814 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) | 809 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
815 .WillOnce(DoAll(InvokeWithoutArgs(&closure, &base::Closure::Run), | 810 .WillOnce(DoAll(InvokeWithoutArgs(&closure, &base::Closure::Run), |
816 RunCallback<1>(PIPELINE_OK))); | 811 RunCallback<1>(PIPELINE_OK))); |
817 | 812 |
818 EXPECT_CALL(*audio_renderer_, Pause(_)) | 813 EXPECT_CALL(*audio_renderer_, Pause()); |
819 .WillOnce(RunClosure<0>()); | |
820 EXPECT_CALL(*audio_renderer_, Flush(_)) | 814 EXPECT_CALL(*audio_renderer_, Flush(_)) |
821 .WillOnce(RunClosure<0>()); | 815 .WillOnce(RunClosure<0>()); |
822 EXPECT_CALL(*audio_renderer_, Preroll(seek_time, _)) | 816 EXPECT_CALL(*audio_renderer_, Preroll(seek_time, _)) |
823 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 817 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
824 EXPECT_CALL(*audio_renderer_, SetPlaybackRate(_)); | 818 EXPECT_CALL(*audio_renderer_, SetPlaybackRate(_)); |
825 EXPECT_CALL(*audio_renderer_, SetVolume(_)); | 819 EXPECT_CALL(*audio_renderer_, SetVolume(_)); |
826 EXPECT_CALL(*audio_renderer_, Play(_)) | 820 EXPECT_CALL(*audio_renderer_, Play()); |
827 .WillOnce(RunClosure<0>()); | |
828 | 821 |
829 EXPECT_CALL(callbacks_, OnPrerollCompleted()); | 822 EXPECT_CALL(callbacks_, OnPrerollCompleted()); |
830 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); | 823 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); |
831 DoSeek(seek_time); | 824 DoSeek(seek_time); |
832 | 825 |
833 EXPECT_EQ(pipeline_->GetMediaTime(), seek_time); | 826 EXPECT_EQ(pipeline_->GetMediaTime(), seek_time); |
834 | 827 |
835 // Now that the seek is complete, verify that time updates advance the current | 828 // Now that the seek is complete, verify that time updates advance the current |
836 // time. | 829 // time. |
837 base::TimeDelta new_time = seek_time + base::TimeDelta::FromMilliseconds(100); | 830 base::TimeDelta new_time = seek_time + base::TimeDelta::FromMilliseconds(100); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 // If we get here it's a successful initialization. | 996 // If we get here it's a successful initialization. |
1004 EXPECT_CALL(*audio_renderer_, Preroll(base::TimeDelta(), _)) | 997 EXPECT_CALL(*audio_renderer_, Preroll(base::TimeDelta(), _)) |
1005 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 998 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
1006 EXPECT_CALL(*video_renderer_, Preroll(base::TimeDelta(), _)) | 999 EXPECT_CALL(*video_renderer_, Preroll(base::TimeDelta(), _)) |
1007 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 1000 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
1008 | 1001 |
1009 EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f)); | 1002 EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f)); |
1010 EXPECT_CALL(*video_renderer_, SetPlaybackRate(0.0f)); | 1003 EXPECT_CALL(*video_renderer_, SetPlaybackRate(0.0f)); |
1011 EXPECT_CALL(*audio_renderer_, SetVolume(1.0f)); | 1004 EXPECT_CALL(*audio_renderer_, SetVolume(1.0f)); |
1012 | 1005 |
1013 EXPECT_CALL(*audio_renderer_, Play(_)) | 1006 EXPECT_CALL(*audio_renderer_, Play()); |
1014 .WillOnce(RunClosure<0>()); | |
1015 EXPECT_CALL(*video_renderer_, Play(_)) | 1007 EXPECT_CALL(*video_renderer_, Play(_)) |
1016 .WillOnce(RunClosure<0>()); | 1008 .WillOnce(RunClosure<0>()); |
1017 | 1009 |
1018 if (status == PIPELINE_OK) | 1010 if (status == PIPELINE_OK) |
1019 EXPECT_CALL(callbacks_, OnPrerollCompleted()); | 1011 EXPECT_CALL(callbacks_, OnPrerollCompleted()); |
1020 | 1012 |
1021 return status; | 1013 return status; |
1022 } | 1014 } |
1023 | 1015 |
1024 void DoSeek(TeardownState state, StopOrError stop_or_error) { | 1016 void DoSeek(TeardownState state, StopOrError stop_or_error) { |
(...skipping 15 matching lines...) Expand all Loading... |
1040 } | 1032 } |
1041 | 1033 |
1042 PipelineStatus SetSeekExpectations(TeardownState state, | 1034 PipelineStatus SetSeekExpectations(TeardownState state, |
1043 StopOrError stop_or_error) { | 1035 StopOrError stop_or_error) { |
1044 PipelineStatus status = PIPELINE_OK; | 1036 PipelineStatus status = PIPELINE_OK; |
1045 base::Closure stop_cb = base::Bind( | 1037 base::Closure stop_cb = base::Bind( |
1046 &CallbackHelper::OnStop, base::Unretained(&callbacks_)); | 1038 &CallbackHelper::OnStop, base::Unretained(&callbacks_)); |
1047 | 1039 |
1048 if (state == kPausing) { | 1040 if (state == kPausing) { |
1049 if (stop_or_error == kStop) { | 1041 if (stop_or_error == kStop) { |
1050 EXPECT_CALL(*audio_renderer_, Pause(_)) | 1042 EXPECT_CALL(*audio_renderer_, Pause()) |
1051 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), RunClosure<0>())); | 1043 .WillOnce(Stop(pipeline_.get(), stop_cb)); |
1052 } else { | 1044 } else { |
1053 status = PIPELINE_ERROR_READ; | 1045 status = PIPELINE_ERROR_READ; |
1054 EXPECT_CALL(*audio_renderer_, Pause(_)).WillOnce( | 1046 EXPECT_CALL(*audio_renderer_, Pause()) |
1055 DoAll(SetError(pipeline_.get(), status), RunClosure<0>())); | 1047 .WillOnce(SetError(pipeline_.get(), status)); |
1056 } | 1048 } |
1057 | 1049 |
1058 return status; | 1050 return status; |
1059 } | 1051 } |
1060 | 1052 |
1061 EXPECT_CALL(*audio_renderer_, Pause(_)).WillOnce(RunClosure<0>()); | 1053 EXPECT_CALL(*audio_renderer_, Pause()); |
1062 EXPECT_CALL(*video_renderer_, Pause(_)).WillOnce(RunClosure<0>()); | 1054 EXPECT_CALL(*video_renderer_, Pause(_)).WillOnce(RunClosure<0>()); |
1063 | 1055 |
1064 if (state == kFlushing) { | 1056 if (state == kFlushing) { |
1065 if (stop_or_error == kStop) { | 1057 if (stop_or_error == kStop) { |
1066 EXPECT_CALL(*audio_renderer_, Flush(_)) | 1058 EXPECT_CALL(*audio_renderer_, Flush(_)) |
1067 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), RunClosure<0>())); | 1059 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), RunClosure<0>())); |
1068 } else { | 1060 } else { |
1069 status = PIPELINE_ERROR_READ; | 1061 status = PIPELINE_ERROR_READ; |
1070 EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce( | 1062 EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce( |
1071 DoAll(SetError(pipeline_.get(), status), RunClosure<0>())); | 1063 DoAll(SetError(pipeline_.get(), status), RunClosure<0>())); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 EXPECT_CALL(*video_renderer_, Preroll(_, _)) | 1105 EXPECT_CALL(*video_renderer_, Preroll(_, _)) |
1114 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 1106 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
1115 | 1107 |
1116 // Playback rate and volume are updated prior to starting. | 1108 // Playback rate and volume are updated prior to starting. |
1117 EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f)); | 1109 EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f)); |
1118 EXPECT_CALL(*video_renderer_, SetPlaybackRate(0.0f)); | 1110 EXPECT_CALL(*video_renderer_, SetPlaybackRate(0.0f)); |
1119 EXPECT_CALL(*audio_renderer_, SetVolume(1.0f)); | 1111 EXPECT_CALL(*audio_renderer_, SetVolume(1.0f)); |
1120 | 1112 |
1121 if (state == kStarting) { | 1113 if (state == kStarting) { |
1122 if (stop_or_error == kStop) { | 1114 if (stop_or_error == kStop) { |
1123 EXPECT_CALL(*audio_renderer_, Play(_)) | 1115 EXPECT_CALL(*audio_renderer_, Play()) |
1124 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), RunClosure<0>())); | 1116 .WillOnce(Stop(pipeline_.get(), stop_cb)); |
1125 } else { | 1117 } else { |
1126 status = PIPELINE_ERROR_READ; | 1118 status = PIPELINE_ERROR_READ; |
1127 EXPECT_CALL(*audio_renderer_, Play(_)).WillOnce( | 1119 EXPECT_CALL(*audio_renderer_, Play()) |
1128 DoAll(SetError(pipeline_.get(), status), RunClosure<0>())); | 1120 .WillOnce(SetError(pipeline_.get(), status)); |
1129 } | 1121 } |
1130 return status; | 1122 return status; |
1131 } | 1123 } |
1132 | 1124 |
1133 NOTREACHED() << "State not supported: " << state; | 1125 NOTREACHED() << "State not supported: " << state; |
1134 return status; | 1126 return status; |
1135 } | 1127 } |
1136 | 1128 |
1137 void DoStopOrError(StopOrError stop_or_error) { | 1129 void DoStopOrError(StopOrError stop_or_error) { |
1138 InSequence s; | 1130 InSequence s; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 INSTANTIATE_TEARDOWN_TEST(Error, Pausing); | 1180 INSTANTIATE_TEARDOWN_TEST(Error, Pausing); |
1189 INSTANTIATE_TEARDOWN_TEST(Error, Flushing); | 1181 INSTANTIATE_TEARDOWN_TEST(Error, Flushing); |
1190 INSTANTIATE_TEARDOWN_TEST(Error, Seeking); | 1182 INSTANTIATE_TEARDOWN_TEST(Error, Seeking); |
1191 INSTANTIATE_TEARDOWN_TEST(Error, Prerolling); | 1183 INSTANTIATE_TEARDOWN_TEST(Error, Prerolling); |
1192 INSTANTIATE_TEARDOWN_TEST(Error, Starting); | 1184 INSTANTIATE_TEARDOWN_TEST(Error, Starting); |
1193 INSTANTIATE_TEARDOWN_TEST(Error, Playing); | 1185 INSTANTIATE_TEARDOWN_TEST(Error, Playing); |
1194 | 1186 |
1195 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing); | 1187 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing); |
1196 | 1188 |
1197 } // namespace media | 1189 } // namespace media |
OLD | NEW |