diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-02-14 13:23:45 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-02-14 13:24:30 +0100 |
commit | 5cbd7ce016adec2beafe49be931ff445f3decdaf (patch) | |
tree | b10357c997b33b3d12fd6317445a06b99944b743 /libavcodec | |
parent | 1e5cb426c687858bdc3d2729123790de106d00cb (diff) | |
parent | f8c507f44b4c994895fc7ad954f009f61de69b1c (diff) | |
download | ffmpeg-5cbd7ce016adec2beafe49be931ff445f3decdaf.tar.gz |
Merge commit 'f8c507f44b4c994895fc7ad954f009f61de69b1c'
* commit 'f8c507f44b4c994895fc7ad954f009f61de69b1c':
h264: Refactor ff_h264_decode_ref_pic_list_reordering
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/h264_refs.c | 132 |
1 files changed, 70 insertions, 62 deletions
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index eecdfa8126..0ca4878345 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -242,75 +242,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 + 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; - long_idx = pic_num_extract(h, pic_id, &pic_structure); + 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 (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; - } + 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 - 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 + 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 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); + } } } } |