diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-02-16 18:46:28 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-02-16 18:54:56 +0100 |
commit | 1fad547cefb4d2f3ed3d764b547ee16cf399e477 (patch) | |
tree | e0c261a8eb1823e1ab9235d1ff7c66a8058a247c /libavcodec/h264.c | |
parent | 2bac1535db970e981e90306d64f2252be4c9fd63 (diff) | |
parent | 54974c62982ae827becdbdb9b620b7ba75d079a0 (diff) | |
download | ffmpeg-1fad547cefb4d2f3ed3d764b547ee16cf399e477.tar.gz |
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.c | 75 |
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; |