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

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

Issue 2267963002: Add support for cancellation of demuxer reads. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix and add tests. Created 4 years, 3 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/filters/ffmpeg_demuxer.cc ('k') | media/filters/file_data_source.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 <stddef.h> 5 #include <stddef.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include <algorithm> 8 #include <algorithm>
9 #include <deque> 9 #include <deque>
10 #include <string> 10 #include <string>
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 media::PipelineStatus expected_pipeline_status) { 134 media::PipelineStatus expected_pipeline_status) {
135 InitializeDemuxerInternal(/*enable_text=*/false, expected_pipeline_status, 135 InitializeDemuxerInternal(/*enable_text=*/false, expected_pipeline_status,
136 base::Time()); 136 base::Time());
137 } 137 }
138 138
139 MOCK_METHOD2(OnReadDoneCalled, void(int, int64_t)); 139 MOCK_METHOD2(OnReadDoneCalled, void(int, int64_t));
140 140
141 struct ReadExpectation { 141 struct ReadExpectation {
142 ReadExpectation(size_t size, 142 ReadExpectation(size_t size,
143 int64_t timestamp_us, 143 int64_t timestamp_us,
144 const base::TimeDelta& discard_front_padding, 144 base::TimeDelta discard_front_padding,
145 bool is_key_frame) 145 bool is_key_frame,
146 DemuxerStream::Status status)
146 : size(size), 147 : size(size),
147 timestamp_us(timestamp_us), 148 timestamp_us(timestamp_us),
148 discard_front_padding(discard_front_padding), 149 discard_front_padding(discard_front_padding),
149 is_key_frame(is_key_frame) {} 150 is_key_frame(is_key_frame),
151 status(status) {}
150 152
151 size_t size; 153 size_t size;
152 int64_t timestamp_us; 154 int64_t timestamp_us;
153 base::TimeDelta discard_front_padding; 155 base::TimeDelta discard_front_padding;
154 bool is_key_frame; 156 bool is_key_frame;
157 DemuxerStream::Status status;
155 }; 158 };
156 159
157 // Verifies that |buffer| has a specific |size| and |timestamp|. 160 // Verifies that |buffer| has a specific |size| and |timestamp|.
158 // |location| simply indicates where the call to this function was made. 161 // |location| simply indicates where the call to this function was made.
159 // This makes it easier to track down where test failures occur. 162 // This makes it easier to track down where test failures occur.
160 void OnReadDone(const tracked_objects::Location& location, 163 void OnReadDone(const tracked_objects::Location& location,
161 const ReadExpectation& read_expectation, 164 const ReadExpectation& read_expectation,
162 DemuxerStream::Status status, 165 DemuxerStream::Status status,
163 const scoped_refptr<DecoderBuffer>& buffer) { 166 const scoped_refptr<DecoderBuffer>& buffer) {
164 std::string location_str; 167 std::string location_str;
165 location.Write(true, false, &location_str); 168 location.Write(true, false, &location_str);
166 location_str += "\n"; 169 location_str += "\n";
167 SCOPED_TRACE(location_str); 170 SCOPED_TRACE(location_str);
168 EXPECT_EQ(status, DemuxerStream::kOk); 171 EXPECT_EQ(read_expectation.status, status);
169 EXPECT_TRUE(buffer.get() != NULL); 172 if (status == DemuxerStream::kOk) {
170 EXPECT_EQ(read_expectation.size, buffer->data_size()); 173 EXPECT_TRUE(buffer);
171 EXPECT_EQ(read_expectation.timestamp_us, 174 EXPECT_EQ(read_expectation.size, buffer->data_size());
172 buffer->timestamp().InMicroseconds()); 175 EXPECT_EQ(read_expectation.timestamp_us,
173 EXPECT_EQ(read_expectation.discard_front_padding, 176 buffer->timestamp().InMicroseconds());
174 buffer->discard_padding().first); 177 EXPECT_EQ(read_expectation.discard_front_padding,
175 EXPECT_EQ(read_expectation.is_key_frame, buffer->is_key_frame()); 178 buffer->discard_padding().first);
179 EXPECT_EQ(read_expectation.is_key_frame, buffer->is_key_frame());
180 }
176 DCHECK_EQ(&message_loop_, base::MessageLoop::current()); 181 DCHECK_EQ(&message_loop_, base::MessageLoop::current());
177 OnReadDoneCalled(read_expectation.size, read_expectation.timestamp_us); 182 OnReadDoneCalled(read_expectation.size, read_expectation.timestamp_us);
178 message_loop_.task_runner()->PostTask( 183 message_loop_.task_runner()->PostTask(
179 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); 184 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
180 } 185 }
181 186
182 DemuxerStream::ReadCB NewReadCB(const tracked_objects::Location& location, 187 DemuxerStream::ReadCB NewReadCB(
183 int size, 188 const tracked_objects::Location& location,
184 int64_t timestamp_us, 189 int size,
185 bool is_key_frame) { 190 int64_t timestamp_us,
186 return NewReadCBWithCheckedDiscard(location, 191 bool is_key_frame,
187 size, 192 DemuxerStream::Status status = DemuxerStream::kOk) {
188 timestamp_us, 193 return NewReadCBWithCheckedDiscard(location, size, timestamp_us,
189 base::TimeDelta(), 194 base::TimeDelta(), is_key_frame, status);
190 is_key_frame);
191 } 195 }
192 196
193 DemuxerStream::ReadCB NewReadCBWithCheckedDiscard( 197 DemuxerStream::ReadCB NewReadCBWithCheckedDiscard(
194 const tracked_objects::Location& location, 198 const tracked_objects::Location& location,
195 int size, 199 int size,
196 int64_t timestamp_us, 200 int64_t timestamp_us,
197 base::TimeDelta discard_front_padding, 201 base::TimeDelta discard_front_padding,
198 bool is_key_frame) { 202 bool is_key_frame,
203 DemuxerStream::Status status = DemuxerStream::kOk) {
199 EXPECT_CALL(*this, OnReadDoneCalled(size, timestamp_us)); 204 EXPECT_CALL(*this, OnReadDoneCalled(size, timestamp_us));
200 205
201 struct ReadExpectation read_expectation(size, 206 struct ReadExpectation read_expectation(
202 timestamp_us, 207 size, timestamp_us, discard_front_padding, is_key_frame, status);
203 discard_front_padding,
204 is_key_frame);
205 208
206 return base::Bind(&FFmpegDemuxerTest::OnReadDone, 209 return base::Bind(&FFmpegDemuxerTest::OnReadDone,
207 base::Unretained(this), 210 base::Unretained(this),
208 location, 211 location,
209 read_expectation); 212 read_expectation);
210 } 213 }
211 214
212 MOCK_METHOD2(OnEncryptedMediaInitData, 215 MOCK_METHOD2(OnEncryptedMediaInitData,
213 void(EmeInitDataType init_data_type, 216 void(EmeInitDataType init_data_type,
214 const std::vector<uint8_t>& init_data)); 217 const std::vector<uint8_t>& init_data));
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 EmeInitDataType::WEBM, 414 EmeInitDataType::WEBM,
412 std::vector<uint8_t>(kEncryptedMediaInitData, 415 std::vector<uint8_t>(kEncryptedMediaInitData,
413 kEncryptedMediaInitData + 416 kEncryptedMediaInitData +
414 arraysize(kEncryptedMediaInitData)))) 417 arraysize(kEncryptedMediaInitData))))
415 .Times(Exactly(2)); 418 .Times(Exactly(2));
416 419
417 CreateDemuxer("bear-320x240-av_enc-av.webm"); 420 CreateDemuxer("bear-320x240-av_enc-av.webm");
418 InitializeDemuxer(); 421 InitializeDemuxer();
419 } 422 }
420 423
424 TEST_F(FFmpegDemuxerTest, AbortPendingReads) {
425 // We test that on a successful audio packet read.
426 CreateDemuxer("bear-320x240.webm");
427 InitializeDemuxer();
428
429 // Attempt a read from the audio stream and run the message loop until done.
430 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
431
432 // Depending on where in the reading process ffmpeg is, an error may cause the
433 // stream to be marked as EOF. Simulate this here to ensure it is properly
434 // cleared by the AbortPendingReads() call.
435 format_context()->pb->eof_reached = 1;
436 audio->Read(NewReadCB(FROM_HERE, 29, 0, true, DemuxerStream::kAborted));
437 demuxer_->AbortPendingReads();
438 base::RunLoop().Run();
439
440 // Ensure blocking thread has completed outstanding work.
441 demuxer_->Stop();
442 EXPECT_EQ(format_context()->pb->eof_reached, 0);
443 demuxer_.reset();
444 }
445
421 TEST_F(FFmpegDemuxerTest, Read_Audio) { 446 TEST_F(FFmpegDemuxerTest, Read_Audio) {
422 // We test that on a successful audio packet read. 447 // We test that on a successful audio packet read.
423 CreateDemuxer("bear-320x240.webm"); 448 CreateDemuxer("bear-320x240.webm");
424 InitializeDemuxer(); 449 InitializeDemuxer();
425 450
426 // Attempt a read from the audio stream and run the message loop until done. 451 // Attempt a read from the audio stream and run the message loop until done.
427 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); 452 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
428 453
429 audio->Read(NewReadCB(FROM_HERE, 29, 0, true)); 454 audio->Read(NewReadCB(FROM_HERE, 29, 0, true));
430 base::RunLoop().Run(); 455 base::RunLoop().Run();
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 866
842 // Video read #1. 867 // Video read #1.
843 video->Read(NewReadCB(FROM_HERE, 5425, 801000, true)); 868 video->Read(NewReadCB(FROM_HERE, 5425, 801000, true));
844 base::RunLoop().Run(); 869 base::RunLoop().Run();
845 870
846 // Video read #2. 871 // Video read #2.
847 video->Read(NewReadCB(FROM_HERE, 1906, 834000, false)); 872 video->Read(NewReadCB(FROM_HERE, 1906, 834000, false));
848 base::RunLoop().Run(); 873 base::RunLoop().Run();
849 } 874 }
850 875
876 TEST_F(FFmpegDemuxerTest, CancelledSeek) {
877 CreateDemuxer("bear-320x240.webm");
878 InitializeDemuxer();
879
880 // Get our streams.
881 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
882 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
883 ASSERT_TRUE(video);
884 ASSERT_TRUE(audio);
885
886 // Read a video packet and release it.
887 video->Read(NewReadCB(FROM_HERE, 22084, 0, true));
888 base::RunLoop().Run();
889
890 // Issue a simple forward seek, which should discard queued packets.
891 WaitableMessageLoopEvent event;
892 demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000),
893 event.GetPipelineStatusCB());
894 // FFmpegDemuxer does not care what the previous seek time was when canceling.
895 demuxer_->CancelPendingSeek(base::TimeDelta::FromSeconds(12345));
896 event.RunAndWaitForStatus(PIPELINE_OK);
897 }
898
851 TEST_F(FFmpegDemuxerTest, SeekText) { 899 TEST_F(FFmpegDemuxerTest, SeekText) {
852 // We're testing that the demuxer frees all queued packets when it receives 900 // We're testing that the demuxer frees all queued packets when it receives
853 // a Seek(). 901 // a Seek().
854 CreateDemuxer("bear-vp8-webvtt.webm"); 902 CreateDemuxer("bear-vp8-webvtt.webm");
855 DemuxerStream* text_stream = NULL; 903 DemuxerStream* text_stream = NULL;
856 EXPECT_CALL(host_, AddTextStream(_, _)) 904 EXPECT_CALL(host_, AddTextStream(_, _))
857 .WillOnce(SaveArg<0>(&text_stream)); 905 .WillOnce(SaveArg<0>(&text_stream));
858 InitializeDemuxerWithText(); 906 InitializeDemuxerWithText();
859 ASSERT_TRUE(text_stream); 907 ASSERT_TRUE(text_stream);
860 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); 908 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type());
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 1325
1278 const MediaTrack& audio_track = *(media_tracks_->tracks()[1]); 1326 const MediaTrack& audio_track = *(media_tracks_->tracks()[1]);
1279 EXPECT_EQ(audio_track.type(), MediaTrack::Audio); 1327 EXPECT_EQ(audio_track.type(), MediaTrack::Audio);
1280 EXPECT_EQ(audio_track.bytestream_track_id(), 2); 1328 EXPECT_EQ(audio_track.bytestream_track_id(), 2);
1281 EXPECT_EQ(audio_track.kind(), "main"); 1329 EXPECT_EQ(audio_track.kind(), "main");
1282 EXPECT_EQ(audio_track.label(), ""); 1330 EXPECT_EQ(audio_track.label(), "");
1283 EXPECT_EQ(audio_track.language(), ""); 1331 EXPECT_EQ(audio_track.language(), "");
1284 } 1332 }
1285 1333
1286 } // namespace media 1334 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_demuxer.cc ('k') | media/filters/file_data_source.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698