Browse code

Merge commit 'b23613268c6b56a8f9de7859562d82b4b88353d9'

* commit 'b23613268c6b56a8f9de7859562d82b4b88353d9':
avconv_dxva2: use the hwcontext API

Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>

Hendrik Leppkes authored on 2016/06/23 06:36:37
Showing 1 changed files
... ...
@@ -40,6 +40,9 @@
40 40
 #include "libavutil/imgutils.h"
41 41
 #include "libavutil/pixfmt.h"
42 42
 
43
+#include "libavutil/hwcontext.h"
44
+#include "libavutil/hwcontext_dxva2.h"
45
+
43 46
 /* define all the GUIDs used directly here,
44 47
    to avoid problems with inconsistent dxva2api.h versions in mingw-w64 and different MSVC version */
45 48
 #include <initguid.h>
... ...
@@ -93,12 +96,7 @@ static const dxva2_mode dxva2_modes[] = {
93 93
     { NULL,                      0 },
94 94
 };
95 95
 
96
-typedef struct surface_info {
97
-    int used;
98
-    uint64_t age;
99
-} surface_info;
100
-
101
-typedef struct DXVA2Context {
96
+typedef struct DXVA2DevicePriv {
102 97
     HMODULE d3dlib;
103 98
     HMODULE dxva2lib;
104 99
 
... ...
@@ -106,49 +104,45 @@ typedef struct DXVA2Context {
106 106
 
107 107
     IDirect3D9                  *d3d9;
108 108
     IDirect3DDevice9            *d3d9device;
109
-    IDirect3DDeviceManager9     *d3d9devmgr;
110
-    IDirectXVideoDecoderService *decoder_service;
109
+} DXVA2DevicePriv;
110
+
111
+typedef struct DXVA2Context {
111 112
     IDirectXVideoDecoder        *decoder;
112 113
 
113 114
     GUID                        decoder_guid;
114 115
     DXVA2_ConfigPictureDecode   decoder_config;
115
-
116
-    LPDIRECT3DSURFACE9          *surfaces;
117
-    surface_info                *surface_infos;
118
-    uint32_t                    num_surfaces;
119
-    uint64_t                    surface_age;
120
-    D3DFORMAT                   surface_format;
116
+    IDirectXVideoDecoderService *decoder_service;
121 117
 
122 118
     AVFrame                     *tmp_frame;
123
-} DXVA2Context;
124 119
 
125
-typedef struct DXVA2SurfaceWrapper {
126
-    DXVA2Context         *ctx;
127
-    LPDIRECT3DSURFACE9   surface;
128
-    IDirectXVideoDecoder *decoder;
129
-} DXVA2SurfaceWrapper;
120
+    AVBufferRef                 *hw_device_ctx;
121
+    AVBufferRef                 *hw_frames_ctx;
122
+} DXVA2Context;
130 123
 
131
-static void dxva2_destroy_decoder(AVCodecContext *s)
124
+static void dxva2_device_uninit(AVHWDeviceContext *ctx)
132 125
 {
133
-    InputStream  *ist = s->opaque;
134
-    DXVA2Context *ctx = ist->hwaccel_ctx;
135
-    int i;
126
+    AVDXVA2DeviceContext *hwctx = ctx->hwctx;
127
+    DXVA2DevicePriv       *priv = ctx->user_opaque;
136 128
 
137
-    if (ctx->surfaces) {
138
-        for (i = 0; i < ctx->num_surfaces; i++) {
139
-            if (ctx->surfaces[i])
140
-                IDirect3DSurface9_Release(ctx->surfaces[i]);
141
-        }
142
-    }
143
-    av_freep(&ctx->surfaces);
144
-    av_freep(&ctx->surface_infos);
145
-    ctx->num_surfaces = 0;
146
-    ctx->surface_age  = 0;
147
-
148
-    if (ctx->decoder) {
149
-        IDirectXVideoDecoder_Release(ctx->decoder);
150
-        ctx->decoder = NULL;
151
-    }
129
+    if (hwctx->devmgr && priv->deviceHandle != INVALID_HANDLE_VALUE)
130
+        IDirect3DDeviceManager9_CloseDeviceHandle(hwctx->devmgr, priv->deviceHandle);
131
+
132
+    if (hwctx->devmgr)
133
+        IDirect3DDeviceManager9_Release(hwctx->devmgr);
134
+
135
+    if (priv->d3d9device)
136
+        IDirect3DDevice9_Release(priv->d3d9device);
137
+
138
+    if (priv->d3d9)
139
+        IDirect3D9_Release(priv->d3d9);
140
+
141
+    if (priv->d3dlib)
142
+        FreeLibrary(priv->d3dlib);
143
+
144
+    if (priv->dxva2lib)
145
+        FreeLibrary(priv->dxva2lib);
146
+
147
+    av_freep(&ctx->user_opaque);
152 148
 }
153 149
 
154 150
 static void dxva2_uninit(AVCodecContext *s)
... ...
@@ -160,29 +154,11 @@ static void dxva2_uninit(AVCodecContext *s)
160 160
     ist->hwaccel_get_buffer    = NULL;
161 161
     ist->hwaccel_retrieve_data = NULL;
162 162
 
163
-    if (ctx->decoder)
164
-        dxva2_destroy_decoder(s);
165
-
166 163
     if (ctx->decoder_service)
167 164
         IDirectXVideoDecoderService_Release(ctx->decoder_service);
168 165
 
169
-    if (ctx->d3d9devmgr && ctx->deviceHandle != INVALID_HANDLE_VALUE)
170
-        IDirect3DDeviceManager9_CloseDeviceHandle(ctx->d3d9devmgr, ctx->deviceHandle);
171
-
172
-    if (ctx->d3d9devmgr)
173
-        IDirect3DDeviceManager9_Release(ctx->d3d9devmgr);
174
-
175
-    if (ctx->d3d9device)
176
-        IDirect3DDevice9_Release(ctx->d3d9device);
177
-
178
-    if (ctx->d3d9)
179
-        IDirect3D9_Release(ctx->d3d9);
180
-
181
-    if (ctx->d3dlib)
182
-        FreeLibrary(ctx->d3dlib);
183
-
184
-    if (ctx->dxva2lib)
185
-        FreeLibrary(ctx->dxva2lib);
166
+    av_buffer_unref(&ctx->hw_frames_ctx);
167
+    av_buffer_unref(&ctx->hw_device_ctx);
186 168
 
187 169
     av_frame_free(&ctx->tmp_frame);
188 170
 
... ...
@@ -190,130 +166,34 @@ static void dxva2_uninit(AVCodecContext *s)
190 190
     av_freep(&s->hwaccel_context);
191 191
 }
