From f8c507f44b4c994895fc7ad954f009f61de69b1c Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Thu, 13 Feb 2014 15:31:57 +0100 Subject: [PATCH] h264: Refactor ff_h264_decode_ref_pic_list_reordering In preparation for MVC support. --- libavcodec/h264_refs.c | 136 ++++++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 64 deletions(-) diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 88aaac7e1b..a0b8f4583f 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -237,75 +237,83 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h) return -1; } - if (reordering_of_pic_nums_idc < 3) { - if (reordering_of_pic_nums_idc < 2) { - const unsigned int abs_diff_pic_num = get_ue_golomb(&h->gb) + 1; - int frame_num; - - if (abs_diff_pic_num > h->max_pic_num) { - av_log(h->avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n"); - return -1; - } - - if (reordering_of_pic_nums_idc == 0) - pred -= abs_diff_pic_num; - else - pred += abs_diff_pic_num; - pred &= h->max_pic_num - 1; - - frame_num = pic_num_extract(h, pred, &pic_structure); - - for (i = h->short_ref_count - 1; i >= 0; i--) { - ref = h->short_ref[i]; - assert(ref->reference); - assert(!ref->long_ref); - if (ref->frame_num == frame_num && - (ref->reference & pic_structure)) - break; - } - if (i >= 0) - ref->pic_id = pred; - } else { - int long_idx; - pic_id = get_ue_golomb(&h->gb); //long_term_pic_idx - - long_idx = pic_num_extract(h, pic_id, &pic_structure); - - if (long_idx > 31) { - av_log(h->avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n"); - return -1; - } - ref = h->long_ref[long_idx]; - assert(!(ref && !ref->reference)); - if (ref && (ref->reference & pic_structure)) { - ref->pic_id = pic_id; - assert(ref->long_ref); - i = 0; - } else { - i = -1; - } + switch (reordering_of_pic_nums_idc) { + case 0: + case 1: { + const unsigned int abs_diff_pic_num = get_ue_golomb(&h->gb) + 1; + int frame_num; + + if (abs_diff_pic_num > h->max_pic_num) { + av_log(h->avctx, AV_LOG_ERROR, + "abs_diff_pic_num overflow\n"); + return AVERROR_INVALIDDATA; + } + + if (reordering_of_pic_nums_idc == 0) + pred -= abs_diff_pic_num; + else + pred += abs_diff_pic_num; + pred &= h->max_pic_num - 1; + + frame_num = pic_num_extract(h, pred, &pic_structure); + + for (i = h->short_ref_count - 1; i >= 0; i--) { + ref = h->short_ref[i]; + assert(ref->reference); + assert(!ref->long_ref); + if (ref->frame_num == frame_num && + (ref->reference & pic_structure)) + break; } + if (i >= 0) + ref->pic_id = pred; + break; + } + case 2: { + int long_idx; + pic_id = get_ue_golomb(&h->gb); // long_term_pic_idx + + long_idx = pic_num_extract(h, pic_id, &pic_structure); - if (i < 0) { - av_log(h->avctx, AV_LOG_ERROR, "reference picture missing during reorder\n"); - memset(&h->ref_list[list][index], 0, sizeof(Picture)); //FIXME + if (long_idx > 31) { + av_log(h->avctx, AV_LOG_ERROR, + "long_term_pic_idx overflow\n"); + return AVERROR_INVALIDDATA; + } + ref = h->long_ref[long_idx]; + assert(!(ref && !ref->reference)); + if (ref && (ref->reference & pic_structure)) { + ref->pic_id = pic_id; + assert(ref->long_ref); + i = 0; } else { - for (i = index; i + 1 < h->ref_count[list]; i++) { - if (ref->long_ref == h->ref_list[list][i].long_ref && - ref->pic_id == h->ref_list[list][i].pic_id) - break; - } - for (; i > index; i--) { - COPY_PICTURE(&h->ref_list[list][i], &h->ref_list[list][i - 1]); - } - COPY_PICTURE(&h->ref_list[list][index], ref); - if (FIELD_PICTURE(h)) { - pic_as_field(&h->ref_list[list][index], pic_structure); - } + i = -1; } + break; + } + default: + av_log(h->avctx, AV_LOG_ERROR, + "illegal reordering_of_pic_nums_idc\n"); + return AVERROR_INVALIDDATA; + } + + if (i < 0) { + av_log(h->avctx, AV_LOG_ERROR, + "reference picture missing during reorder\n"); + memset(&h->ref_list[list][index], 0, sizeof(Picture)); // FIXME } else { - av_log(h->avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n"); - return -1; + for (i = index; i + 1 < h->ref_count[list]; i++) { + if (ref->long_ref == h->ref_list[list][i].long_ref && + ref->pic_id == h->ref_list[list][i].pic_id) + break; + } + for (; i > index; i--) { + COPY_PICTURE(&h->ref_list[list][i], &h->ref_list[list][i - 1]); + } + COPY_PICTURE(&h->ref_list[list][index], ref); + if (FIELD_PICTURE(h)) { + pic_as_field(&h->ref_list[list][index], pic_structure); + } } } } -- 2.11.0