diff options
author | CrystalP <CrystalP@xbmc.org> | 2011-10-05 13:13:25 -0400 |
---|---|---|
committer | CrystalP <CrystalP@xbmc.org> | 2011-10-15 17:20:23 -0400 |
commit | 15239ded0a9a0cd0ff4950a6f79390981d5ad959 (patch) | |
tree | 89aaa5c3cbcb2544da39cbe159f483729d4422c8 /lib/ffmpeg/libavcodec | |
parent | b16cd79940bc7c08fe9da9f6645e208073aeee71 (diff) |
dxva-h264 Fix dxva playback of streams that don't start with an I-Frame.
GPUs with ATI UVDa and UVD+ have trouble when decoding doesn't start on an
I-Frame, and they don't recover on later I-Frames.
The variable to track the first I-Frame is in H264Context so that it can be
reset by code in h264 when initializing the context or flushing.
credits isidrogar, see ticket #11772.
sample on team ftp, samples/11772/CSI_ New York - TV3 - 2008-09-16_1.ts
Diffstat (limited to 'lib/ffmpeg/libavcodec')
-rw-r--r-- | lib/ffmpeg/libavcodec/dxva2_h264.c | 8 | ||||
-rw-r--r-- | lib/ffmpeg/libavcodec/h264.c | 2 | ||||
-rw-r--r-- | lib/ffmpeg/libavcodec/h264.h | 2 |
3 files changed, 12 insertions, 0 deletions
diff --git a/lib/ffmpeg/libavcodec/dxva2_h264.c b/lib/ffmpeg/libavcodec/dxva2_h264.c index 4e3370cf4d..2954b89c8b 100644 --- a/lib/ffmpeg/libavcodec/dxva2_h264.c +++ b/lib/ffmpeg/libavcodec/dxva2_h264.c @@ -430,6 +430,14 @@ static int 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; + } + return ff_dxva2_common_end_frame(avctx, s, &ctx_pic->pp, sizeof(ctx_pic->pp), &ctx_pic->qm, sizeof(ctx_pic->qm), diff --git a/lib/ffmpeg/libavcodec/h264.c b/lib/ffmpeg/libavcodec/h264.c index b84430a1d7..a4d35ae623 100644 --- a/lib/ffmpeg/libavcodec/h264.c +++ b/lib/ffmpeg/libavcodec/h264.c @@ -1479,6 +1479,7 @@ static void flush_dpb(AVCodecContext *avctx){ h->delayed_pic[i]->reference= 0; h->delayed_pic[i]= NULL; } + h->got_first_iframe = 0; h->outputed_poc= INT_MIN; h->prev_interlaced_frame = 1; idr(h); @@ -1848,6 +1849,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ return -1; s->first_field = 0; h->prev_interlaced_frame = 1; + h->got_first_iframe = 0; init_scan_tables(h); ff_h264_alloc_tables(h); diff --git a/lib/ffmpeg/libavcodec/h264.h b/lib/ffmpeg/libavcodec/h264.h index b403968485..bdca23763d 100644 --- a/lib/ffmpeg/libavcodec/h264.h +++ b/lib/ffmpeg/libavcodec/h264.h @@ -587,6 +587,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 |