192 192
 
193
-static void dxva2_release_buffer(void *opaque, uint8_t *data)
194
-{
195
-    DXVA2SurfaceWrapper *w   = opaque;
196
-    DXVA2Context        *ctx = w->ctx;
197
-    int i;
198
-
199
-    for (i = 0; i < ctx->num_surfaces; i++) {
200
-        if (ctx->surfaces[i] == w->surface) {
201
-            ctx->surface_infos[i].used = 0;
202
-            break;
203
-        }
204
-    }
205
-    IDirect3DSurface9_Release(w->surface);
206
-    IDirectXVideoDecoder_Release(w->decoder);
207
-    av_free(w);
208
-}
209
-
210 193
 static int dxva2_get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
211 194
 {
212 195
     InputStream  *ist = s->opaque;
213 196
     DXVA2Context *ctx = ist->hwaccel_ctx;
214
-    int i, old_unused = -1;
215
-    LPDIRECT3DSURFACE9 surface;
216
-    DXVA2SurfaceWrapper *w = NULL;
217
-
218
-    av_assert0(frame->format == AV_PIX_FMT_DXVA2_VLD);
219
-
220
-    for (i = 0; i < ctx->num_surfaces; i++) {
221
-        surface_info *info = &ctx->surface_infos[i];
222
-        if (!info->used && (old_unused == -1 || info->age < ctx->surface_infos[old_unused].age))
223
-            old_unused = i;
224
-    }
225
-    if (old_unused == -1) {
226
-        av_log(NULL, AV_LOG_ERROR, "No free DXVA2 surface!\n");
227
-        return AVERROR(ENOMEM);
228
-    }
229
-    i = old_unused;
230 197
 
231
-    surface = ctx->surfaces[i];
232
-
233
-    w = av_mallocz(sizeof(*w));
234
-    if (!w)
235
-        return AVERROR(ENOMEM);
236
-
237
-    frame->buf[0] = av_buffer_create((uint8_t*)surface, 0,
238
-                                     dxva2_release_buffer, w,
239
-                                     AV_BUFFER_FLAG_READONLY);
240
-    if (!frame->buf[0]) {
241
-        av_free(w);
242
-        return AVERROR(ENOMEM);
243
-    }
244
-
245
-    w->ctx     = ctx;
246
-    w->surface = surface;
247
-    IDirect3DSurface9_AddRef(w->surface);
248
-    w->decoder = ctx->decoder;
249
-    IDirectXVideoDecoder_AddRef(w->decoder);
250
-
251
-    ctx->surface_infos[i].used = 1;
252
-    ctx->surface_infos[i].age  = ctx->surface_age++;
253
-
254
-    frame->data[3] = (uint8_t *)surface;
255
-
256
-    return 0;
198
+    return av_hwframe_get_buffer(ctx->hw_frames_ctx, frame, 0);
257 199
 }
