[SCM] libav/experimental: dxva2_h264: set the correct ref frame index in the long slice struct

siretart at users.alioth.debian.org siretart at users.alioth.debian.org
Sun Aug 10 16:02:59 UTC 2014


The following commit has been merged in the experimental branch:
commit 2fcef90bee98bffeff1d95b7197738f50c450d86
Author: Hendrik Leppkes <h.leppkes at gmail.com>
Date:   Tue Apr 22 15:22:50 2014 +0200

    dxva2_h264: set the correct ref frame index in the long slice struct
    
    The latest H.264 DXVA specification states that the index in this
    structure should refer to a valid entry in the RefFrameList of the picture
    parameter structure, and not to the actual surface index.
    
    Fixes H.264 DXVA2 decoding on recent Intel GPUs (tested on Sandy and Ivy)
    
    Signed-off-by: Anton Khirnov <anton at khirnov.net>

diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c
index 2e6f57d..1e4d98a 100644
--- a/libavcodec/dxva2_h264.c
+++ b/libavcodec/dxva2_h264.c
@@ -195,8 +195,18 @@ static void fill_slice_short(DXVA_Slice_H264_Short *slice,
     slice->wBadSliceChopping     = 0;
 }
 
+static int get_refpic_index(const DXVA_PicParams_H264 *pp, int surface_index)
+{
+    int i;
+    for (i = 0; i < FF_ARRAY_ELEMS(pp->RefFrameList); i++) {
+        if ((pp->RefFrameList[i].bPicEntry & 0x7f) == surface_index)
+          return i;
+    }
+    return 0x7f;
+}
+
 static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
-                            unsigned position, unsigned size)
+                            const DXVA_PicParams_H264 *pp, unsigned position, unsigned size)
 {
     const H264Context *h = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
@@ -229,8 +239,8 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
             if (list < h->list_count && i < h->ref_count[list]) {
                 const H264Picture *r = &h->ref_list[list][i];
                 unsigned plane;
-                fill_picture_entry(&slice->RefPicList[list][i],
-                                   ff_dxva2_get_surface_index(ctx, &r->f),
+                unsigned index = get_refpic_index(pp, ff_dxva2_get_surface_index(ctx, &r->f));
+                fill_picture_entry(&slice->RefPicList[list][i], index,
                                    r->reference == PICT_BOTTOM_FIELD);
                 for (plane = 0; plane < 3; plane++) {
                     int w, o;
@@ -415,7 +425,7 @@ static int dxva2_h264_decode_slice(AVCodecContext *avctx,
                          position, size);
     else
         fill_slice_long(avctx, &ctx_pic->slice_long[ctx_pic->slice_count],
-                        position, size);
+                        &ctx_pic->pp, position, size);
     ctx_pic->slice_count++;
 
     if (h->slice_type != AV_PICTURE_TYPE_I && h->slice_type != AV_PICTURE_TYPE_SI)

-- 
Libav/FFmpeg packaging



More information about the pkg-multimedia-commits mailing list