summaryrefslogtreecommitdiffstats
path: root/chrome/gpu/gpu_video_decoder_mft.h
blob: 3644617b671e6368b41250bc1b8d26fe09ba36e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_GPU_GPU_VIDEO_DECODER_MFT_H_
#define CHROME_GPU_GPU_VIDEO_DECODER_MFT_H_

#include "build/build_config.h"  // For OS_WIN.

#if defined(OS_WIN)

#include <d3d9.h>
#include <dxva2api.h>
#include <evr.h>
#include <initguid.h>
#include <mfapi.h>
#include <mferror.h>
#include <mfidl.h>
#include <shlwapi.h>
#include <wmcodecdsp.h>

#include <deque>

#include "base/scoped_comptr_win.h"
#include "chrome/gpu/gpu_video_decoder.h"

class GpuVideoDecoderMFT : public GpuVideoDecoder {
 public:
  virtual bool DoInitialize(const GpuVideoDecoderInitParam& init_param,
                            GpuVideoDecoderInitDoneParam* done_param);
  virtual bool DoUninitialize();
  virtual void DoFlush();
  virtual void DoEmptyThisBuffer(const GpuVideoDecoderInputBufferParam& buffer);
  virtual void DoFillThisBuffer(const GpuVideoDecoderOutputBufferParam& frame);
  virtual void DoFillThisBufferDoneACK();

 private:
  GpuVideoDecoderMFT(const GpuVideoDecoderInfoParam* param,
                     GpuChannel* channel_,
                     base::ProcessHandle handle);

  friend class GpuVideoService;

  // TODO(jiesun): Find a way to move all these to GpuVideoService..
  static bool StartupComLibraries();
  static void ShutdownComLibraries();
  bool CreateD3DDevManager(HWND video_window);

  // helper.
  bool InitMediaFoundation();
  bool InitDecoder();
  bool CheckDecoderDxvaSupport();

  bool SetDecoderMediaTypes();
  bool SetDecoderInputMediaType();
  bool SetDecoderOutputMediaType(const GUID subtype);
  bool SendMFTMessage(MFT_MESSAGE_TYPE msg);
  bool GetStreamsInfoAndBufferReqs();

  // Help function to create IMFSample* out of input buffer.
  // data are copied into IMFSample's own IMFMediaBuffer.
  // Client should Release() the IMFSample*.
  static IMFSample* CreateInputSample(uint8* data,
                                      int32 size,
                                      int64 timestamp,
                                      int64 duration,
                                      int32 min_size);

  bool DoDecode();

  ScopedComPtr<IDirect3D9> d3d9_;
  ScopedComPtr<IDirect3DDevice9> device_;
  ScopedComPtr<IDirect3DDeviceManager9> device_manager_;
  ScopedComPtr<IMFTransform> decoder_;

  MFT_INPUT_STREAM_INFO input_stream_info_;
  MFT_OUTPUT_STREAM_INFO output_stream_info_;

  std::deque<ScopedComPtr<IMFSample> > input_buffer_queue_;
  bool output_transfer_buffer_busy_;

  typedef enum {
    kNormal,     // normal playing state.
    kFlushing,   // upon received Flush(), before FlushDone()
    kEosFlush,   // upon input EOS received.
    kStopped,    // upon output EOS received.
  } State;
  State state_;

  int32 pending_request_;

  DISALLOW_COPY_AND_ASSIGN(GpuVideoDecoderMFT);
};

#endif

#endif  // CHROME_GPU_GPU_VIDEO_DECODER_MFT_H_