258 200
 
259 201
 static int dxva2_retrieve_data(AVCodecContext *s, AVFrame *frame)
260 202
 {
261
-    LPDIRECT3DSURFACE9 surface =  (LPDIRECT3DSURFACE9)frame->data[3];
262 203
     InputStream        *ist = s->opaque;
263 204
     DXVA2Context       *ctx = ist->hwaccel_ctx;
264
-    D3DSURFACE_DESC    surfaceDesc;
265
-    D3DLOCKED_RECT     LockedRect;
266
-    HRESULT            hr;
267
-    int                ret, nbytes;
268
-
269
-    IDirect3DSurface9_GetDesc(surface, &surfaceDesc);
270
-
271
-    ctx->tmp_frame->width  = frame->width;
272
-    ctx->tmp_frame->height = frame->height;
273
-    switch (ctx->surface_format){
274
-    case MKTAG('N','V','1','2'):
275
-        ctx->tmp_frame->format = AV_PIX_FMT_NV12;
276
-        nbytes = 1;
277
-        break;
278
-    case MKTAG('P','0','1','0'):
279
-        ctx->tmp_frame->format = AV_PIX_FMT_P010;
280
-        nbytes = 2;
281
-        break;
282
-    default:
283
-        av_assert0(0);
284
-    }
205
+    int                ret;
285 206
 
286
-    ret = av_frame_get_buffer(ctx->tmp_frame, 32);
207
+    ret = av_hwframe_transfer_data(ctx->tmp_frame, frame, 0);
287 208
     if (ret < 0)
288 209
         return ret;
289 210
 
290
-    hr = IDirect3DSurface9_LockRect(surface, &LockedRect, NULL, D3DLOCK_READONLY);
291
-    if (FAILED(hr)) {
292
-        av_log(NULL, AV_LOG_ERROR, "Unable to lock DXVA2 surface\n");
293
-        return AVERROR_UNKNOWN;
294
-    }
295
-
296
-    av_image_copy_plane(ctx->tmp_frame->data[0], ctx->tmp_frame->linesize[0],
297
-                        (uint8_t*)LockedRect.pBits,
298
-                        LockedRect.Pitch, frame->width * nbytes, frame->height);
299
-
300
-    av_image_copy_plane(ctx->tmp_frame->data[1], ctx->tmp_frame->linesize[1],
301
-                        (uint8_t*)LockedRect.pBits + LockedRect.Pitch * surfaceDesc.Height,
302
-                        LockedRect.Pitch, frame->width * nbytes, frame->height / 2);
303
-
304
-    IDirect3DSurface9_UnlockRect(surface);
305
-
306 211
     ret = av_frame_copy_props(ctx->tmp_frame, frame);
307
-    if (ret < 0)
308
-        goto fail;
212
+    if (ret < 0) {
213
+        av_frame_unref(ctx->tmp_frame);
214
+        return ret;
215
+    }
309 216
 
310 217
     av_frame_unref(frame);
311 218
     av_frame_move_ref(frame, ctx->tmp_frame);
312 219
 
313 220
     return 0;
314
-fail:
315
-    av_frame_unref(ctx->tmp_frame);
316
-    return ret;
317 221
 }
