Merge pull request #5101 from FernetMenta/ffmpeg-threads
[vuplus_xbmc] / xbmc / cores / dvdplayer / DVDCodecs / Video / DXVA.h
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20 #pragma once
21
22 #include "DllAvCodec.h"
23 #include "DVDCodecs/Video/DVDVideoCodecFFmpeg.h"
24 #include "guilib/D3DResource.h"
25 #include "threads/Event.h"
26 #include "DVDResource.h"
27 #include <dxva2api.h>
28 #include <deque>
29 #include <vector>
30 #include "settings/VideoSettings.h"
31 #include "guilib/Geometry.h"
32
33 namespace DXVA {
34
35 class CSurfaceContext
36   : public IDVDResourceCounted<CSurfaceContext>
37 {
38 public:
39   CSurfaceContext();
40   ~CSurfaceContext();
41
42    void HoldSurface(IDirect3DSurface9* surface);
43
44 protected:
45   std::vector<IDirect3DSurface9*> m_heldsurfaces;
46 };
47
48 class CDecoder
49   : public CDVDVideoCodecFFmpeg::IHardwareDecoder
50   , public ID3DResource
51 {
52 public:
53   CDecoder();
54  ~CDecoder();
55   virtual bool Open      (AVCodecContext* avctx, const enum PixelFormat, unsigned int surfaces);
56   virtual int  Decode    (AVCodecContext* avctx, AVFrame* frame);
57   virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture);
58   virtual int  Check     (AVCodecContext* avctx);
59   virtual void Close();
60   virtual const std::string Name() { return "dxva2"; }
61   virtual unsigned GetAllowedReferences();
62
63   bool  OpenTarget(const GUID &guid);
64   bool  OpenDecoder();
65   int   GetBuffer(AVCodecContext *avctx, AVFrame *pic);
66   void  RelBuffer(AVCodecContext *avctx, AVFrame *pic);
67
68   static bool      Supports(enum PixelFormat fmt);
69
70
71 protected:
72   enum EDeviceState
73   { DXVA_OPEN
74   , DXVA_RESET
75   , DXVA_LOST
76   } m_state;
77
78   virtual void OnCreateDevice()  {}
79   virtual void OnDestroyDevice() { CSingleLock lock(m_section); m_state = DXVA_LOST;  m_event.Reset(); }
80   virtual void OnLostDevice()    { CSingleLock lock(m_section); m_state = DXVA_LOST;  m_event.Reset(); }
81   virtual void OnResetDevice()   { CSingleLock lock(m_section); m_state = DXVA_RESET; m_event.Set();   }
82
83   struct SVideoBuffer
84   {
85     SVideoBuffer();
86    ~SVideoBuffer();
87     void Clear();
88
89     IDirect3DSurface9* surface;
90     bool               used;
91     int                age;
92   };
93
94   IDirectXVideoDecoderService* m_service;
95   IDirectXVideoDecoder*        m_decoder;
96   HANDLE                       m_device;
97   GUID                         m_input;
98   DXVA2_VideoDesc              m_format;
99   static const unsigned        m_buffer_max = 32;
100   SVideoBuffer                 m_buffer[m_buffer_max];
101   unsigned                     m_buffer_count;
102   unsigned                     m_buffer_age;
103   int                          m_refs;
104
105   struct dxva_context*         m_context;
106
107   CSurfaceContext*             m_surface_context;
108
109   unsigned int                 m_shared;
110
111   CCriticalSection             m_section;
112   CEvent                       m_event;
113 };
114
115 class CProcessor
116   : public ID3DResource
117 {
118 public:
119   CProcessor();
120  ~CProcessor();
121
122   virtual bool           PreInit();
123   virtual void           UnInit();
124   virtual bool           Open(UINT width, UINT height, unsigned int flags, unsigned int format, unsigned int extended_format);
125   virtual void           Close();
126   virtual REFERENCE_TIME Add(DVDVideoPicture* picture);
127   virtual bool           Render(CRect src, CRect dst, IDirect3DSurface9* target, const REFERENCE_TIME time, DWORD flags);
128   virtual unsigned       Size() { if (m_service) return m_size; return 0; }
129
130   virtual void OnCreateDevice()  {}
131   virtual void OnDestroyDevice() { CSingleLock lock(m_section); Close(); }
132   virtual void OnLostDevice()    { CSingleLock lock(m_section); Close(); }
133   virtual void OnResetDevice()   { CSingleLock lock(m_section); Close(); }
134
135 protected:
136   virtual bool UpdateSize(const DXVA2_VideoDesc& dsc);
137   virtual bool CreateSurfaces();
138   virtual bool OpenProcessor();
139   virtual bool SelectProcessor();
140   virtual void EvaluateQuirkNoDeintProcForProg();
141
142   IDirectXVideoProcessorService* m_service;
143   IDirectXVideoProcessor*        m_process;
144   GUID                           m_device;
145
146   DXVA2_VideoProcessorCaps m_caps;
147   DXVA2_VideoDesc  m_desc;
148
149   DXVA2_ValueRange m_brightness;
150   DXVA2_ValueRange m_contrast;
151   DXVA2_ValueRange m_hue;
152   DXVA2_ValueRange m_saturation;
153   REFERENCE_TIME   m_time;
154   unsigned         m_size;
155   unsigned         m_max_back_refs;
156   unsigned         m_max_fwd_refs;
157   EDEINTERLACEMODE m_deinterlace_mode;
158   EINTERLACEMETHOD m_interlace_method;
159   bool             m_progressive; // true for progressive source or to force ignoring interlacing flags.
160   unsigned         m_index;
161
162   struct SVideoSample
163   {
164     DXVA2_VideoSample sample;
165     CSurfaceContext* context;
166   };
167
168   typedef std::deque<SVideoSample> SSamples;
169   SSamples          m_sample;
170
171   CCriticalSection  m_section;
172
173   LPDIRECT3DSURFACE9* m_surfaces;
174   CSurfaceContext* m_context;
175
176   bool             m_quirk_nodeintprocforprog;
177 };
178
179 };