| From 939ebbbc46ca9995637415594f1815633587104f Mon Sep 17 00:00:00 2001 |
| From: marc <mhocking@ubuntu-desktop.(none)> |
| Date: Mon, 18 Feb 2013 17:18:18 +0000 |
| Subject: [PATCH 12/13] dxva-h264 Fix dxva playback of streams that don't start |
| with an I-Frame. |
| |
| Patch part of the XBMC patch set for ffmpeg, downloaded from |
| https://github.com/xbmc/FFmpeg/. |
| |
| Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de> |
| Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> |
| --- |
| libavcodec/dxva2_h264.c | 8 ++++++++ |
| libavcodec/h264.c | 1 + |
| libavcodec/h264.h | 2 ++ |
| libavcodec/h264_slice.c | 1 + |
| 4 files changed, 12 insertions(+) |
| |
| diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c |
| index 6deccc3..85b25fd 100644 |
| --- a/libavcodec/dxva2_h264.c |
| +++ b/libavcodec/dxva2_h264.c |
| @@ -451,6 +451,14 @@ static int dxva2_h264_end_frame(AVCodecContext *avctx) |
| |
| 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->f, |
| &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 222bf58..ea2ec17 100644 |
| --- a/libavcodec/h264.c |
| +++ b/libavcodec/h264.c |
| @@ -1085,6 +1085,7 @@ void ff_h264_flush_change(H264Context *h) |
| h->mmco_reset = 1; |
| for (i = 0; i < h->nb_slice_ctx; i++) |
| h->slice_ctx[i].list_count = 0; |
| + h->got_first_iframe = 0; |
| } |
| |
| /* forget old pics after a seek */ |
| diff --git a/libavcodec/h264.h b/libavcodec/h264.h |
| index b94f06b..bc9458b 100644 |
| --- a/libavcodec/h264.h |
| +++ b/libavcodec/h264.h |
| @@ -741,6 +741,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 |
| diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c |
| index 53f61ca..b171d78 100644 |
| --- a/libavcodec/h264_slice.c |
| +++ b/libavcodec/h264_slice.c |
| @@ -1189,6 +1189,7 @@ static int h264_slice_header_init(H264Context *h, int reinit) |
| ff_h264_free_tables(h, 0); |
| h->first_field = 0; |
| h->prev_interlaced_frame = 1; |
| + h->got_first_iframe = 0; |
| |
| init_scan_tables(h); |
| ret = ff_h264_alloc_tables(h); |
| -- |
| 2.1.0 |
| |