OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #ifndef MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_ | 5 #ifndef MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_ |
6 #define MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_ | 6 #define MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_ |
7 | 7 |
8 #include "base/gtest_prod_util.h" | 8 #include "base/gtest_prod_util.h" |
9 #include "base/time.h" | 9 #include "base/time.h" |
| 10 #include "media/base/factory.h" |
| 11 #include "media/base/filters.h" |
10 #include "media/base/pts_heap.h" | 12 #include "media/base/pts_heap.h" |
11 #include "media/base/video_frame.h" | 13 #include "media/base/video_frame.h" |
12 #include "media/filters/decoder_base.h" | 14 #include "media/filters/decoder_base.h" |
13 | 15 |
14 // FFmpeg types. | 16 // FFmpeg types. |
15 struct AVRational; | 17 struct AVRational; |
16 | 18 |
17 namespace media { | 19 namespace media { |
18 | 20 |
19 class VideoDecodeEngine; | 21 class VideoDecodeEngine; |
20 | 22 |
21 class FFmpegVideoDecoder : public DecoderBase<VideoDecoder, VideoFrame> { | 23 class FFmpegVideoDecoder : public VideoDecoder { |
22 public: | 24 public: |
23 explicit FFmpegVideoDecoder(VideoDecodeEngine* engine); | 25 explicit FFmpegVideoDecoder(VideoDecodeEngine* engine); |
24 virtual ~FFmpegVideoDecoder(); | 26 virtual ~FFmpegVideoDecoder(); |
25 | 27 |
26 static FilterFactory* CreateFactory(); | 28 static FilterFactory* CreateFactory(); |
27 static bool IsMediaFormatSupported(const MediaFormat& media_format); | 29 static bool IsMediaFormatSupported(const MediaFormat& media_format); |
28 | 30 |
29 protected: | 31 // MediaFilter implementation. |
30 virtual void DoInitialize(DemuxerStream* demuxer_stream, bool* success, | 32 virtual void Stop(FilterCallback* callback); |
31 Task* done_cb); | 33 virtual void Seek(base::TimeDelta time, FilterCallback* callback); |
32 virtual void DoStop(Task* done_cb); | 34 virtual void Flush(FilterCallback* callback); |
33 virtual void DoSeek(base::TimeDelta time, Task* done_cb); | |
34 virtual void DoDecode(Buffer* input); | |
35 | 35 |
36 protected: | 36 // Decoder implementation. |
37 virtual void OnEmptyBufferDone(scoped_refptr<Buffer> buffer); | 37 virtual void Initialize(DemuxerStream* demuxer_stream, |
38 virtual void FillThisBuffer(scoped_refptr<VideoFrame> frame); | 38 FilterCallback* callback); |
| 39 virtual const MediaFormat& media_format() { return media_format_; } |
| 40 virtual void FillThisBuffer(scoped_refptr<VideoFrame> video_frame); |
| 41 virtual bool ProvidesBuffer(); |
39 | 42 |
40 private: | 43 private: |
41 friend class FilterFactoryImpl1<FFmpegVideoDecoder, VideoDecodeEngine*>; | 44 friend class FilterFactoryImpl1<FFmpegVideoDecoder, VideoDecodeEngine*>; |
42 friend class DecoderPrivateMock; | 45 friend class DecoderPrivateMock; |
43 friend class FFmpegVideoDecoderTest; | 46 friend class FFmpegVideoDecoderTest; |
44 FRIEND_TEST_ALL_PREFIXES(FFmpegVideoDecoderTest, FindPtsAndDuration); | 47 FRIEND_TEST_ALL_PREFIXES(FFmpegVideoDecoderTest, FindPtsAndDuration); |
45 FRIEND_TEST_ALL_PREFIXES(FFmpegVideoDecoderTest, | 48 FRIEND_TEST_ALL_PREFIXES(FFmpegVideoDecoderTest, |
46 DoDecode_EnqueueVideoFrameError); | 49 DoDecode_EnqueueVideoFrameError); |
47 FRIEND_TEST_ALL_PREFIXES(FFmpegVideoDecoderTest, | 50 FRIEND_TEST_ALL_PREFIXES(FFmpegVideoDecoderTest, |
48 DoDecode_FinishEnqueuesEmptyFrames); | 51 DoDecode_FinishEnqueuesEmptyFrames); |
49 FRIEND_TEST_ALL_PREFIXES(FFmpegVideoDecoderTest, | 52 FRIEND_TEST_ALL_PREFIXES(FFmpegVideoDecoderTest, |
50 DoDecode_TestStateTransition); | 53 DoDecode_TestStateTransition); |
51 FRIEND_TEST_ALL_PREFIXES(FFmpegVideoDecoderTest, DoSeek); | 54 FRIEND_TEST_ALL_PREFIXES(FFmpegVideoDecoderTest, DoSeek); |
52 | 55 |
53 // The TimeTuple struct is used to hold the needed timestamp data needed for | 56 // The TimeTuple struct is used to hold the needed timestamp data needed for |
54 // enqueuing a video frame. | 57 // enqueuing a video frame. |
55 struct TimeTuple { | 58 struct TimeTuple { |
56 base::TimeDelta timestamp; | 59 base::TimeDelta timestamp; |
57 base::TimeDelta duration; | 60 base::TimeDelta duration; |
58 }; | 61 }; |
59 | 62 |
60 enum DecoderState { | 63 enum DecoderState { |
| 64 kUnInitialized, |
61 kNormal, | 65 kNormal, |
62 kFlushCodec, | 66 kFlushCodec, |
63 kDecodeFinished, | 67 kDecodeFinished, |
| 68 kStopped |
64 }; | 69 }; |
65 | 70 |
66 // Implement DecoderBase template methods. | 71 void OnInitializeComplete(FilterCallback* done_cb); |
67 virtual void EnqueueVideoFrame(const scoped_refptr<VideoFrame>& video_frame); | 72 void OnStopComplete(FilterCallback* callback); |
| 73 void OnFlushComplete(FilterCallback* callback); |
| 74 void OnSeekComplete(FilterCallback* callback); |
| 75 void OnReadComplete(Buffer* buffer); |
68 | 76 |
69 // Create an empty video frame and queue it. | 77 // TODO(jiesun): until demuxer pass scoped_refptr<Buffer>: we could not merge |
70 virtual void EnqueueEmptyFrame(); | 78 // this with OnReadComplete |
| 79 void OnReadCompleteTask(scoped_refptr<Buffer> buffer); |
71 | 80 |
72 // Methods that pickup after the decode engine has finished its action. | 81 virtual void OnEngineEmptyBufferDone(scoped_refptr<Buffer> buffer); |
73 virtual void OnInitializeComplete(bool* success /* Not owned */, | 82 virtual void OnEngineFillBufferDone(scoped_refptr<VideoFrame> video_frame); |
74 Task* done_cb); | |
75 | |
76 virtual void OnDecodeComplete(scoped_refptr<VideoFrame> video_frame); | |
77 | 83 |
78 // Attempt to get the PTS and Duration for this frame by examining the time | 84 // Attempt to get the PTS and Duration for this frame by examining the time |
79 // info provided via packet stream (stored in |pts_heap|), or the info | 85 // info provided via packet stream (stored in |pts_heap|), or the info |
80 // writen into the AVFrame itself. If no data is available in either, then | 86 // written into the AVFrame itself. If no data is available in either, then |
81 // attempt to generate a best guess of the pts based on the last known pts. | 87 // attempt to generate a best guess of the pts based on the last known pts. |
82 // | 88 // |
83 // Data inside the AVFrame (if provided) is trusted the most, followed | 89 // Data inside the AVFrame (if provided) is trusted the most, followed |
84 // by data from the packet stream. Estimation based on the |last_pts| is | 90 // by data from the packet stream. Estimation based on the |last_pts| is |
85 // reserved as a last-ditch effort. | 91 // reserved as a last-ditch effort. |
86 virtual TimeTuple FindPtsAndDuration(const AVRational& time_base, | 92 virtual TimeTuple FindPtsAndDuration(const AVRational& time_base, |
87 PtsHeap* pts_heap, | 93 PtsHeap* pts_heap, |
88 const TimeTuple& last_pts, | 94 const TimeTuple& last_pts, |
89 const VideoFrame* frame); | 95 const VideoFrame* frame); |
90 | 96 |
91 // Signals the pipeline that a decode error occurs, and moves the decoder | |
92 // into the kDecodeFinished state. | |
93 virtual void SignalPipelineError(); | |
94 | |
95 // Injection point for unittest to provide a mock engine. Takes ownership of | 97 // Injection point for unittest to provide a mock engine. Takes ownership of |
96 // the provided engine. | 98 // the provided engine. |
97 virtual void SetVideoDecodeEngineForTest(VideoDecodeEngine* engine); | 99 virtual void SetVideoDecodeEngineForTest(VideoDecodeEngine* engine); |
98 | 100 |
99 size_t width_; | 101 size_t width_; |
100 size_t height_; | 102 size_t height_; |
| 103 MediaFormat media_format_; |
101 | 104 |
102 PtsHeap pts_heap_; // Heap of presentation timestamps. | 105 PtsHeap pts_heap_; // Heap of presentation timestamps. |
103 TimeTuple last_pts_; | 106 TimeTuple last_pts_; |
104 scoped_ptr<AVRational> time_base_; // Pointer to avoid needing full type. | 107 scoped_ptr<AVRational> time_base_; // Pointer to avoid needing full type. |
105 DecoderState state_; | 108 DecoderState state_; |
106 scoped_ptr<VideoDecodeEngine> decode_engine_; | 109 scoped_ptr<VideoDecodeEngine> decode_engine_; |
107 | 110 |
| 111 // Tracks the number of asynchronous reads issued to |demuxer_stream_|. |
| 112 // Using size_t since it is always compared against deque::size(). |
| 113 size_t pending_reads_; |
| 114 // Tracks the number of asynchronous reads issued from renderer. |
| 115 size_t pending_requests_; |
| 116 |
| 117 // Pointer to the demuxer stream that will feed us compressed buffers. |
| 118 scoped_refptr<DemuxerStream> demuxer_stream_; |
| 119 |
108 DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecoder); | 120 DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecoder); |
109 }; | 121 }; |
110 | 122 |
111 } // namespace media | 123 } // namespace media |
112 | 124 |
113 #endif // MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_ | 125 #endif // MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_ |
OLD | NEW |