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 |