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

Side by Side Diff: media/filters/ffmpeg_demuxer.h

Issue 2855373002: Use ffmpeg packet.pos for restarting reading after reenabling video
Patch Set: reset pending_seek_position_ after calling the pending_seek_cb_ Created 3 years, 7 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 | « no previous file | media/filters/ffmpeg_demuxer.cc » ('j') | media/filters/ffmpeg_demuxer.cc » ('J')
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 // Implements the Demuxer interface using FFmpeg's libavformat. At this time 5 // Implements the Demuxer interface using FFmpeg's libavformat. At this time
6 // will support demuxing any audio/video format thrown at it. The streams 6 // will support demuxing any audio/video format thrown at it. The streams
7 // output mime types audio/x-ffmpeg and video/x-ffmpeg and include an integer 7 // output mime types audio/x-ffmpeg and video/x-ffmpeg and include an integer
8 // key FFmpegCodecID which contains the CodecID enumeration value. The CodecIDs 8 // key FFmpegCodecID which contains the CodecID enumeration value. The CodecIDs
9 // can be used to create and initialize the corresponding FFmpeg decoder. 9 // can be used to create and initialize the corresponding FFmpeg decoder.
10 // 10 //
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 ReadCB read_cb_; 193 ReadCB read_cb_;
194 StreamStatusChangeCB stream_status_change_cb_; 194 StreamStatusChangeCB stream_status_change_cb_;
195 195
196 #if BUILDFLAG(USE_PROPRIETARY_CODECS) 196 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
197 std::unique_ptr<FFmpegBitstreamConverter> bitstream_converter_; 197 std::unique_ptr<FFmpegBitstreamConverter> bitstream_converter_;
198 #endif 198 #endif
199 199
200 std::string encryption_key_id_; 200 std::string encryption_key_id_;
201 bool fixup_negative_timestamps_; 201 bool fixup_negative_timestamps_;
202 202
203 base::TimeDelta stream_capacity_;
204
203 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerStream); 205 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerStream);
204 }; 206 };
205 207
206 class MEDIA_EXPORT FFmpegDemuxer : public Demuxer { 208 class MEDIA_EXPORT FFmpegDemuxer : public Demuxer {
207 public: 209 public:
208 FFmpegDemuxer(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 210 FFmpegDemuxer(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
209 DataSource* data_source, 211 DataSource* data_source,
210 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb, 212 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb,
211 const MediaTracksUpdatedCB& media_tracks_updated_cb, 213 const MediaTracksUpdatedCB& media_tracks_updated_cb,
212 MediaLog* media_log); 214 MediaLog* media_log);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 266
265 // FFmpeg callbacks during initialization. 267 // FFmpeg callbacks during initialization.
266 void OnOpenContextDone(const PipelineStatusCB& status_cb, bool result); 268 void OnOpenContextDone(const PipelineStatusCB& status_cb, bool result);
267 void OnFindStreamInfoDone(const PipelineStatusCB& status_cb, int result); 269 void OnFindStreamInfoDone(const PipelineStatusCB& status_cb, int result);
268 270
269 void LogMetadata(AVFormatContext* avctx, base::TimeDelta max_duration); 271 void LogMetadata(AVFormatContext* avctx, base::TimeDelta max_duration);
270 272
271 // FFmpeg callbacks during seeking. 273 // FFmpeg callbacks during seeking.
272 void OnSeekFrameDone(int result); 274 void OnSeekFrameDone(int result);
273 275
276 // Called when FFmpeg completes the seek initiated in
277 // OnSelectedVideoTrackChanged in order to restart the |stream|.
278 void OnSeekDoneForRestartingStream(FFmpegDemuxerStream* stream, int result);
279
274 // FFmpeg callbacks during reading + helper method to initiate reads. 280 // FFmpeg callbacks during reading + helper method to initiate reads.
275 void ReadFrameIfNeeded(); 281 void ReadFrameIfNeeded();
276 void OnReadFrameDone(ScopedAVPacket packet, int result); 282 void OnReadFrameDone(ScopedAVPacket packet, int result);
277 283
278 // Returns true iff any stream has additional capacity. Note that streams can 284 // Returns true iff any stream has additional capacity. Note that streams can
279 // go over capacity depending on how the file is muxed. 285 // go over capacity depending on how the file is muxed.
280 bool StreamsHaveAvailableCapacity(); 286 bool StreamsHaveAvailableCapacity();
281 287
282 // Returns true if the maximum allowed memory usage has been reached. 288 // Returns true if the maximum allowed memory usage has been reached.
283 bool IsMaxMemoryUsageReached() const; 289 bool IsMaxMemoryUsageReached() const;
284 290
285 // Signal all FFmpegDemuxerStreams that the stream has ended. 291 // Signal all FFmpegDemuxerStreams that the stream has ended.
286 void StreamHasEnded(); 292 void StreamHasEnded();
287 293
288 // Called by |url_protocol_| whenever |data_source_| returns a read error. 294 // Called by |url_protocol_| whenever |data_source_| returns a read error.
289 void OnDataSourceError(); 295 void OnDataSourceError();
290 296
291 // Returns the first stream from |streams_| that matches |type| as an 297 // Returns the first stream from |streams_| that matches |type| as an
292 // FFmpegDemuxerStream and is enabled. 298 // FFmpegDemuxerStream and is enabled.
293 FFmpegDemuxerStream* GetFirstEnabledFFmpegStream( 299 FFmpegDemuxerStream* GetFirstEnabledFFmpegStream(
294 DemuxerStream::Type type) const; 300 DemuxerStream::Type type) const;
295 301
296 // Called after the streams have been collected from the media, to allow 302 // Called after the streams have been collected from the media, to allow
297 // the text renderer to bind each text stream to the cue rendering engine. 303 // the text renderer to bind each text stream to the cue rendering engine.
298 void AddTextStreams(); 304 void AddTextStreams();
299 305
300 void SetLiveness(DemuxerStream::Liveness liveness); 306 void SetLiveness(DemuxerStream::Liveness liveness);
301 307
308 // Do an FFmpeg seek such that the read position is adjusted to be able to
309 // restart playback from the |time| position. If the |preferred_stream| is not
310 // null then it is used for seeking, otherwise the preferred stream is
311 // selected by FindPreferredStreamForSeeking function. When the seek is
312 // completed the |ffmpeg_seek_done_cb| will be called with FFmpeg result.
313 using FFmpegSeekDoneCB = base::Callback<void(int ffmpeg_result)>;
314 void SeekInternal(base::TimeDelta time,
315 FFmpegDemuxerStream* preferred_stream,
316 const FFmpegSeekDoneCB& ffmpeg_seek_done_cb);
DaleCurtis 2017/05/24 22:24:18 pass by value nowadays.
servolk 2017/05/24 22:58:20 Done.
317
302 DemuxerHost* host_; 318 DemuxerHost* host_;
303 319
304 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 320 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
305 321
306 // Task runner on which all blocking FFmpeg operations are executed; retrieved 322 // Task runner on which all blocking FFmpeg operations are executed; retrieved
307 // from base::TaskScheduler. 323 // from base::TaskScheduler.
308 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; 324 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
309 325
310 // Indicates if Stop() has been called. 326 // Indicates if Stop() has been called.
311 bool stopped_; 327 bool stopped_;
312 328
313 // Tracks if there's an outstanding av_read_frame() operation. 329 // Tracks if there's an outstanding av_read_frame() operation.
314 // 330 //
315 // TODO(scherkus): Allow more than one read in flight for higher read 331 // TODO(scherkus): Allow more than one read in flight for higher read
316 // throughput using demuxer_bench to verify improvements. 332 // throughput using demuxer_bench to verify improvements.
317 bool pending_read_; 333 bool pending_read_;
318 334
319 // Tracks if there's an outstanding av_seek_frame() operation. Used to discard 335 // Tracks if there's an outstanding av_seek_frame() operation. Used to discard
320 // results of pre-seek av_read_frame() operations. 336 // results of pre-seek av_read_frame() operations.
321 PipelineStatusCB pending_seek_cb_; 337 PipelineStatusCB pending_seek_cb_;
338 base::TimeDelta pending_seek_position_;
322 339
323 // |streams_| mirrors the AVStream array in AVFormatContext. It contains 340 // |streams_| mirrors the AVStream array in AVFormatContext. It contains
324 // FFmpegDemuxerStreams encapsluating AVStream objects at the same index. 341 // FFmpegDemuxerStreams encapsluating AVStream objects at the same index.
325 // 342 //
326 // Since we only support a single audio and video stream, |streams_| will 343 // Since we only support a single audio and video stream, |streams_| will
327 // contain NULL entries for additional audio/video streams as well as for 344 // contain NULL entries for additional audio/video streams as well as for
328 // stream types that we do not currently support. 345 // stream types that we do not currently support.
329 // 346 //
330 // Once initialized, operations on FFmpegDemuxerStreams should be carried out 347 // Once initialized, operations on FFmpegDemuxerStreams should be carried out
331 // on the demuxer thread. 348 // on the demuxer thread.
(...skipping 18 matching lines...) Expand all
350 // start time) with enabled status matching |enabled|. 367 // start time) with enabled status matching |enabled|.
351 FFmpegDemuxerStream* FindStreamWithLowestStartTimestamp(bool enabled); 368 FFmpegDemuxerStream* FindStreamWithLowestStartTimestamp(bool enabled);
352 369
353 // Finds a preferred stream for seeking to |seek_time|. Preference is 370 // Finds a preferred stream for seeking to |seek_time|. Preference is
354 // typically given to video streams, unless the |seek_time| is earlier than 371 // typically given to video streams, unless the |seek_time| is earlier than
355 // the start time of the video stream. In that case a stream with the earliest 372 // the start time of the video stream. In that case a stream with the earliest
356 // start time is preferred. Disabled streams are considered only as the last 373 // start time is preferred. Disabled streams are considered only as the last
357 // fallback option. 374 // fallback option.
358 FFmpegDemuxerStream* FindPreferredStreamForSeeking(base::TimeDelta seek_time); 375 FFmpegDemuxerStream* FindPreferredStreamForSeeking(base::TimeDelta seek_time);
359 376
377 // Restarts a previous pending seek if a video stream got re-enabled while a
378 // pending seek was in progress.
379 void RestartPendingSeek(base::TimeDelta time,
380 const PipelineStatusCB& cb,
DaleCurtis 2017/05/24 22:24:18 Ditto.
381 PipelineStatus prev_seek_status);
382
360 // The Time associated with timestamp 0. Set to a null 383 // The Time associated with timestamp 0. Set to a null
361 // time if the file doesn't have an association to Time. 384 // time if the file doesn't have an association to Time.
362 base::Time timeline_offset_; 385 base::Time timeline_offset_;
363 386
364 // Whether text streams have been enabled for this demuxer. 387 // Whether text streams have been enabled for this demuxer.
365 bool text_enabled_; 388 bool text_enabled_;
366 389
367 // Set if we know duration of the audio stream. Used when processing end of 390 // Set if we know duration of the audio stream. Used when processing end of
368 // stream -- at this moment we definitely know duration. 391 // stream -- at this moment we definitely know duration.
369 bool duration_known_; 392 bool duration_known_;
370 base::TimeDelta duration_; 393 base::TimeDelta duration_;
371 394
372 // FFmpegURLProtocol implementation and corresponding glue bits. 395 // FFmpegURLProtocol implementation and corresponding glue bits.
373 std::unique_ptr<BlockingUrlProtocol> url_protocol_; 396 std::unique_ptr<BlockingUrlProtocol> url_protocol_;
374 std::unique_ptr<FFmpegGlue> glue_; 397 std::unique_ptr<FFmpegGlue> glue_;
375 398
376 const EncryptedMediaInitDataCB encrypted_media_init_data_cb_; 399 const EncryptedMediaInitDataCB encrypted_media_init_data_cb_;
377 400
378 const MediaTracksUpdatedCB media_tracks_updated_cb_; 401 const MediaTracksUpdatedCB media_tracks_updated_cb_;
379 402
380 std::map<MediaTrack::Id, FFmpegDemuxerStream*> track_id_to_demux_stream_map_; 403 std::map<MediaTrack::Id, FFmpegDemuxerStream*> track_id_to_demux_stream_map_;
381 404
405 int64_t last_audio_packet_pos_;
406 FFmpegDemuxerStream* restarting_stream_;
407
382 // NOTE: Weak pointers must be invalidated before all other member variables. 408 // NOTE: Weak pointers must be invalidated before all other member variables.
383 base::WeakPtr<FFmpegDemuxer> weak_this_; 409 base::WeakPtr<FFmpegDemuxer> weak_this_;
384 base::WeakPtrFactory<FFmpegDemuxer> cancel_pending_seek_factory_; 410 base::WeakPtrFactory<FFmpegDemuxer> cancel_pending_seek_factory_;
385 base::WeakPtrFactory<FFmpegDemuxer> weak_factory_; 411 base::WeakPtrFactory<FFmpegDemuxer> weak_factory_;
386 412
387 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxer); 413 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxer);
388 }; 414 };
389 415
390 } // namespace media 416 } // namespace media
391 417
392 #endif // MEDIA_FILTERS_FFMPEG_DEMUXER_H_ 418 #endif // MEDIA_FILTERS_FFMPEG_DEMUXER_H_
OLDNEW
« no previous file with comments | « no previous file | media/filters/ffmpeg_demuxer.cc » ('j') | media/filters/ffmpeg_demuxer.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698