vaapi: switch ff_vaapi_get_surface_id from Picture to AVFrame
[ffmpeg.git] / libavcodec / dxva2.c
index 63addb7..6d4550c 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <assert.h>
+#include <string.h>
+
+#include "libavutil/log.h"
+#include "libavutil/time.h"
+
+#include "avcodec.h"
+#include "mpegvideo.h"
 #include "dxva2_internal.h"
 
 void *ff_dxva2_get_surface(const Picture *picture)
@@ -50,10 +58,13 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
     void     *dxva_data;
     unsigned dxva_size;
     int      result;
+    HRESULT hr;
 
-    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, type,
-                                              &dxva_data, &dxva_size))) {
-        av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %d\n", type);
+    hr = IDirectXVideoDecoder_GetBuffer(ctx->decoder, type,
+                                        &dxva_data, &dxva_size);
+    if (FAILED(hr)) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %u: 0x%lx\n",
+               type, hr);
         return -1;
     }
     if (size <= dxva_size) {
@@ -66,17 +77,21 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
 
         result = 0;
     } else {
-        av_log(avctx, AV_LOG_ERROR, "Buffer for type %d was too small\n", type);
+        av_log(avctx, AV_LOG_ERROR, "Buffer for type %u was too small\n", type);
         result = -1;
     }
-    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type))) {
-        av_log(avctx, AV_LOG_ERROR, "Failed to release buffer type %d\n", type);
+
+    hr = IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type);
+    if (FAILED(hr)) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Failed to release buffer type %u: 0x%lx\n",
+               type, hr);
         result = -1;
     }
     return result;
 }
 
-int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s,
+int ff_dxva2_common_end_frame(AVCodecContext *avctx, Picture *pic,
                               const void *pp, unsigned pp_size,
                               const void *qm, unsigned qm_size,
                               int (*commit_bs_si)(AVCodecContext *,
@@ -87,12 +102,19 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s,
     unsigned               buffer_count = 0;
     DXVA2_DecodeBufferDesc buffer[4];
     DXVA2_DecodeExecuteParams exec = { 0 };
-    int      result;
-
-    if (FAILED(IDirectXVideoDecoder_BeginFrame(ctx->decoder,
-                                               ff_dxva2_get_surface(s->current_picture_ptr),
-                                               NULL))) {
-        av_log(avctx, AV_LOG_ERROR, "Failed to begin frame\n");
+    int result, runs = 0;
+    HRESULT hr;
+
+    do {
+        hr = IDirectXVideoDecoder_BeginFrame(ctx->decoder,
+                                             ff_dxva2_get_surface(pic),
+                                             NULL);
+        if (hr == E_PENDING)
+            av_usleep(2000);
+    } while (hr == E_PENDING && ++runs < 50);
+
+    if (FAILED(hr)) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to begin frame: 0x%lx\n", hr);
         return -1;
     }
 
@@ -135,18 +157,18 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s,
     exec.NumCompBuffers      = buffer_count;
     exec.pCompressedBuffers  = buffer;
     exec.pExtensionData      = NULL;
-    if (FAILED(IDirectXVideoDecoder_Execute(ctx->decoder, &exec))) {
-        av_log(avctx, AV_LOG_ERROR, "Failed to execute\n");
+    hr = IDirectXVideoDecoder_Execute(ctx->decoder, &exec);
+    if (FAILED(hr)) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to execute: 0x%lx\n", hr);
         result = -1;
     }
 
 end:
-    if (FAILED(IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL))) {
-        av_log(avctx, AV_LOG_ERROR, "Failed to end frame\n");
+    hr = IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL);
+    if (FAILED(hr)) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to end frame: 0x%lx\n", hr);
         result = -1;
     }
 
-    if (!result)
-        ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
     return result;
 }