318 222
 
319 223
 static int dxva2_alloc(AVCodecContext *s)
... ...
@@ -329,41 +209,60 @@ static int dxva2_alloc(AVCodecContext *s)
329 329
     unsigned resetToken = 0;
330 330
     UINT adapter = D3DADAPTER_DEFAULT;
331 331
 
332
+    AVHWDeviceContext    *device_ctx;
333
+    AVDXVA2DeviceContext *device_hwctx;
334
+    DXVA2DevicePriv      *device_priv;
335
+    int ret;
336
+
332 337
     ctx = av_mallocz(sizeof(*ctx));
333 338
     if (!ctx)
334 339
         return AVERROR(ENOMEM);
335 340
 
336
-    ctx->deviceHandle = INVALID_HANDLE_VALUE;
337
-
338 341
     ist->hwaccel_ctx           = ctx;
339 342
     ist->hwaccel_uninit        = dxva2_uninit;
340 343
     ist->hwaccel_get_buffer    = dxva2_get_buffer;
341 344
     ist->hwaccel_retrieve_data = dxva2_retrieve_data;
342 345
 
343
-    ctx->d3dlib = LoadLibrary("d3d9.dll");
344
-    if (!ctx->d3dlib) {
346
+    ctx->hw_device_ctx = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_DXVA2);
347
+    if (!ctx->hw_device_ctx)
348
+        goto fail;
349
+
350
+    device_ctx   = (AVHWDeviceContext*)ctx->hw_device_ctx->data;
351
+    device_hwctx = device_ctx->hwctx;
352
+
353
+    device_priv = av_mallocz(sizeof(*device_priv));
354
+    if (!device_priv)
355
+        goto fail;
356
+
357
+    device_ctx->user_opaque = device_priv;
358
+    device_ctx->free        = dxva2_device_uninit;
359
+
360
+    device_priv->deviceHandle = INVALID_HANDLE_VALUE;
361
+
362
+    device_priv->d3dlib = LoadLibrary("d3d9.dll");
363
+    if (!device_priv->d3dlib) {
345 364
         av_log(NULL, loglevel, "Failed to load D3D9 library\n");
346 365
         goto fail;
347 366
     }
