 Chromium Code Reviews
 Chromium Code Reviews Issue 2855373002:
  Use ffmpeg packet.pos for restarting reading after reenabling video
    
  
    Issue 2855373002:
  Use ffmpeg packet.pos for restarting reading after reenabling video 
  | 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 // 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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_ | 
| OLD | NEW |