Ticket #8620: 0001-DXVA2_stabilization.commit

File 0001-DXVA2_stabilization.commit, 2.5 KB (added by SHinck@…, 6 years ago)

Fix for picture corruption

Line 
1From c283642dcb0827c62abfce6f4839a37f2a71a88a Mon Sep 17 00:00:00 2001
2From: Sascha Hinck <SHinck@web.de>
3Date: Sat, 6 Jul 2013 01:37:04 +0200
4Subject: [PATCH] DXVA picture stabilization at seeks or FFW/FREW
5
6After seeks or even switch channels at playing live tv with dxva2 hardware
7decoding the picture isn't smooth but there are distortions and frame
8swapping. That's because of begin_frame in dxva2 decoder fails. This
9commit fixes this.
10---
11 mythtv/external/FFmpeg/libavcodec/dxva2.c |   28 +++++++++++++++++++++++-----
12 1 files changed, 23 insertions(+), 5 deletions(-)
13
14diff --git a/mythtv/external/FFmpeg/libavcodec/dxva2.c b/mythtv/external/FFmpeg/libavcodec/dxva2.c
15index d866071..ca2fa69 100644
16--- a/mythtv/external/FFmpeg/libavcodec/dxva2.c
17+++ b/mythtv/external/FFmpeg/libavcodec/dxva2.c
18@@ -76,6 +76,20 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
19     return result;
20 }
21 
22+#define MAX_RETRY_ON_PENDING 50
23+#define DO_DXVA_PENDING_LOOP(x) nTry = 0; \
24+while (FAILED(result = x) && nTry < MAX_RETRY_ON_PENDING) \
25+{ \
26+    if (result != E_PENDING) break; \
27+    av_log(avctx, AV_LOG_INFO, " Dxva2 pending: %d\n",nTry); \
28+    Sleep(dxva_delay); \
29+    if (nTry) { \
30+        av_log(avctx, AV_LOG_INFO, " Dxva2 pending Delay: %d\n",dxva_delay); \
31+        dxva_delay++; \
32+    } \
33+    nTry++; \
34+}
35+
36 int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s,
37                               const void *pp, unsigned pp_size,
38                               const void *qm, unsigned qm_size,
39@@ -87,12 +101,16 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s,
40     unsigned               buffer_count = 0;
41     DXVA2_DecodeBufferDesc buffer[4];
42     DXVA2_DecodeExecuteParams exec = { 0 };
43-    int      result;
44+    int      result, nTry;
45+    void *surface;
46+    static int dxva_delay = 0;
47+
48+    surface = ff_dxva2_get_surface(s->current_picture_ptr);
49 
50-    if (FAILED(IDirectXVideoDecoder_BeginFrame(ctx->decoder,
51-                                               ff_dxva2_get_surface(s->current_picture_ptr),
52-                                               NULL))) {
53-        av_log(avctx, AV_LOG_ERROR, "Failed to begin frame\n");
54+    DO_DXVA_PENDING_LOOP(IDirectXVideoDecoder_BeginFrame(ctx->decoder,surface,NULL))
55+    if (FAILED(result)) {
56+        av_log(avctx, AV_LOG_ERROR, "Failed to begin frame (0x%.8X), surface %.8x, index %d\n",result,
57+                surface,ff_dxva2_get_surface_index(ctx,s->current_picture_ptr));
58         return -1;
59     }
60