Initial work for DXVA2 support.
[vlc.git] / modules / codec / avcodec / dxva2.c
1 /*****************************************************************************
2  * dxva.c: DXVA 2 video decoder
3  *****************************************************************************
4  * Copyright (C) 2009 Geoffroy Couprie
5  * $Id$
6  *
7  * Authors: Geoffroy Couprie <geal@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_codec.h>
34
35 #include <windows.h>
36 #include <windowsx.h>
37 #include <ole2.h>
38 #include <commctrl.h>
39 #include <shlwapi.h>
40 #include <d3d9.h>
41
42 #include "dxva.h"
43
44 DEFINE_GUID(DXVA2_ModeMPEG2_MoComp, 0xe6a9f44b, 0x61b0, 0x4563,0x9e,0xa4,0x63,0xd2,0xa3,0xc6,0xfe,0x66);
45 DEFINE_GUID(DXVA2_ModeMPEG2_IDCT,   0xbf22ad00, 0x03ea, 0x4690,0x80,0x77,0x47,0x33,0x46,0x20,0x9b,0x7e);
46 DEFINE_GUID(DXVA2_ModeMPEG2_VLD,    0xee27417f, 0x5e28, 0x4e65,0xbe,0xea,0x1d,0x26,0xb5,0x08,0xad,0xc9);
47 DEFINE_GUID(DXVA2_ModeH264_A,  0x1b81be64, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
48 DEFINE_GUID(DXVA2_ModeH264_B,  0x1b81be65, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
49 DEFINE_GUID(DXVA2_ModeH264_C,  0x1b81be66, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
50 DEFINE_GUID(DXVA2_ModeH264_D,  0x1b81be67, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
51 DEFINE_GUID(DXVA2_ModeH264_E,  0x1b81be68, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
52 DEFINE_GUID(DXVA2_ModeH264_F,  0x1b81be69, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
53 DEFINE_GUID(DXVA2_ModeWMV8_A,  0x1b81be80, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
54 DEFINE_GUID(DXVA2_ModeWMV8_B,  0x1b81be81, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
55 DEFINE_GUID(DXVA2_ModeWMV9_A,  0x1b81be90, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
56 DEFINE_GUID(DXVA2_ModeWMV9_B,  0x1b81be91, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
57 DEFINE_GUID(DXVA2_ModeWMV9_C,  0x1b81be94, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
58 DEFINE_GUID(DXVA2_ModeVC1_A,   0x1b81beA0, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
59 DEFINE_GUID(DXVA2_ModeVC1_B,   0x1b81beA1, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
60 DEFINE_GUID(DXVA2_ModeVC1_C,   0x1b81beA2, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
61 DEFINE_GUID(DXVA2_ModeVC1_D,   0x1b81beA3, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
62
63 const GUID IID_IDirectXVideoDecoderService = {0xfc51a551,0xd5e7,0x11d9, {0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02}};
64 const GUID IID_IDirectXVideoAccelerationService = {0xfc51a550,0xd5e7,0x11d9,{0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02}};
65
66 const D3DFORMAT VIDEO_RENDER_TARGET_FORMAT = D3DFMT_X8R8G8B8;
67
68 void format_error();
69
70 #define print_error(a) format_error(p_dec, __FILE__, __FUNCTION__, __LINE__,a)
71
72 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block );
73 LPDIRECTXVIDEODECODER pvid_dec;
74 LPDIRECT3DSURFACE9 psurfaces = NULL;
75 /*****************************************************************************
76  * decoder_sys_t : dxva decoder descriptor
77  *****************************************************************************/
78 struct decoder_sys_t
79 {
80         HINSTANCE g_hinst;                          /* This application's HINSTANCE */
81         HINSTANCE hd3d9_dll;
82         HWND g_hwndChild;                           /* Optional child window */
83         LPDIRECT3D9 g_pD3D;
84         D3DPRESENT_PARAMETERS d3dpp;
85         LPDIRECT3DDEVICE9 g_pd3dDevice;
86     IDirect3DSurface9* g_pD3DRT;
87 };
88
89 /*****************************************************************************
90  * Local prototypes
91  *****************************************************************************/
92 static int  OpenDecoder( vlc_object_t * );
93 static void CloseDecoder( vlc_object_t * );
94
95 /*****************************************************************************
96  * Module descriptor
97  *****************************************************************************/
98 vlc_module_begin ()
99     set_description( N_("DXVA 2 video decoder") )
100     set_capability( "decoder", 150 )
101     set_category( CAT_INPUT )
102     set_subcategory( SUBCAT_INPUT_VCODEC )
103     set_callbacks( OpenDecoder, CloseDecoder )
104     add_shortcut( "dxva" )
105 vlc_module_end ()
106
107 /*****************************************************************************
108  * OpenDecoder: probe the decoder and return score
109  *****************************************************************************/
110 static int OpenDecoder( vlc_object_t *p_this )
111 {
112     decoder_t *p_dec = (decoder_t*)p_this;
113     decoder_sys_t *p_sys;
114
115 switch( p_dec->fmt_in.i_codec )
116     {
117     case VLC_FOURCC('h','2','6','4'):
118     //case VLC_FOURCC('m','p','g','2'):
119     //case VLC_FOURCC('m','p','g','v'):
120     //case VLC_CODEC_WMVA:
121     //case VLC_CODEC_VC1:
122         break;
123     default:
124         //if( p_dec->fmt_in.i_original_fourcc )
125             return VLC_EGENERIC;
126         //break;
127     }
128
129     /* Allocate the memory needed to store the decoder's structure */
130     p_sys = malloc(sizeof(decoder_sys_t));
131     if( p_sys == NULL )
132         return VLC_ENOMEM;
133
134 /************** VLC codec stuff **********************/
135     char fourcc[5];
136     char original_fourcc[5];
137     fourcc[5] = 0;
138     original_fourcc[5] = 0;
139     vlc_fourcc_to_char(p_dec->fmt_in.i_codec, fourcc);
140     vlc_fourcc_to_char(p_dec->fmt_in.i_original_fourcc, original_fourcc);
141     msg_Dbg(p_dec, "Input format:\n\tcategory:%u\n\tcodec:%s\n\toriginal fourcc:%s\n\tbitrate:%u",
142             p_dec->fmt_in.i_cat,fourcc,original_fourcc, p_dec->fmt_in.i_bitrate);     
143     msg_Dbg(p_dec, "Input format:\n\twidth:%u\n\theight:%u\n\tratio:%d",
144             p_dec->fmt_in.video.i_width,p_dec->fmt_in.video.i_height,p_dec->fmt_in.video.i_aspect);
145 /************** D3D stuff **********************/
146
147     ZeroMemory( &p_sys->d3dpp, sizeof(D3DPRESENT_PARAMETERS) );
148
149     p_sys->d3dpp.Windowed = TRUE;
150     p_sys->d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
151     p_sys->d3dpp.BackBufferFormat = VIDEO_RENDER_TARGET_FORMAT;
152     p_sys->d3dpp.BackBufferWidth  = p_dec->fmt_in.video.i_width;
153     p_sys->d3dpp.BackBufferHeight = p_dec->fmt_in.video.i_height;
154     p_sys->d3dpp.BackBufferCount = 2;
155     p_sys->d3dpp.Flags = D3DPRESENTFLAG_VIDEO;
156
157     LPDIRECT3D9 (WINAPI *OurDirect3DCreate9)(UINT SDKVersion);
158
159     msg_Dbg( p_dec, "loading d3d dll" );
160     p_sys->hd3d9_dll = LoadLibrary(TEXT("D3D9.DLL"));
161     if( NULL == p_sys->hd3d9_dll )
162     {
163         msg_Warn( p_dec, "cannot load d3d9.dll, aborting" );
164         return VLC_EGENERIC;
165     }
166
167     msg_Dbg( p_dec, "loading d3d function" );
168     OurDirect3DCreate9 =
169       (void *)GetProcAddress( p_sys->hd3d9_dll,
170                               TEXT("Direct3DCreate9") );
171     if( OurDirect3DCreate9 == NULL )
172     {
173         msg_Err( p_dec, "Cannot locate reference to Direct3DCreate9 ABI in DLL" );
174         return VLC_EGENERIC;
175     }
176
177     msg_Dbg( p_dec, "creating d3d" );
178     if( NULL == ( p_sys->g_pD3D = OurDirect3DCreate9( D3D_SDK_VERSION ) ) )
179     {
180         msg_Err( p_dec, "Direct3DCreate9 failed" );
181         return VLC_EGENERIC;
182     }
183
184     msg_Dbg( p_dec, "creating d3d device" );
185
186     /* Direct3D needs a HWND to create a device, even without using ::Present
187     this HWND is used to alert Direct3D when there's a change of focus window.
188     For now, use GetShellWindow, as it looks harmless */
189     if( FAILED( IDirect3D9_CreateDevice( p_sys->g_pD3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetShellWindow(),
190                               D3DCREATE_SOFTWARE_VERTEXPROCESSING,
191                               &p_sys->d3dpp, &p_sys->g_pd3dDevice ) ) )
192     {
193         print_error("IDirect3D9_CreateDevice failed");
194         return VLC_EGENERIC;
195     }
196 /*****************END OF D3D****************************/
197
198 /*****************DXVA STUFF****************************/
199
200     HRESULT hr;
201     HINSTANCE hdxva2_dll;
202
203     HRESULT (WINAPI *MyDXVA2CreateVideoService)
204         (
205         IDirect3DDevice9 *pDD,
206         REFIID riid,
207         void **ppService
208         );
209     HRESULT (WINAPI *MyDXVA2CreateDirect3DDeviceManager9)
210         (
211             UINT *pResetToken,
212             IDirect3DDeviceManager9 **ppDXVAManager
213         );
214
215
216     hdxva2_dll = LoadLibrary(TEXT("DXVA2.DLL"));
217     if( NULL == hdxva2_dll )
218     {
219         msg_Err( p_dec, "cannot load DXVA2\n");
220         return 3;
221     }
222
223     MyDXVA2CreateVideoService =
224       (void *)GetProcAddress(hdxva2_dll,
225                               TEXT("DXVA2CreateVideoService") );
226
227     if( MyDXVA2CreateVideoService == NULL )
228     {
229         msg_Err( p_dec, "cannot load function\n");
230         return 4;
231     }
232     else
233         msg_Info( p_dec, "DXVA2CreateVideoService Success!");
234
235     MyDXVA2CreateDirect3DDeviceManager9 =
236       (void *)GetProcAddress(hdxva2_dll,
237                               TEXT("DXVA2CreateDirect3DDeviceManager9") );
238
239     if( MyDXVA2CreateDirect3DDeviceManager9 == NULL )
240     {
241         msg_Err( p_dec, "cannot load function\n");
242         return 4;
243     }
244     else
245         msg_Info( p_dec, "DXVA2CreateDirect3DDeviceManager9 Success!");
246
247     UINT reset_token;
248     LPDIRECT3DDEVICEMANAGER9 p_devman;
249     if( FAILED(  MyDXVA2CreateDirect3DDeviceManager9 ( &reset_token,&p_devman ) ) )
250     {
251         msg_Err( p_dec, " MyDXVA2CreateDirect3DDeviceManager9 failed");
252         return 5;
253     }
254     else
255         msg_Info( p_dec, "obtained IDirect3DDeviceManager9");   
256
257     HRESULT bb = IDirect3DDeviceManager9_ResetDevice( p_devman, p_sys->g_pd3dDevice, reset_token);
258     msg_Err( p_dec, "IDirect3DDeviceManager9_ResetDevice result: %08x", bb);
259
260     LPDIRECTXVIDEODECODERSERVICE g_pdxva_vs;
261     HANDLE hDevice;
262     
263     HRESULT hret1 = IDirect3DDeviceManager9_OpenDeviceHandle( p_devman, &hDevice);
264     
265     HRESULT hret2 = IDirect3DDeviceManager9_GetVideoService( p_devman, hDevice, &IID_IDirectXVideoDecoderService,
266         (void **) &g_pdxva_vs );
267
268     /*****************configuration dxva****************************/
269
270     UINT nbguid = 0;
271     GUID* pdecoderguids = NULL;
272
273     if( FAILED( IDirectXVideoDecoderService_GetDecoderDeviceGuids ( g_pdxva_vs, &nbguid, &pdecoderguids ) ) )
274     {
275         msg_Err( p_dec, "IDirectXVideoDecoderService_GetDecoderDeviceGuids failed");
276         return 6;
277     }
278
279     UINT iGuid;
280     // Look for the decoder GUIDs we want.
281     for (iGuid = 0; iGuid < nbguid; iGuid++)
282     {
283         //liste des GUID à afficher plus tard en Dbg (pour savoir ce qu'on peut décoder)
284         msg_Dbg( p_dec, "GUID = %08X-%04x-%04x-XXXX\n", pdecoderguids[iGuid].Data1,pdecoderguids[iGuid].Data2,pdecoderguids[iGuid].Data3);
285         
286     }
287     
288    /* on prend pour les tests pdecoderguids[6] = DXVA2_ModeH264_E => H.264 VLD, no FGT.
289    On cherche parmi les GUID qu'on a récupérés celui qui correspond au codec de la vidéo
290    cf http://msdn.microsoft.com/en-us/library/ms697067%28VS.85%29.aspx pour une correspondance entre les GUID et les codecs
291    if( p_dec->fmt_in.i_original_fourcc == VLC_FOURCC('h','2','6','4'))
292     {
293         for (iGuid = 0; iGuid < nbguid; iGuid++)
294         {
295    
296         }
297     }*/
298    
299     // FAILS probably because of the unusual d3d device
300     UINT nb_render = 0;
301     D3DFORMAT *prender_targets = NULL;
302
303     if( FAILED( IDirectXVideoDecoderService_GetDecoderRenderTargets ( g_pdxva_vs,
304                 &pdecoderguids[6], &nb_render, &prender_targets) ) )
305     {
306         msg_Err( p_dec, "IDirectXVideoDecoderService_GetDecoderRenderTargets failed");
307         return 7;
308     } 
309     
310     fourcc[5] = 0;
311     vlc_fourcc_to_char(prender_targets[0], fourcc);
312     msg_Info( p_dec, "we got %d decoder formats, choosing d3dformat n° %d test desc:%s", 
313         nb_render,prender_targets[0],fourcc);
314
315 /* Only one decoder format, for now */    
316 /* Ici, il faut faire la même chose que les decoder GUIDs: on regarde les différents formats, et on en choisit un qui correspond*/
317     D3DFORMAT fmt = prender_targets[0];
318     DXVA2_VideoDesc vid_desc;
319     DXVA2_ExtendedFormat ext_fmt;
320    // ext_fmt = 
321     vid_desc.SampleWidth = p_dec->fmt_in.video.i_width;//???
322     vid_desc.SampleHeight = p_dec->fmt_in.video.i_height;//???
323
324     vid_desc.Format = prender_targets[0];
325     vid_desc.InputSampleFreq.Numerator = 60;
326     vid_desc.InputSampleFreq.Denominator = 1;
327     vid_desc.OutputFrameFreq.Numerator = 60;
328     vid_desc.OutputFrameFreq.Denominator = 1;
329     vid_desc.OutputFrameFreq = vid_desc.InputSampleFreq;
330     vid_desc.UABProtectionLevel = false;
331     vid_desc.Reserved = 0;
332
333     UINT nb_dec_conf=0;
334     DXVA2_ConfigPictureDecode* pdec_conf = NULL;
335     if( FAILED( IDirectXVideoDecoderService_GetDecoderConfigurations ( g_pdxva_vs,
336                 &pdecoderguids[0], &vid_desc, NULL, &nb_dec_conf, &pdec_conf )))
337     {
338         msg_Err( p_dec, "IDirectXVideoDecoderService_GetDecoderConfigurations failed\n");
339         return 7;
340     }           
341     
342     msg_Info( p_dec, "we got %d decoder configurations", nb_dec_conf);
343  
344 /* Création de la surface de rendering*/
345     if( FAILED( IDirectXVideoDecoderService_CreateSurface ( g_pdxva_vs,  p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height,
346         1, prender_targets[0], D3DPOOL_DEFAULT, 0, 0/*DXVA2_VideoDecoderRenderTarget*/, &psurfaces, NULL )))
347     {
348         msg_Err( p_dec, "IDirectXVideoAccelerationService_CreateSurface failed\n");
349         return 7;
350     } 
351     
352     msg_Info( p_dec, "we got d3d surfaces\n");
353     
354
355     HRESULT aa;
356     aa = IDirectXVideoDecoderService_CreateVideoDecoder ( g_pdxva_vs,
357                 &pdecoderguids[6], &vid_desc, &pdec_conf[1], &psurfaces, 2,
358                 &pvid_dec);
359    // msg_Err( p_dec,"IDirectXVideoDecoderService_CreateVideoDecoder1: %08x\n", aa);
360
361     HRESULT cc = IDirect3DDeviceManager9_ResetDevice( p_devman, p_sys->g_pd3dDevice, reset_token);
362     //msg_Err( p_dec, "IDirect3DDeviceManager9_ResetDevice result: %08x\n", cc);
363     
364     aa = IDirectXVideoDecoderService_CreateVideoDecoder ( g_pdxva_vs,
365                 &pdecoderguids[6], &vid_desc, &pdec_conf[1], &psurfaces, 2,
366                 &pvid_dec);
367     //msg_Err( p_dec, "IDirectXVideoDecoderService_CreateVideoDecoder2: %08x\n", aa);
368
369     /*if( FAILED( IDirectXVideoDecoderService_CreateVideoDecoder ( g_pdxva_vs,
370                 &pdecoderguids[6], &vid_desc, &pdec_conf[0], &psurfaces, 6,
371                 &pvid_dec)))
372     {
373         print_error("IDirectXVideoDecoderService_CreateVideoDecoder failed");
374         return 9;  
375     }*/
376     if( aa == 0)
377     {
378         p_dec->pf_decode_video = DecodeBlock;
379         p_dec->fmt_out.i_cat = VIDEO_ES;
380         p_dec->fmt_out.i_codec = VLC_CODEC_I420; //???
381         p_dec->fmt_out.video.i_width = p_dec->fmt_in.video.i_width;//pas sur
382         p_dec->fmt_out.video.i_height = p_dec->fmt_in.video.i_height;//???
383         p_dec->fmt_out.video.i_visible_width = p_dec->fmt_in.video.i_width;//???
384         p_dec->fmt_out.video.i_visible_height = p_dec->fmt_in.video.i_height;//???
385         p_dec->fmt_out.video.i_aspect = 1;//p_dec->fmt_in.video.i_aspect;//?????
386         p_dec->fmt_out.video.i_sar_num = 1;
387         p_dec->fmt_out.video.i_sar_den = 1;
388         return VLC_SUCCESS;
389     }
390     else
391     {
392 /**************END OF DXVA******************************/
393
394     //CoTaskMemFree(pdecoderguids);
395     return VLC_EGENERIC;
396     }
397 }
398
399
400
401 /*****************************************************************************
402  * DecodeBlock: dxva decoder
403  *****************************************************************************/
404 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
405 {
406     decoder_sys_t   *p_sys = p_dec->p_sys;
407
408     picture_t       *p_pic;
409
410     block_t *p_block;
411
412     if( !pp_block || !*pp_block ) return NULL;
413
414     p_block = *pp_block;
415     uint8_t * buf = p_block->p_buffer;
416
417 /*****************************************************************************/
418 /* Etapes du décodage: http://msdn.microsoft.com/en-us/library/aa965245%28VS.85%29.aspx#Decoding */
419
420     if( 0 != IDirectXVideoDecoder_BeginFrame(pvid_dec,psurfaces,NULL ) )
421     {
422         print_error("IDirectXVideoDecoder_BeginFrame failed");
423     }
424
425     UINT BufferType = DXVA2_PictureParametersBufferType;
426     void *pBuffer;
427     UINT BufferSize;
428     if( 0 != IDirectXVideoDecoder_GetBuffer(pvid_dec, BufferType, &pBuffer, &BufferSize))
429     {
430         print_error("IDirectXVideoDecoder_GetBuffer failed");
431     }
432     else
433     {
434     //    msg_Dbg( p_dec, "IDirectXVideoDecoder_GetBuffer -> buffer size=%u\n", BufferSize);
435    
436 /*************** FILLING THE BUFFER *****************************/   
437         /*here fill pbuffer with video*/
438         memcpy( pBuffer, p_block->p_buffer, BufferSize );
439
440 /*************** BUFFER FILLED ***********************************/
441         if( 0 != IDirectXVideoDecoder_ReleaseBuffer(pvid_dec, BufferType) ) 
442         {
443             print_error("IDirectXVideoDecoder_ReleaseBuffer failed");
444         }
445 /*************** DECODE VIDEO ***********************/
446         
447         DXVA2_DecodeExecuteParams params;
448         params.NumCompBuffers = 1;
449         
450         DXVA2_DecodeBufferDesc bufferdesc[2];
451         bufferdesc[0].CompressedBufferType = BufferType;
452         bufferdesc[0].BufferIndex = 0; // Reserved
453         bufferdesc[0].DataOffset = 0;
454         bufferdesc[0].DataSize = BufferSize;
455         bufferdesc[0].FirstMBaddress = 0; //??????
456         bufferdesc[0].NumMBsInBuffer = 1; //??????
457         bufferdesc[0].Width = 0; // Reserved
458         bufferdesc[0].Height = 0; // Reserved
459         bufferdesc[0].Stride = 0; // Reserved
460         bufferdesc[0].ReservedBits = 0; // Reserved
461         bufferdesc[0].pvPVPState = NULL; // No encrypted data
462
463         params.pCompressedBuffers = bufferdesc;
464         params.pExtensionData = NULL; // no private data to send to the driver
465         HRESULT hr2 = IDirectXVideoDecoder_Execute(pvid_dec, &params);
466         if(hr2 != (HRESULT)0x00000000L)
467         {
468             //print_error("");
469         //    msg_Err( p_dec, "IDirectXVideoDecoder_Execute failed with error %08x\n", hr2);
470         }
471         else
472         {
473         //    msg_Err( p_dec, "\n\nIDirectXVideoDecoder_Execute SUCCESS\n\n");
474         }
475         
476         bufferdesc[1].CompressedBufferType = DXVA2_BitStreamDateBufferType;
477         bufferdesc[1].BufferIndex = 0; // Reserved
478         bufferdesc[1].DataOffset = 0;
479         bufferdesc[1].DataSize = BufferSize;
480         bufferdesc[1].FirstMBaddress = 0; //??????
481         bufferdesc[1].NumMBsInBuffer = 1; //??????
482         bufferdesc[1].Width = 0; // Reserved
483         bufferdesc[1].Height = 0; // Reserved
484         bufferdesc[1].Stride = 0; // Reserved
485         bufferdesc[1].ReservedBits = 0; // Reserved
486         bufferdesc[1].pvPVPState = NULL; // No encrypted data
487         
488         DXVA2_DecodeExecuteParams params2;
489         params2.NumCompBuffers = 1;
490         params2.pCompressedBuffers = bufferdesc + 1;
491         params2.pExtensionData = NULL; // no private data to send to the driver
492         void *pBuffer2;
493         UINT BufferSize2;
494         
495         if( 0 != IDirectXVideoDecoder_GetBuffer(pvid_dec, DXVA2_BitStreamDateBufferType, &pBuffer2, &BufferSize2))
496         {
497         //    print_error("IDirectXVideoDecoder_GetBuffer failed");
498         }
499         else
500         {
501         //    msg_Dbg( p_dec, "IDirectXVideoDecoder_GetBuffer bitstream -> buffer size=%u\n", BufferSize2);
502             hr2 = IDirectXVideoDecoder_Execute(pvid_dec, &params2);
503             if(hr2 != (HRESULT)0x00000000L)
504             {
505                 //print_error("");
506          //       msg_Err( p_dec, "IDirectXVideoDecoder_Execute bitstream failed with error %08x\n", hr2);
507             }
508             else
509             {
510         //        msg_Err( p_dec, "\n\nIDirectXVideoDecoder_Execute bitstream SUCCESS\n\n");
511             }            
512         }
513 /*************** END OF DECODING ***********************/
514     }
515
516     
517     HANDLE endframeout;
518     if( 0 != IDirectXVideoDecoder_EndFrame(pvid_dec,&endframeout) )
519     {
520         print_error("IDirectXVideoDecoder_EndFrame");
521
522     }
523     
524     //msg_Dbg( p_dec, "New picture");
525     /* Get a new picture */
526     p_pic = decoder_NewPicture( p_dec );
527     if( !p_pic ) return NULL;
528     //msg_Dbg( p_dec, "Got a new picture");
529
530      /*access the surface's memory*/
531     D3DLOCKED_RECT d3dlock;
532     if( FAILED( IDirect3DSurface9_LockRect( psurfaces, &d3dlock, NULL, 0/*??*/)) )
533     {
534         print_error("");
535     }
536     //Copy in picture_t, not block
537     //memcpy( p_block->p_buffer, d3dlock.pBits, BufferSize );
538     if( FAILED(IDirect3DSurface9_UnlockRect( psurfaces )))
539     {
540         print_error("");
541     }
542     
543     /* Error handling, dates des samples, bloc_Release? */
544     block_Release( p_block );
545     return NULL;
546 }
547
548 /*****************************************************************************
549  * CloseDecoder: dxva decoder destruction
550  *****************************************************************************/
551 static void CloseDecoder( vlc_object_t *p_this )
552 {
553     decoder_t *p_dec = (decoder_t *)p_this;
554     decoder_sys_t *p_sys = p_dec->p_sys;
555
556     if( p_sys->g_pd3dDevice != NULL)
557         IDirect3DDevice9_Release( p_sys->g_pd3dDevice );
558     if( p_sys->g_pD3D != NULL)
559         IDirect3D9_Release( p_sys->g_pD3D );
560
561     free( p_sys );
562 }
563
564 void format_error(decoder_t *p_dec, char * file, char * function, int line, char * msg)
565 {
566                 LPVOID lpMsgBuf;
567         DWORD err = GetLastError();
568                 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
569                                                 NULL, /* lpSource */
570                                                 err, /*dwMessageId */
571                                                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* dwLanguageId */
572                                                 (LPTSTR) &lpMsgBuf,
573                                                 0, NULL );
574                 msg_Err( p_dec, "Error in %s:%d - %s : %08x-%s | %s", file, line, function, err, lpMsgBuf, msg);
575                 LocalFree(lpMsgBuf);
576         fflush(stdout);
577                 return;
578 }