| Index: media/mf/mft_h264_decoder.h
|
| ===================================================================
|
| --- media/mf/mft_h264_decoder.h (revision 57106)
|
| +++ media/mf/mft_h264_decoder.h (working copy)
|
| @@ -2,146 +2,96 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
| //
|
| -// Decodes H.264 Annex B streams using the Media Foundation H.264 decoder as
|
| -// a standalone Media Foundation Transform (MFT).
|
| -// Note: A single MftH264Decoder instance is only for 1 H.264 video stream only.
|
| -// Inputting streams consisting of more than 1 video to a single instance
|
| -// may result in undefined behavior.
|
| +// MFT H.264 decoder.
|
|
|
| #ifndef MEDIA_MF_MFT_H264_DECODER_H_
|
| #define MEDIA_MF_MFT_H264_DECODER_H_
|
|
|
| -#include <string>
|
| +#include "build/build_config.h" // For OS_WIN.
|
|
|
| +#if defined(OS_WIN)
|
| +
|
| +#include <deque>
|
| +
|
| +#include <d3d9.h>
|
| +#include <dxva2api.h>
|
| #include <mfidl.h>
|
|
|
| -#include "base/basictypes.h"
|
| -#include "base/callback.h"
|
| #include "base/gtest_prod_util.h"
|
| -#include "base/scoped_ptr.h"
|
| +#include "base/scoped_comptr_win.h"
|
| +#include "media/filters/video_decode_engine.h"
|
|
|
| -struct IDirect3DDeviceManager9;
|
| -struct IMFTransform;
|
| +class MessageLoop;
|
|
|
| namespace media {
|
|
|
| -class DataBuffer;
|
| -class VideoFrame;
|
| -
|
| -// A decoder that takes samples of Annex B streams then outputs decoded frames.
|
| -class MftH264Decoder : public base::RefCountedThreadSafe<MftH264Decoder> {
|
| +class MftH264Decoder : public media::VideoDecodeEngine {
|
| public:
|
| - enum Error {
|
| - kResetOutputStreamFailed = 0,
|
| - kNoMoreOutput,
|
| - kUnspecifiedError,
|
| - kNoMemory,
|
| - kOutputSampleError
|
| - };
|
| - typedef Callback1<scoped_refptr<DataBuffer>*>::Type
|
| - ReadInputCallback;
|
| - typedef Callback1<scoped_refptr<VideoFrame> >::Type OutputReadyCallback;
|
| - typedef Callback1<Error>::Type OutputErrorCallback;
|
| + typedef enum {
|
| + kUninitialized, // un-initialized.
|
| + kNormal, // normal playing state.
|
| + kFlushing, // upon received Flush(), before FlushDone()
|
| + kEosDrain, // upon input EOS received.
|
| + kStopped, // upon output EOS received.
|
| + } State;
|
|
|
| explicit MftH264Decoder(bool use_dxva);
|
| ~MftH264Decoder();
|
| + virtual void Initialize(MessageLoop* message_loop,
|
| + media::VideoDecodeEngine::EventHandler* event_handler,
|
| + const VideoCodecConfig& config);
|
| + virtual void Uninitialize();
|
| + virtual void Flush();
|
| + virtual void Seek();
|
| + virtual void EmptyThisBuffer(scoped_refptr<Buffer> buffer);
|
| + virtual void FillThisBuffer(scoped_refptr<VideoFrame> frame);
|
|
|
| - // Initializes the decoder. |dev_manager| is not required if the decoder does
|
| - // not use DXVA.
|
| - // If the other arguments are not known, leave them as 0. They can be
|
| - // provided to the decoder to try to avoid an initial output format change,
|
| - // but it is not necessary to have them.
|
| - // The object takes ownership of the callbacks. However, the caller must
|
| - // make sure the objects associated with the callbacks outlives the time
|
| - // when GetOutput() will be called.
|
| - bool Init(IDirect3DDeviceManager9* dev_manager,
|
| - int frame_rate_num, int frame_rate_denom,
|
| - int width, int height,
|
| - int aspect_num, int aspect_denom,
|
| - ReadInputCallback* read_input_cb,
|
| - OutputReadyCallback* output_avail_cb,
|
| - OutputErrorCallback* output_error_cb);
|
| -
|
| - // Tries to get an output sample from the decoder, and if successful, calls
|
| - // the callback with the sample, or status of the decoder if an error
|
| - // occurred.
|
| - void GetOutput();
|
| - bool Flush();
|
| -
|
| - bool initialized() const { return initialized_; }
|
| bool use_dxva() const { return use_dxva_; }
|
| - bool drain_message_sent() const { return drain_message_sent_; }
|
| - int in_buffer_size() const { return in_buffer_size_; }
|
| - int out_buffer_size() const { return out_buffer_size_; }
|
| - int frames_read() const { return frames_read_; }
|
| - int frames_decoded() const { return frames_decoded_; }
|
| - int width() const { return width_; }
|
| - int height() const { return height_; }
|
| + State state() const { return state_; }
|
|
|
| private:
|
| friend class MftH264DecoderTest;
|
| - FRIEND_TEST_ALL_PREFIXES(MftH264DecoderTest,
|
| - SendDrainMessageBeforeInitDeathTest);
|
| - FRIEND_TEST_ALL_PREFIXES(MftH264DecoderTest, SendDrainMessageAtInit);
|
| - FRIEND_TEST_ALL_PREFIXES(MftH264DecoderTest, DrainOnEndOfInputStream);
|
| - FRIEND_TEST_ALL_PREFIXES(MftH264DecoderTest, NoOutputOnGarbageInput);
|
| + FRIEND_TEST_ALL_PREFIXES(MftH264DecoderTest, LibraryInit);
|
|
|
| - bool InitComMfLibraries();
|
| - bool InitDecoder(IDirect3DDeviceManager9* dev_manager,
|
| - int frame_rate_num, int frame_rate_denom,
|
| - int width, int height,
|
| - int aspect_num, int aspect_denom);
|
| - bool SetDecoderD3d9Manager(IDirect3DDeviceManager9* dev_manager);
|
| - bool SetDecoderMediaTypes(int frame_rate_num, int frame_rate_denom,
|
| - int width, int height,
|
| - int aspect_num, int aspect_denom);
|
| - bool SetDecoderInputMediaType(int frame_rate_num, int frame_rate_denom,
|
| - int width, int height,
|
| - int aspect_num, int aspect_denom);
|
| + // TODO(jiesun): Find a way to move all these to GpuVideoService..
|
| + static bool StartupComLibraries();
|
| + static void ShutdownComLibraries();
|
| + bool CreateD3DDevManager();
|
| +
|
| + bool InitInternal();
|
| + bool InitDecoder();
|
| + bool CheckDecoderDxvaSupport();
|
| + bool SetDecoderMediaTypes();
|
| + bool SetDecoderInputMediaType();
|
| bool SetDecoderOutputMediaType(const GUID subtype);
|
| - bool SendStartMessage();
|
| + bool SendMFTMessage(MFT_MESSAGE_TYPE msg);
|
| bool GetStreamsInfoAndBufferReqs();
|
| - bool ReadInput();
|
|
|
| - // Sends an Annex B stream to the decoder. The times here should be given
|
| - // in 100ns units. This creates a IMFSample, copies the stream over to the
|
| - // sample, and sends the sample to the decoder.
|
| - // Returns: true if the sample was sent successfully.
|
| - bool SendInput(const uint8* data, int size, int64 timestamp, int64 duration);
|
| + bool DoDecode();
|
|
|
| - bool SendEndOfStreamMessage();
|
|
|
| - // Sends a drain message to the decoder to indicate no more input will be
|
| - // sent. SendInput() should not be called after calling this method.
|
| - // Returns: true if the drain message was sent successfully.
|
| - bool SendDrainMessage();
|
| -
|
| - // |output_error_callback_| should stop the message loop.
|
| - scoped_ptr<ReadInputCallback> read_input_callback_;
|
| - scoped_ptr<OutputReadyCallback> output_avail_callback_;
|
| - scoped_ptr<OutputErrorCallback> output_error_callback_;
|
| - IMFTransform* decoder_;
|
| - bool initialized_;
|
| bool use_dxva_;
|
| - bool drain_message_sent_;
|
| - bool next_frame_discontinuous_;
|
|
|
| - // Minimum input and output buffer sizes/alignment required by the decoder.
|
| - // If |buffer_alignment_| is zero, then the buffer needs not be aligned.
|
| - int in_buffer_size_;
|
| - int in_buffer_alignment_;
|
| - int out_buffer_size_;
|
| - int out_buffer_alignment_;
|
| - int frames_read_;
|
| - int frames_decoded_;
|
| - int width_;
|
| - int height_;
|
| - int stride_;
|
| - const GUID output_format_;
|
| + ScopedComPtr<IDirect3D9> d3d9_;
|
| + ScopedComPtr<IDirect3DDevice9> device_;
|
| + ScopedComPtr<IDirect3DDeviceManager9> device_manager_;
|
| + HWND device_window_;
|
| + ScopedComPtr<IMFTransform> decoder_;
|
|
|
| + MFT_INPUT_STREAM_INFO input_stream_info_;
|
| + MFT_OUTPUT_STREAM_INFO output_stream_info_;
|
| +
|
| + State state_;
|
| +
|
| + VideoDecodeEngine::EventHandler* event_handler_;
|
| + VideoCodecConfig config_;
|
| + VideoCodecInfo info_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(MftH264Decoder);
|
| };
|
|
|
| } // namespace media
|
|
|
| +#endif // defined(OS_WIN)
|
| +
|
| #endif // MEDIA_MF_MFT_H264_DECODER_H_
|
|
|