[FFmpeg-cvslog] avcodec/h264: Keep a reference to the last picture for EC
Michael Niedermayer
git at videolan.org
Sun Jan 11 17:42:27 CET 2015
ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Sun Jan 11 16:40:27 2015 +0100| [855463c007719d8a9cddfa757a00ae5428b3dbde] | committer: Michael Niedermayer
avcodec/h264: Keep a reference to the last picture for EC
This and the next commit improve error concealment for
green-block-artifacts-from-canon-100-hs.MOV
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=855463c007719d8a9cddfa757a00ae5428b3dbde
---
libavcodec/h264.c | 5 +++++
libavcodec/h264.h | 1 +
libavcodec/h264_refs.c | 4 ++++
libavcodec/h264_slice.c | 8 +++++++-
4 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index f40449e..b27e747 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -1838,6 +1838,8 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data,
* packets do not get used. */
h->data_partitioning = 0;
+ ff_h264_unref_picture(h, &h->last_pic_for_ec);
+
/* end of stream, output what is still in the buffers */
if (buf_size == 0) {
out:
@@ -1930,6 +1932,8 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data,
assert(pict->buf[0] || !*got_frame);
+ ff_h264_unref_picture(h, &h->last_pic_for_ec);
+
return get_consumed_bytes(buf_index, buf_size);
}
@@ -1954,6 +1958,7 @@ static av_cold int h264_decode_end(AVCodecContext *avctx)
ff_h264_free_context(h);
ff_h264_unref_picture(h, &h->cur_pic);
+ ff_h264_unref_picture(h, &h->last_pic_for_ec);
return 0;
}
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 74c1bbf..2d8e137 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -352,6 +352,7 @@ typedef struct H264Context {
H264Picture *DPB;
H264Picture *cur_pic_ptr;
H264Picture cur_pic;
+ H264Picture last_pic_for_ec;
int pixel_shift; ///< 0 for 8-bit H264, 1 for high-bit-depth H264
int chroma_qp[2]; // QPc
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index 12da921..78c283c 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -493,6 +493,10 @@ void ff_h264_remove_all_refs(H264Context *h)
}
assert(h->long_ref_count == 0);
+ ff_h264_unref_picture(h, &h->last_pic_for_ec);
+ if (h->short_ref_count)
+ ff_h264_ref_picture(h, &h->last_pic_for_ec, h->short_ref[0]);
+
for (i = 0; i < h->short_ref_count; i++) {
unreference_pic(h, h->short_ref[i], 0);
h->short_ref[i] = NULL;
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index e689044..ae50b9a 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -542,6 +542,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
memset(&h->mb_luma_dc, 0, sizeof(h->mb_luma_dc));
memset(&h->mb_padding, 0, sizeof(h->mb_padding));
memset(&h->cur_pic, 0, sizeof(h->cur_pic));
+ memset(&h->last_pic_for_ec, 0, sizeof(h->last_pic_for_ec));
h->avctx = dst;
h->DPB = NULL;
@@ -1959,7 +1960,12 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0)
(h->ref_list[j][i].reference & 3);
}
- if (h->ref_count[0]) ff_h264_set_erpic(&h->er.last_pic, &h->ref_list[0][0]);
+ if (h->ref_count[0]) {
+ ff_h264_set_erpic(&h->er.last_pic, &h->ref_list[0][0]);
+ } else if (h->last_pic_for_ec.f.buf[0]) {
+ ff_h264_set_erpic(&h->er.last_pic, &h->last_pic_for_ec);
+ }
+
if (h->ref_count[1]) ff_h264_set_erpic(&h->er.next_pic, &h->ref_list[1][0]);
h->er.ref_count = h->ref_count[0];
More information about the ffmpeg-cvslog
mailing list