Chromium Code Reviews| 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 |