summaryrefslogtreecommitdiff
path: root/libavcodec/h264.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-02-16 18:46:28 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-02-16 18:54:56 +0100
commit1fad547cefb4d2f3ed3d764b547ee16cf399e477 (patch)
treee0c261a8eb1823e1ab9235d1ff7c66a8058a247c /libavcodec/h264.c
parent2bac1535db970e981e90306d64f2252be4c9fd63 (diff)
parent54974c62982ae827becdbdb9b620b7ba75d079a0 (diff)
Merge commit '54974c62982ae827becdbdb9b620b7ba75d079a0'
* commit '54974c62982ae827becdbdb9b620b7ba75d079a0': error_resilience: decouple ER from MpegEncContext Conflicts: libavcodec/error_resilience.c libavcodec/h263dec.c libavcodec/h264.c libavcodec/mpegvideo.c libavcodec/vc1dec.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/h264.c')
-rw-r--r--libavcodec/h264.c75
1 files changed, 63 insertions, 12 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 3a44bd475c..087e5fcca6 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -91,6 +91,42 @@ int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx)
return h ? h->sps.num_reorder_frames : 0;
}
+static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
+ int (*mv)[2][4][2],
+ int mb_x, int mb_y, int mb_intra, int mb_skipped)
+{
+ H264Context *h = opaque;
+ MpegEncContext *s = &h->s;
+
+ s->mb_x = mb_x;
+ s->mb_y = mb_y;
+ h->mb_xy = s->mb_x + s->mb_y * s->mb_stride;
+ memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
+ av_assert1(ref >= 0);
+ /* FIXME: It is possible albeit uncommon that slice references
+ * differ between slices. We take the easy approach and ignore
+ * it for now. If this turns out to have any relevance in
+ * practice then correct remapping should be added. */
+ if (ref >= h->ref_count[0])
+ ref = 0;
+ if (!h->ref_list[0][ref].f.data[0]) {
+ av_log(s->avctx, AV_LOG_DEBUG, "Reference not available for error concealing\n");
+ ref = 0;
+ }
+ if ((h->ref_list[0][ref].f.reference&3) != 3) {
+ av_log(s->avctx, AV_LOG_DEBUG, "Reference invalid\n");
+ return;
+ }
+ fill_rectangle(&s->current_picture.f.ref_index[0][4 * h->mb_xy],
+ 2, 2, 2, ref, 1);
+ fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
+ fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8,
+ pack16to32((*mv)[0][0][0], (*mv)[0][0][1]), 4);
+ h->mb_mbaff =
+ h->mb_field_decoding_flag = 0;
+ ff_h264_hl_decode_mb(h);
+}
+
/**
* Check if the top & left blocks are available if needed and
* change the dc mode so it only uses the available blocks.
@@ -977,6 +1013,9 @@ static int context_init(H264Context *h)
h->ref_cache[1][scan8[7] + 1] =
h->ref_cache[1][scan8[13] + 1] = PART_NOT_AVAILABLE;
+ h->s.er.decode_mb = h264_er_decode_mb;
+ h->s.er.opaque = h;
+
return 0;
fail:
@@ -1355,7 +1394,8 @@ int ff_h264_frame_start(H264Context *h)
return -1;
if(!h->sync)
avpriv_color_frame(&h->s.current_picture_ptr->f, c);
- ff_er_frame_start(s);
+
+ ff_mpeg_er_frame_start(s);
/*
* ff_MPV_frame_start uses pict_type to derive key_frame.
* This is incorrect for H.264; IDR markings must be used.
@@ -2378,7 +2418,7 @@ static int field_end(H264Context *h, int in_setup)
* causes problems for the first MB line, too.
*/
if (!FIELD_PICTURE && h->current_slice && !h->sps.new)
- ff_er_frame_end(s);
+ ff_er_frame_end(&s->er);
ff_MPV_frame_end(s);
@@ -3158,11 +3198,13 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
s->last_picture_ptr = &h->ref_list[0][0];
s->last_picture_ptr->owner2 = s;
+ s->er.last_pic = s->last_picture_ptr;
ff_copy_picture(&s->last_picture, s->last_picture_ptr);
}
if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
s->next_picture_ptr = &h->ref_list[1][0];
s->next_picture_ptr->owner2 = s;
+ s->er.next_pic = s->next_picture_ptr;
ff_copy_picture(&s->next_picture, s->next_picture_ptr);
}
@@ -3734,6 +3776,15 @@ static void decode_finish_row(H264Context *h)
s->picture_structure == PICT_BOTTOM_FIELD);
}
+static void er_add_slice(H264Context *h, int startx, int starty,
+ int endx, int endy, int status)
+{
+ ERContext *er = &h->s.er;
+
+ er->ref_count = h->ref_count[0];
+ ff_er_add_slice(er, startx, starty, endx, endy, status);
+}
+
static int decode_slice(struct AVCodecContext *avctx, void *arg)
{
H264Context *h = *(void **)arg;
@@ -3782,7 +3833,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
if ((s->workaround_bugs & FF_BUG_TRUNCATED) &&
h->cabac.bytestream > h->cabac.bytestream_end + 2) {
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x - 1,
+ er_add_slice(h, s->resync_mb_x, s->resync_mb_y, s->mb_x - 1,
s->mb_y, ER_MB_END);
if (s->mb_x >= lf_x_start)
loop_filter(h, lf_x_start, s->mb_x + 1);
@@ -3795,7 +3846,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
"error while decoding MB %d %d, bytestream (%td)\n",
s->mb_x, s->mb_y,
h->cabac.bytestream_end - h->cabac.bytestream);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x,
+ er_add_slice(h, s->resync_mb_x, s->resync_mb_y, s->mb_x,
s->mb_y, ER_MB_ERROR);
return -1;
}
@@ -3815,7 +3866,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
if (eos || s->mb_y >= s->mb_height) {
tprintf(s->avctx, "slice end %d %d\n",
get_bits_count(&s->gb), s->gb.size_in_bits);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x - 1,
+ er_add_slice(h, s->resync_mb_x, s->resync_mb_y, s->mb_x - 1,
s->mb_y, ER_MB_END);
if (s->mb_x > lf_x_start)
loop_filter(h, lf_x_start, s->mb_x);
@@ -3842,7 +3893,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
if (ret < 0) {
av_log(h->s.avctx, AV_LOG_ERROR,
"error while decoding MB %d %d\n", s->mb_x, s->mb_y);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x,
+ er_add_slice(h, s->resync_mb_x, s->resync_mb_y, s->mb_x,
s->mb_y, ER_MB_ERROR);
return -1;
}
@@ -3863,13 +3914,13 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
if ( get_bits_left(&s->gb) == 0
|| get_bits_left(&s->gb) > 0 && !(s->avctx->err_recognition & AV_EF_AGGRESSIVE)) {
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
+ er_add_slice(h, s->resync_mb_x, s->resync_mb_y,
s->mb_x - 1, s->mb_y,
ER_MB_END);
return 0;
} else {
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
+ er_add_slice(h, s->resync_mb_x, s->resync_mb_y,
s->mb_x, s->mb_y,
ER_MB_END);
@@ -3882,7 +3933,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
tprintf(s->avctx, "slice end %d %d\n",
get_bits_count(&s->gb), s->gb.size_in_bits);
if (get_bits_left(&s->gb) == 0) {
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
+ er_add_slice(h, s->resync_mb_x, s->resync_mb_y,
s->mb_x - 1, s->mb_y,
ER_MB_END);
if (s->mb_x > lf_x_start)
@@ -3890,7 +3941,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
return 0;
} else {
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x,
+ er_add_slice(h, s->resync_mb_x, s->resync_mb_y, s->mb_x,
s->mb_y, ER_MB_ERROR);
return -1;
@@ -3923,7 +3974,7 @@ static int execute_decode_slices(H264Context *h, int context_count)
for (i = 1; i < context_count; i++) {
hx = h->thread_context[i];
hx->s.err_recognition = avctx->err_recognition;
- hx->s.error_count = 0;
+ hx->s.er.error_count = 0;
hx->x264_build = h->x264_build;
}
@@ -3937,7 +3988,7 @@ static int execute_decode_slices(H264Context *h, int context_count)
s->droppable = hx->s.droppable;
s->picture_structure = hx->s.picture_structure;
for (i = 1; i < context_count; i++)
- h->s.error_count += h->thread_context[i]->s.error_count;
+ h->s.er.error_count += h->thread_context[i]->s.er.error_count;
}
return 0;