| OLD | NEW | 
|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.  Use of this | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.  Use of this | 
| 2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the | 
| 3 // LICENSE file. | 3 // 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 <queue> | 8 #include <queue> | 
| 9 | 9 | 
| 10 #include "media/base/factory.h" | 10 #include "media/base/factory.h" | 
| 11 #include "media/base/pts_heap.h" | 11 #include "media/base/pts_heap.h" | 
| 12 #include "media/filters/decoder_base.h" | 12 #include "media/filters/decoder_base.h" | 
|  | 13 #include "media/filters/video_decode_engine.h" | 
| 13 #include "testing/gtest/include/gtest/gtest_prod.h" | 14 #include "testing/gtest/include/gtest/gtest_prod.h" | 
| 14 | 15 | 
| 15 // FFmpeg types. | 16 // FFmpeg types. | 
| 16 struct AVCodecContext; | 17 struct AVCodecContext; | 
| 17 struct AVFrame; | 18 struct AVFrame; | 
| 18 struct AVRational; | 19 struct AVRational; | 
|  | 20 struct AVStream; | 
| 19 | 21 | 
| 20 namespace media { | 22 namespace media { | 
| 21 | 23 | 
|  | 24 class FFmpegVideoDecodeEngine : public VideoDecodeEngine { | 
|  | 25  public: | 
|  | 26   FFmpegVideoDecodeEngine(); | 
|  | 27   virtual ~FFmpegVideoDecodeEngine(); | 
|  | 28 | 
|  | 29   // Implementation of the VideoDecodeEngine Interface. | 
|  | 30   virtual void Initialize(AVStream* stream, Task* done_cb); | 
|  | 31   virtual void DecodeFrame(const Buffer& buffer, AVFrame* yuv_frame, | 
|  | 32                            bool* got_result, Task* done_cb); | 
|  | 33   virtual void Flush(Task* done_cb); | 
|  | 34   virtual VideoSurface::Format GetSurfaceFormat() const; | 
|  | 35 | 
|  | 36   virtual State state() const { return state_; } | 
|  | 37 | 
|  | 38   virtual AVCodecContext* codec_context() const { return codec_context_; } | 
|  | 39 | 
|  | 40   virtual void SetCodecContextForTest(AVCodecContext* context) { | 
|  | 41     codec_context_ = context; | 
|  | 42   } | 
|  | 43 | 
|  | 44  private: | 
|  | 45   AVCodecContext* codec_context_; | 
|  | 46   State state_; | 
|  | 47 | 
|  | 48   DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecodeEngine); | 
|  | 49 }; | 
|  | 50 | 
| 22 class FFmpegVideoDecoder : public DecoderBase<VideoDecoder, VideoFrame> { | 51 class FFmpegVideoDecoder : public DecoderBase<VideoDecoder, VideoFrame> { | 
| 23  public: | 52  public: | 
| 24   static FilterFactory* CreateFactory() { | 53   static FilterFactory* CreateFactory(); | 
| 25     return new FilterFactoryImpl0<FFmpegVideoDecoder>(); |  | 
| 26   } |  | 
| 27 |  | 
| 28   static bool IsMediaFormatSupported(const MediaFormat& media_format); | 54   static bool IsMediaFormatSupported(const MediaFormat& media_format); | 
| 29 | 55 | 
| 30  protected: |  | 
| 31   virtual bool OnInitialize(DemuxerStream* demuxer_stream); |  | 
| 32 |  | 
| 33   virtual void OnSeek(base::TimeDelta time); |  | 
| 34 |  | 
| 35   virtual void OnDecode(Buffer* buffer); |  | 
| 36 |  | 
| 37  private: | 56  private: | 
| 38   friend class FilterFactoryImpl0<FFmpegVideoDecoder>; | 57   friend class FilterFactoryImpl1<FFmpegVideoDecoder, VideoDecodeEngine*>; | 
| 39   friend class DecoderPrivateMock; | 58   friend class DecoderPrivateMock; | 
| 40   friend class FFmpegVideoDecoderTest; | 59   friend class FFmpegVideoDecoderTest; | 
| 41   FRIEND_TEST(FFmpegVideoDecoderTest, DecodeFrame_0ByteFrame); |  | 
| 42   FRIEND_TEST(FFmpegVideoDecoderTest, DecodeFrame_DecodeError); |  | 
| 43   FRIEND_TEST(FFmpegVideoDecoderTest, DecodeFrame_Normal); |  | 
| 44   FRIEND_TEST(FFmpegVideoDecoderTest, FindPtsAndDuration); | 60   FRIEND_TEST(FFmpegVideoDecoderTest, FindPtsAndDuration); | 
| 45   FRIEND_TEST(FFmpegVideoDecoderTest, GetSurfaceFormat); | 61   FRIEND_TEST(FFmpegVideoDecoderTest, DoDecode_EnqueueVideoFrameError); | 
| 46   FRIEND_TEST(FFmpegVideoDecoderTest, OnDecode_EnqueueVideoFrameError); | 62   FRIEND_TEST(FFmpegVideoDecoderTest, DoDecode_FinishEnqueuesEmptyFrames); | 
| 47   FRIEND_TEST(FFmpegVideoDecoderTest, OnDecode_FinishEnqueuesEmptyFrames); | 63   FRIEND_TEST(FFmpegVideoDecoderTest, DoDecode_TestStateTransition); | 
| 48   FRIEND_TEST(FFmpegVideoDecoderTest, OnDecode_TestStateTransition); | 64   FRIEND_TEST(FFmpegVideoDecoderTest, DoSeek); | 
| 49   FRIEND_TEST(FFmpegVideoDecoderTest, OnSeek); |  | 
| 50 | 65 | 
| 51   // The TimeTuple struct is used to hold the needed timestamp data needed for | 66   // The TimeTuple struct is used to hold the needed timestamp data needed for | 
| 52   // enqueuing a video frame. | 67   // enqueuing a video frame. | 
| 53   struct TimeTuple { | 68   struct TimeTuple { | 
| 54     base::TimeDelta timestamp; | 69     base::TimeDelta timestamp; | 
| 55     base::TimeDelta duration; | 70     base::TimeDelta duration; | 
| 56   }; | 71   }; | 
| 57 | 72 | 
| 58   FFmpegVideoDecoder(); | 73   FFmpegVideoDecoder(VideoDecodeEngine* engine); | 
| 59   virtual ~FFmpegVideoDecoder(); | 74   virtual ~FFmpegVideoDecoder(); | 
| 60 | 75 | 
|  | 76   // Implement DecoderBase template methods. | 
|  | 77   virtual void DoInitialize(DemuxerStream* demuxer_stream, bool* success, | 
|  | 78                             Task* done_cb); | 
|  | 79   virtual void DoSeek(base::TimeDelta time, Task* done_cb); | 
|  | 80   virtual void DoDecode(Buffer* buffer, Task* done_cb); | 
|  | 81 | 
| 61   virtual bool EnqueueVideoFrame(VideoSurface::Format surface_format, | 82   virtual bool EnqueueVideoFrame(VideoSurface::Format surface_format, | 
| 62                                  const TimeTuple& time, | 83                                  const TimeTuple& time, | 
| 63                                  const AVFrame* frame); | 84                                  const AVFrame* frame); | 
| 64 | 85 | 
| 65   // Create an empty video frame and queue it. | 86   // Create an empty video frame and queue it. | 
| 66   virtual void EnqueueEmptyFrame(); | 87   virtual void EnqueueEmptyFrame(); | 
| 67 | 88 | 
| 68   virtual void CopyPlane(size_t plane, const VideoSurface& surface, | 89   virtual void CopyPlane(size_t plane, const VideoSurface& surface, | 
| 69                          const AVFrame* frame); | 90                          const AVFrame* frame); | 
| 70 | 91 | 
| 71   // Converts a AVCodecContext |pix_fmt| to a VideoSurface::Format. | 92   // Methods that pickup after the decode engine has finished its action. | 
| 72   virtual VideoSurface::Format GetSurfaceFormat( | 93   virtual void OnInitializeComplete(bool* success /* Not owned */, | 
| 73       const AVCodecContext& codec_context); | 94                                     Task* done_cb); | 
| 74 | 95   virtual void OnDecodeComplete(AVFrame* yuv_frame, bool* got_frame, | 
| 75   // Decodes one frame of video with the given buffer.  Returns false if there | 96                                 Task* done_cb); | 
| 76   // was a decode error, or a zero-byte frame was produced. |  | 
| 77   virtual bool DecodeFrame(const Buffer& buffer, AVCodecContext* codec_context, |  | 
| 78                            AVFrame* yuv_frame); |  | 
| 79 | 97 | 
| 80   // Attempt to get the PTS and Duration for this frame by examining the time | 98   // Attempt to get the PTS and Duration for this frame by examining the time | 
| 81   // info provided via packet stream (stored in |pts_heap|), or the info | 99   // info provided via packet stream (stored in |pts_heap|), or the info | 
| 82   // writen into the AVFrame itself.  If no data is available in either, then | 100   // writen into the AVFrame itself.  If no data is available in either, then | 
| 83   // attempt to generate a best guess of the pts based on the last known pts. | 101   // attempt to generate a best guess of the pts based on the last known pts. | 
| 84   // | 102   // | 
| 85   // Data inside the AVFrame (if provided) is trusted the most, followed | 103   // Data inside the AVFrame (if provided) is trusted the most, followed | 
| 86   // by data from the packet stream.  Estimation based on the |last_pts| is | 104   // by data from the packet stream.  Estimation based on the |last_pts| is | 
| 87   // reserved as a last-ditch effort. | 105   // reserved as a last-ditch effort. | 
| 88   virtual TimeTuple FindPtsAndDuration(const AVRational& time_base, | 106   virtual TimeTuple FindPtsAndDuration(const AVRational& time_base, | 
| 89                                        const PtsHeap& pts_heap, | 107                                        const PtsHeap& pts_heap, | 
| 90                                        const TimeTuple& last_pts, | 108                                        const TimeTuple& last_pts, | 
| 91                                        const AVFrame* frame); | 109                                        const AVFrame* frame); | 
| 92 | 110 | 
| 93   // Signals the pipeline that a decode error occurs, and moves the decoder | 111   // Signals the pipeline that a decode error occurs, and moves the decoder | 
| 94   // into the kDecodeFinished state. | 112   // into the kDecodeFinished state. | 
| 95   virtual void SignalPipelineError(); | 113   virtual void SignalPipelineError(); | 
| 96 | 114 | 
|  | 115   // Injection point for unittest to provide a mock engine.  Takes ownership of | 
|  | 116   // the provided engine. | 
|  | 117   virtual void SetVideoDecodeEngineForTest(VideoDecodeEngine* engine); | 
|  | 118 | 
| 97   size_t width_; | 119   size_t width_; | 
| 98   size_t height_; | 120   size_t height_; | 
| 99 | 121 | 
| 100   PtsHeap pts_heap_;  // Heap of presentation timestamps. | 122   PtsHeap pts_heap_;  // Heap of presentation timestamps. | 
| 101   TimeTuple last_pts_; | 123   TimeTuple last_pts_; | 
| 102   scoped_ptr<AVRational> time_base_;  // Pointer to avoid needing full type. | 124   scoped_ptr<AVRational> time_base_;  // Pointer to avoid needing full type. | 
| 103 | 125 | 
| 104   enum DecoderState { | 126   enum DecoderState { | 
| 105     kNormal, | 127     kNormal, | 
| 106     kFlushCodec, | 128     kFlushCodec, | 
| 107     kDecodeFinished, | 129     kDecodeFinished, | 
| 108   }; | 130   }; | 
| 109 | 131 | 
| 110   DecoderState state_; | 132   DecoderState state_; | 
| 111 | 133 | 
| 112   AVCodecContext* codec_context_; | 134   scoped_ptr<VideoDecodeEngine> decode_engine_; | 
| 113 | 135 | 
| 114   DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecoder); | 136   DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecoder); | 
| 115 }; | 137 }; | 
| 116 | 138 | 
| 117 }  // namespace media | 139 }  // namespace media | 
| 118 | 140 | 
| 119 #endif  // MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_ | 141 #endif  // MEDIA_FILTERS_FFMPEG_VIDEO_DECODER_H_ | 
| OLD | NEW | 
|---|