348
-    ctx->dxva2lib = LoadLibrary("dxva2.dll");
349
-    if (!ctx->dxva2lib) {
367
+    device_priv->dxva2lib = LoadLibrary("dxva2.dll");
368
+    if (!device_priv->dxva2lib) {
350 369
         av_log(NULL, loglevel, "Failed to load DXVA2 library\n");
351 370
         goto fail;
352 371
     }
353 372
 
354
-    createD3D = (pDirect3DCreate9 *)GetProcAddress(ctx->d3dlib, "Direct3DCreate9");
373
+    createD3D = (pDirect3DCreate9 *)GetProcAddress(device_priv->d3dlib, "Direct3DCreate9");
355 374
     if (!createD3D) {
356 375
         av_log(NULL, loglevel, "Failed to locate Direct3DCreate9\n");
357 376
         goto fail;
358 377
     }
359
-    createDeviceManager = (pCreateDeviceManager9 *)GetProcAddress(ctx->dxva2lib, "DXVA2CreateDirect3DDeviceManager9");
378
+    createDeviceManager = (pCreateDeviceManager9 *)GetProcAddress(device_priv->dxva2lib, "DXVA2CreateDirect3DDeviceManager9");
360 379
     if (!createDeviceManager) {
361 380
         av_log(NULL, loglevel, "Failed to locate DXVA2CreateDirect3DDeviceManager9\n");
362 381
         goto fail;
363 382
     }
364 383
 
365
-    ctx->d3d9 = createD3D(D3D_SDK_VERSION);
366
-    if (!ctx->d3d9) {
384
+    device_priv->d3d9 = createD3D(D3D_SDK_VERSION);
385
+    if (!device_priv->d3d9) {
367 386
         av_log(NULL, loglevel, "Failed to create IDirect3D object\n");
368 387
         goto fail;
369 388
     }
... ...
@@ -373,7 +272,7 @@ static int dxva2_alloc(AVCodecContext *s)
373 373
         av_log(NULL, AV_LOG_INFO, "Using HWAccel device %d\n", adapter);
374 374
     }
375 375
 
376
-    IDirect3D9_GetAdapterDisplayMode(ctx->d3d9, adapter, &d3ddm);
376
+    IDirect3D9_GetAdapterDisplayMode(device_priv->d3d9, adapter, &d3ddm);
377 377
     d3dpp.Windowed         = TRUE;
378 378
     d3dpp.BackBufferWidth  = 640;
379 379
     d3dpp.BackBufferHeight = 480;
... ...
@@ -382,38 +281,44 @@ static int dxva2_alloc(AVCodecContext *s)
382 382
     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
383 383
     d3dpp.Flags            = D3DPRESENTFLAG_VIDEO;
384 384
 
385
-    hr = IDirect3D9_CreateDevice(ctx->d3d9, adapter, D3DDEVTYPE_HAL, GetDesktopWindow(),
385
+    hr = IDirect3D9_CreateDevice(device_priv->d3d9, adapter, D3DDEVTYPE_HAL, GetDesktopWindow(),
386 386
                                  D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
387
-                                 &d3dpp, &ctx->d3d9device);
387
+                                 &d3dpp, &device_priv->d3d9device);
388 388
     if (FAILED(hr)) {
389 389
         av_log(NULL, loglevel, "Failed to create Direct3D device\n");
390 390
         goto fail;
391 391
     }
392 392
 
393
-    hr = createDeviceManager(&resetToken, &ctx->d3d9devmgr);
393
+    hr = createDeviceManager(&resetToken, &device_hwctx->devmgr);
394 394
     if (FAILED(hr)) {
395 395
         av_log(NULL, loglevel, "Failed to create Direct3D device manager\n");
396 396
         goto fail;
397 397
     }
398 398
 
399
-    hr = IDirect3DDeviceManager9_ResetDevice(ctx->d3d9devmgr, ctx->d3d9device, resetToken);
399
+    hr = IDirect3DDeviceManager9_ResetDevice(device_hwctx->devmgr, device_priv->d3d9device, resetToken);
400 400
     if (FAILED(hr)) {
401 401
         av_log(NULL, loglevel, "Failed to bind Direct3D device to device manager\n");
402 402
         goto fail;
403 403
     }
404 404
 
405
-    hr = IDirect3DDeviceManager9_OpenDeviceHandle(ctx->d3d9devmgr, &ctx->deviceHandle);
405
+    hr = IDirect3DDeviceManager9_OpenDeviceHandle(device_hwctx->devmgr, &device_priv->deviceHandle);
406 406
     if (FAILED(hr)) {
407 407
         av_log(NULL, loglevel, "Failed to open device handle\n");
408 408
         goto fail;
409 409
     }
410 410
 
411
-    hr = IDirect3DDeviceManager9_GetVideoService(ctx->d3d9devmgr, ctx->deviceHandle, &IID_IDirectXVideoDecoderService, (void **)&ctx->decoder_service);
411
+    hr = IDirect3DDeviceManager9_GetVideoService(device_hwctx->devmgr, device_priv->deviceHandle, &IID_IDirectXVideoDecoderService, (void **)&ctx->decoder_service);
412 412
     if (FAILED(hr)) {
413 413
         av_log(NULL, loglevel, "Failed to create IDirectXVideoDecoderService\n");
414 414
         goto fail;
415 415
     }
416 416
 
417
+    ret = av_hwdevice_ctx_init(ctx->hw_device_ctx);
418
+    if (ret < 0) {
419
+        av_log(NULL, loglevel, "Failed to initialize the HW device context\n");
420
+        goto fail;
421
+    }
422
+
417 423
     ctx->tmp_frame = av_frame_alloc();
418 424
     if (!ctx->tmp_frame)
419 425
         goto fail;
... ...
@@ -489,9 +394,12 @@ static int dxva2_create_decoder(AVCodecContext *s)
489 489
     DXVA2_VideoDesc desc = { 0 };
490 490
     DXVA2_ConfigPictureDecode config;
491 491
     HRESULT hr;
492
-    int surface_alignment;
492
+    int surface_alignment, num_surfaces;
493 493
     int ret;
494 494
 
495
+    AVDXVA2FramesContext *frames_hwctx;
496
+    AVHWFramesContext *frames_ctx;
497
+
495 498
     hr = IDirectXVideoDecoderService_GetDecoderDeviceGuids(ctx->decoder_service, &guid_count, &guid_list);
496 499
     if (FAILED(hr)) {
497 500
         av_log(NULL, loglevel, "Failed to retrieve decoder device GUIDs\n");
... ...
@@ -557,44 +465,43 @@ static int dxva2_create_decoder(AVCodecContext *s)
557 557
         surface_alignment = 16;
558 558
 
559 559
     /* 4 base work surfaces */
560
-    ctx->num_surfaces = 4;
560
+    num_surfaces = 4;
561 561
 
562 562
     /* add surfaces based on number of possible refs */
563 563
     if (s->codec_id == AV_CODEC_ID_H264 || s->codec_id == AV_CODEC_ID_HEVC)
564
-        ctx->num_surfaces += 16;
564
+        num_surfaces += 16;
565 565
     else if (s->codec_id == AV_CODEC_ID_VP9)
566
-        ctx->num_surfaces += 8;
566
+        num_surfaces += 8;
567 567
     else
568
-        ctx->num_surfaces += 2;
568
+        num_surfaces += 2;
569 569
 
570 570
     /* add extra surfaces for frame threading */
571 571
     if (s->active_thread_type & FF_THREAD_FRAME)
572
-        ctx->num_surfaces += s->thread_count;
573
-
574
-    ctx->surfaces      = av_mallocz(ctx->num_surfaces * sizeof(*ctx->surfaces));
575
-    ctx->surface_infos = av_mallocz(ctx->num_surfaces * sizeof(*ctx->surface_infos));
576
-    ctx->surface_format = target_format;
572
+        num_surfaces += s->thread_count;
577 573
 
578
-    if (!ctx->surfaces || !ctx->surface_infos) {
579
-        av_log(NULL, loglevel, "Unable to allocate surface arrays\n");
574
+    ctx->hw_frames_ctx = av_hwframe_ctx_alloc(ctx->hw_device_ctx);
575
+    if (!ctx->hw_frames_ctx)
580 576
         goto fail;
581
-    }
577
+    frames_ctx   = (AVHWFramesContext*)ctx->hw_frames_ctx->data;
578
+    frames_hwctx = frames_ctx->hwctx;
582 579
 
583
-    hr = IDirectXVideoDecoderService_CreateSurface(ctx->decoder_service,
584
-                                                   FFALIGN(s->coded_width, surface_alignment),
585
-                                                   FFALIGN(s->coded_height, surface_alignment),
586
-                                                   ctx->num_surfaces - 1,
587
-                                                   target_format, D3DPOOL_DEFAULT, 0,
588
-                                                   DXVA2_VideoDecoderRenderTarget,
589
-                                                   ctx->surfaces, NULL);
590
-    if (FAILED(hr)) {
591
-        av_log(NULL, loglevel, "Failed to create %d video surfaces\n", ctx->num_surfaces);
580
+    frames_ctx->format            = AV_PIX_FMT_DXVA2_VLD;
581
+    frames_ctx->sw_format         = (target_format == MKTAG('P','0','1','0') ? AV_PIX_FMT_P010 : AV_PIX_FMT_NV12);
582
+    frames_ctx->width             = FFALIGN(s->coded_width, surface_alignment);
583
+    frames_ctx->height            = FFALIGN(s->coded_height, surface_alignment);
584
+    frames_ctx->initial_pool_size = num_surfaces;
585
+
586
+    frames_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget;
587
+
588
+    ret = av_hwframe_ctx_init(ctx->hw_frames_ctx);
589
+    if (ret < 0) {
590
+        av_log(NULL, loglevel, "Failed to initialize the HW frames context\n");
592 591
         goto fail;
593 592
     }
594 593
 
595 594
     hr = IDirectXVideoDecoderService_CreateVideoDecoder(ctx->decoder_service, &device_guid,
596
-                                                        &desc, &config, ctx->surfaces,
597
-                                                        ctx->num_surfaces, &ctx->decoder);
595
+                                                        &desc, &config, frames_hwctx->surfaces,
596
+                                                        frames_hwctx->nb_surfaces, &frames_hwctx->decoder_to_release);
598 597
     if (FAILED(hr)) {
599 598
         av_log(NULL, loglevel, "Failed to create DXVA2 video decoder\n");
600 599
         goto fail;
... ...
@@ -604,16 +511,16 @@ static int dxva2_create_decoder(AVCodecContext *s)
604 604
     ctx->decoder_config = config;
605 605
 
606 606
     dxva_ctx->cfg           = &ctx->decoder_config;
607
-    dxva_ctx->decoder       = ctx->decoder;
608
-    dxva_ctx->surface       = ctx->surfaces;
609
-    dxva_ctx->surface_count = ctx->num_surfaces;
607
+    dxva_ctx->decoder       = frames_hwctx->decoder_to_release;
608
+    dxva_ctx->surface       = frames_hwctx->surfaces;
609
+    dxva_ctx->surface_count = frames_hwctx->nb_surfaces;
610 610
 
611 611
     if (IsEqualGUID(&ctx->decoder_guid, &DXVADDI_Intel_ModeH264_E))
612 612
         dxva_ctx->workaround |= FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO;
613 613
 
614 614
     return 0;
615 615
 fail:
616
-    dxva2_destroy_decoder(s);
616
+    av_buffer_unref(&ctx->hw_frames_ctx);
617 617
     return AVERROR(EINVAL);
618 618
 }
619 619
 
... ...
@@ -643,8 +550,7 @@ int dxva2_init(AVCodecContext *s)
643 643
         return AVERROR(EINVAL);
644 644
     }
645 645
 
646
-    if (ctx->decoder)
647
-        dxva2_destroy_decoder(s);
646
+    av_buffer_unref(&ctx->hw_frames_ctx);
648 647
 
649 648
     ret = dxva2_create_decoder(s);
650 649
     if (ret < 0) {