From 95b4c0af771121001967e01c1a13125c13178e25 Mon Sep 17 00:00:00 2001
From: marc <mhocking@ubuntu-desktop.(none)>
Date: Mon, 18 Feb 2013 17:18:18 +0000
Subject: [PATCH] dxva-h264 Fix dxva playback of streams that don't  start
 with an I-Frame.

---
 libavcodec/dxva2_h264.c |    8 ++++++++
 libavcodec/h264.c       |    2 ++
 libavcodec/h264.h       |    2 ++
 3 files changed, 12 insertions(+)

diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c
index f7d4e5d..2ad4afd 100644
--- a/libavcodec/dxva2_h264.c
+++ b/libavcodec/dxva2_h264.c
@@ -431,6 +431,14 @@

     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
         return -1;
+
+    // Wait for an I-frame before start decoding. Workaround for ATI UVD and UVD+ GPUs
+    if (!h->got_first_iframe) {
+        if (!(ctx_pic->pp.wBitFields & (1 << 15)))
+            return -1;
+        h->got_first_iframe = 1;
+    }
+
     ret = ff_dxva2_common_end_frame(avctx, h->cur_pic_ptr,
                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
                                     &ctx_pic->qm, sizeof(ctx_pic->qm),
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 0aab4e7..aee9407 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -2183,6 +2183,7 @@ static void flush_dpb(AVCodecContext *avctx)
             h->delayed_pic[i]->f.reference = 0;
         h->delayed_pic[i] = NULL;
     }
+    h->got_first_iframe = 0;
 
     flush_change(h);
     ff_mpeg_flush(avctx);
@@ -2597,6 +2598,7 @@ static int h264_slice_header_init(H264Context *h, int reinit)
     }
     s->first_field = 0;
     h->prev_interlaced_frame = 1;
+    h->got_first_iframe = 0;
 
     init_scan_tables(h);
     if (ff_h264_alloc_tables(h) < 0) {
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 4b6a19e..06c2384 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -588,6 +588,8 @@ typedef struct H264Context {
     int luma_weight_flag[2];    ///< 7.4.3.2 luma_weight_lX_flag
     int chroma_weight_flag[2];  ///< 7.4.3.2 chroma_weight_lX_flag
 
+    int got_first_iframe;
+
     // Timestamp stuff
     int sei_buffering_period_present;   ///< Buffering period SEI flag
     int initial_cpb_removal_delay[32];  ///< Initial timestamps for CPBs
-- 
1.7.10.4

