Пример #1
0
void ff_h264_direct_dist_scale_factor(const H264Context *const h,
                                      H264SliceContext *sl)
{
    const int poc  = FIELD_PICTURE(h) ? h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD]
                                      : h->cur_pic_ptr->poc;
    const int poc1 = sl->ref_list[1][0].poc;
    int i, field;

    if (FRAME_MBAFF(h))
        for (field = 0; field < 2; field++) {
            const int poc  = h->cur_pic_ptr->field_poc[field];
            const int poc1 = sl->ref_list[1][0].parent->field_poc[field];
            for (i = 0; i < 2 * sl->ref_count[0]; i++)
                sl->dist_scale_factor_field[field][i ^ field] =
                    get_scale_factor(sl, poc, poc1, i + 16);
        }

    for (i = 0; i < sl->ref_count[0]; i++)
        sl->dist_scale_factor[i] = get_scale_factor(sl, poc, poc1, i);
}
Пример #2
0
int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
                                   int first_slice)
{
    int i, ret;
    MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = mmco_temp;
    int mmco_index = 0;

    if (h->nal_unit_type == NAL_IDR_SLICE) { // FIXME fields
        skip_bits1(gb); // broken_link
        if (get_bits1(gb)) {
            mmco[0].opcode   = MMCO_LONG;
            mmco[0].long_arg = 0;
            mmco_index       = 1;
        }
    } else {
        if (get_bits1(gb)) { // adaptive_ref_pic_marking_mode_flag
            for (i = 0; i < MAX_MMCO_COUNT; i++) {
                MMCOOpcode opcode = get_ue_golomb_31(gb);

                mmco[i].opcode = opcode;
                if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG) {
                    mmco[i].short_pic_num =
                        (h->curr_pic_num - get_ue_golomb(gb) - 1) &
                            (h->max_pic_num - 1);
#if 0
                    if (mmco[i].short_pic_num >= h->short_ref_count ||
                        h->short_ref[ mmco[i].short_pic_num ] == NULL){
                        av_log(s->avctx, AV_LOG_ERROR,
                               "illegal short ref in memory management control "
                               "operation %d\n", mmco);
                        return -1;
                    }
#endif
                }
                if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED ||
                    opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG) {
                    unsigned int long_arg = get_ue_golomb_31(gb);
                    if (long_arg >= 32 ||
                        (long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG &&
                                             long_arg == 16) &&
                         !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE(h)))) {
                        av_log(h->avctx, AV_LOG_ERROR,
                               "illegal long ref in memory management control "
                               "operation %d\n", opcode);
                        return -1;
                    }
                    mmco[i].long_arg = long_arg;
                }

                if (opcode > (unsigned) MMCO_LONG) {
                    av_log(h->avctx, AV_LOG_ERROR,
                           "illegal memory management control operation %d\n",
                           opcode);
                    return -1;
                }
                if (opcode == MMCO_END)
                    break;
            }
            mmco_index = i;
        } else {
            if (first_slice) {
                ret = ff_generate_sliding_window_mmcos(h, first_slice);
                if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE)
                    return ret;
            }
            mmco_index = -1;
        }
    }

    if (first_slice && mmco_index != -1) {
        memcpy(h->mmco, mmco_temp, sizeof(h->mmco));
        h->mmco_index = mmco_index;
    } else if (!first_slice && mmco_index >= 0 &&
               (mmco_index != h->mmco_index ||
                check_opcodes(h->mmco, mmco_temp, mmco_index))) {
        av_log(h->avctx, AV_LOG_ERROR,
               "Inconsistent MMCO state between slices [%d, %d]\n",
               mmco_index, h->mmco_index);
        return AVERROR_INVALIDDATA;
    }

    return 0;
}
Пример #3
0
int ff_h264_decode_ref_pic_list_reordering(H264Context *h)
{
    int list, index, pic_structure, i;

    print_short_term(h);
    print_long_term(h);

    for (list = 0; list < h->list_count; list++) {
        for (i = 0; i < h->ref_count[list]; i++)
            COPY_PICTURE(&h->ref_list[list][i], &h->default_ref_list[list][i]);

        if (get_bits1(&h->gb)) {
            int pred = h->curr_pic_num;

            for (index = 0; ; index++) {
                unsigned int reordering_of_pic_nums_idc = get_ue_golomb_31(&h->gb);
                unsigned int pic_id;
                int i;
                Picture *ref = NULL;

                if (reordering_of_pic_nums_idc == 3)
                    break;

                if (index >= h->ref_count[list]) {
                    av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n");
                    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;
                        }
                    }

                    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 {
                        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);
                        }
                    }
                } else {
                    av_log(h->avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n");
                    return -1;
                }
            }
        }
    }
    for (list = 0; list < h->list_count; list++) {
        for (index = 0; index < h->ref_count[list]; index++) {
            if (   !h->ref_list[list][index].f.buf[0]
                || (!FIELD_PICTURE(h) && (h->ref_list[list][index].reference&3) != 3)) {
                int i;
                av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref_list[list][0].poc);
                for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++)
                    h->last_pocs[i] = INT_MIN;
                if (h->default_ref_list[list][0].f.buf[0]
                    && !(!FIELD_PICTURE(h) && (h->default_ref_list[list][0].reference&3) != 3))
                    COPY_PICTURE(&h->ref_list[list][index], &h->default_ref_list[list][0]);
                else
                    return -1;
            }
            av_assert0(av_buffer_get_ref_count(h->ref_list[list][index].f.buf[0]) > 0);
        }
    }

    return 0;
}
Пример #4
0
int ff_h264_fill_default_ref_list(H264Context *h)
{
    int i, len;

    if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
        Picture *sorted[32];
        int cur_poc, list;
        int lens[2];

        if (FIELD_PICTURE(h))
            cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD];
        else
            cur_poc = h->cur_pic_ptr->poc;

        for (list = 0; list < 2; list++) {
            len  = add_sorted(sorted,       h->short_ref, h->short_ref_count, cur_poc, 1 ^ list);
            len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list);
            av_assert0(len <= 32);

            len  = build_def_list(h->default_ref_list[list], FF_ARRAY_ELEMS(h->default_ref_list[0]),
                                  sorted, len, 0, h->picture_structure);
            len += build_def_list(h->default_ref_list[list] + len,
                                  FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
                                  h->long_ref, 16, 1, h->picture_structure);
            av_assert0(len <= 32);

            if (len < h->ref_count[list])
                memset(&h->default_ref_list[list][len], 0, sizeof(Picture) * (h->ref_count[list] - len));
            lens[list] = len;
        }

        if (lens[0] == lens[1] && lens[1] > 1) {
            for (i = 0; i < lens[0] &&
                        h->default_ref_list[0][i].f.buf[0]->buffer ==
                        h->default_ref_list[1][i].f.buf[0]->buffer; i++);
            if (i == lens[0]) {
                Picture tmp;
                COPY_PICTURE(&tmp, &h->default_ref_list[1][0]);
                COPY_PICTURE(&h->default_ref_list[1][0], &h->default_ref_list[1][1]);
                COPY_PICTURE(&h->default_ref_list[1][1], &tmp);
            }
        }
    } else {
        len  = build_def_list(h->default_ref_list[0], FF_ARRAY_ELEMS(h->default_ref_list[0]),
                              h->short_ref, h->short_ref_count, 0, h->picture_structure);
        len += build_def_list(h->default_ref_list[0] + len,
                              FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
                              h-> long_ref, 16, 1, h->picture_structure);
        av_assert0(len <= 32);

        if (len < h->ref_count[0])
            memset(&h->default_ref_list[0][len], 0, sizeof(Picture) * (h->ref_count[0] - len));
    }
#ifdef TRACE
    for (i = 0; i < h->ref_count[0]; i++) {
        tprintf(h->avctx, "List0: %s fn:%d 0x%p\n",
                (h->default_ref_list[0][i].long_ref ? "LT" : "ST"),
                h->default_ref_list[0][i].pic_id,
                h->default_ref_list[0][i].f.data[0]);
    }
    if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
        for (i = 0; i < h->ref_count[1]; i++) {
            tprintf(h->avctx, "List1: %s fn:%d 0x%p\n",
                    (h->default_ref_list[1][i].long_ref ? "LT" : "ST"),
                    h->default_ref_list[1][i].pic_id,
                    h->default_ref_list[1][i].f.data[0]);
        }
    }
#endif
    return 0;
}
Пример #5
0
int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl)
{
    int list, index, pic_structure;

    print_short_term(h);
    print_long_term(h);

    h264_initialise_ref_list(h, sl);

    for (list = 0; list < sl->list_count; list++) {
        if (get_bits1(&sl->gb)) {    // ref_pic_list_modification_flag_l[01]
            int pred = h->curr_pic_num;

            for (index = 0; ; index++) {
                unsigned int modification_of_pic_nums_idc = get_ue_golomb_31(&sl->gb);
                unsigned int pic_id;
                int i;
                H264Picture *ref = NULL;

                if (modification_of_pic_nums_idc == 3)
                    break;

                if (index >= sl->ref_count[list]) {
                    av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n");
                    return -1;
                }

                switch (modification_of_pic_nums_idc) {
                case 0:
                case 1: {
                    const unsigned int abs_diff_pic_num = get_ue_golomb_long(&sl->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 (modification_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(&sl->gb); // long_term_pic_idx

                    long_idx = pic_num_extract(h, pic_id, &pic_structure);

                    if (long_idx > 31U) {
                        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) && !mismatches_ref(h, ref)) {
                        ref->pic_id = pic_id;
                        assert(ref->long_ref);
                        i = 0;
                    } else {
                        i = -1;
                    }
                    break;
                }
                default:
                    av_log(h->avctx, AV_LOG_ERROR,
                           "illegal modification_of_pic_nums_idc %u\n",
                           modification_of_pic_nums_idc);
                    return AVERROR_INVALIDDATA;
                }

                if (i < 0) {
                    av_log(h->avctx, AV_LOG_ERROR,
                           "reference picture missing during reorder\n");
                    memset(&sl->ref_list[list][index], 0, sizeof(sl->ref_list[0][0])); // FIXME
                } else {
                    for (i = index; i + 1 < sl->ref_count[list]; i++) {
                        if (sl->ref_list[list][i].parent &&
                            ref->long_ref == sl->ref_list[list][i].parent->long_ref &&
                            ref->pic_id   == sl->ref_list[list][i].pic_id)
                            break;
                    }
                    for (; i > index; i--) {
                        sl->ref_list[list][i] = sl->ref_list[list][i - 1];
                    }
                    ref_from_h264pic(&sl->ref_list[list][index], ref);
                    if (FIELD_PICTURE(h)) {
                        pic_as_field(&sl->ref_list[list][index], pic_structure);
                    }
                }
            }
        }
    }
    for (list = 0; list < sl->list_count; list++) {
        for (index = 0; index < sl->ref_count[list]; index++) {
            if (   !sl->ref_list[list][index].parent
                || (!FIELD_PICTURE(h) && (sl->ref_list[list][index].reference&3) != 3)) {
                int i;
                av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref[list].poc);
                for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++)
                    h->last_pocs[i] = INT_MIN;
                if (h->default_ref[list].parent
                    && !(!FIELD_PICTURE(h) && (h->default_ref[list].reference&3) != 3))
                    sl->ref_list[list][index] = h->default_ref[list];
                else
                    return -1;
            }
            av_assert0(av_buffer_get_ref_count(sl->ref_list[list][index].parent->f->buf[0]) > 0);
        }
    }

    return 0;
}
Пример #6
0
static void h264_initialise_ref_list(H264Context *h, H264SliceContext *sl)
{
    int i, len;
    int j;

    if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
        H264Picture *sorted[32];
        int cur_poc, list;
        int lens[2];

        if (FIELD_PICTURE(h))
            cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD];
        else
            cur_poc = h->cur_pic_ptr->poc;

        for (list = 0; list < 2; list++) {
            len  = add_sorted(sorted,       h->short_ref, h->short_ref_count, cur_poc, 1 ^ list);
            len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list);
            av_assert0(len <= 32);

            len  = build_def_list(sl->ref_list[list], FF_ARRAY_ELEMS(sl->ref_list[0]),
                                  sorted, len, 0, h->picture_structure);
            len += build_def_list(sl->ref_list[list] + len,
                                  FF_ARRAY_ELEMS(sl->ref_list[0]) - len,
                                  h->long_ref, 16, 1, h->picture_structure);
            av_assert0(len <= 32);

            if (len < sl->ref_count[list])
                memset(&sl->ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len));
            lens[list] = len;
        }

        if (lens[0] == lens[1] && lens[1] > 1) {
            for (i = 0; i < lens[0] &&
                        sl->ref_list[0][i].parent->f->buf[0]->buffer ==
                        sl->ref_list[1][i].parent->f->buf[0]->buffer; i++);
            if (i == lens[0]) {
                FFSWAP(H264Ref, sl->ref_list[1][0], sl->ref_list[1][1]);
            }
        }
    } else {
        len  = build_def_list(sl->ref_list[0], FF_ARRAY_ELEMS(sl->ref_list[0]),
                              h->short_ref, h->short_ref_count, 0, h->picture_structure);
        len += build_def_list(sl->ref_list[0] + len,
                              FF_ARRAY_ELEMS(sl->ref_list[0]) - len,
                              h-> long_ref, 16, 1, h->picture_structure);
        av_assert0(len <= 32);

        if (len < sl->ref_count[0])
            memset(&sl->ref_list[0][len], 0, sizeof(H264Ref) * (sl->ref_count[0] - len));
    }

    for (j = 0; j<1+(sl->slice_type_nos == AV_PICTURE_TYPE_B); j++) {
        for (i = 0; i < sl->ref_count[j]; i++) {
            if (sl->ref_list[j][i].parent) {
                if (mismatches_ref(h, sl->ref_list[j][i].parent)) {
                    av_log(h->avctx, AV_LOG_ERROR, "Discarding mismatching reference\n");
                    memset(&sl->ref_list[j][i], 0, sizeof(sl->ref_list[j][i]));
                }
            }
        }
    }
    for (i = 0; i < sl->list_count; i++)
        h->default_ref[i] = sl->ref_list[i][0];
}
Пример #7
0
int ff_h264_fill_default_ref_list(H264Context *h, H264SliceContext *sl)
{
    int i, len;
    int j;

    if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
        H264Picture *sorted[32];
        int cur_poc, list;
        int lens[2];

        if (FIELD_PICTURE(h))
            cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD];
        else
            cur_poc = h->cur_pic_ptr->poc;

        for (list = 0; list < 2; list++) {
            len  = add_sorted(sorted,       h->short_ref, h->short_ref_count, cur_poc, 1 ^ list);
            len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list);
            av_assert0(len <= 32);

            len  = build_def_list(h->default_ref_list[list], FF_ARRAY_ELEMS(h->default_ref_list[0]),
                                  sorted, len, 0, h->picture_structure);
            len += build_def_list(h->default_ref_list[list] + len,
                                  FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
                                  h->long_ref, 16, 1, h->picture_structure);
            av_assert0(len <= 32);

            if (len < sl->ref_count[list])
                memset(&h->default_ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len));
            lens[list] = len;
        }

        if (lens[0] == lens[1] && lens[1] > 1) {
            for (i = 0; i < lens[0] &&
                        h->default_ref_list[0][i].parent->f->buf[0]->buffer ==
                        h->default_ref_list[1][i].parent->f->buf[0]->buffer; i++);
            if (i == lens[0]) {
                FFSWAP(H264Ref, h->default_ref_list[1][0], h->default_ref_list[1][1]);
            }
        }
    } else {
        len  = build_def_list(h->default_ref_list[0], FF_ARRAY_ELEMS(h->default_ref_list[0]),
                              h->short_ref, h->short_ref_count, 0, h->picture_structure);
        len += build_def_list(h->default_ref_list[0] + len,
                              FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
                              h-> long_ref, 16, 1, h->picture_structure);
        av_assert0(len <= 32);

        if (len < sl->ref_count[0])
            memset(&h->default_ref_list[0][len], 0, sizeof(H264Ref) * (sl->ref_count[0] - len));
    }
#ifdef TRACE
    for (i = 0; i < sl->ref_count[0]; i++) {
        ff_tlog(h->avctx, "List0: %s fn:%d 0x%p\n",
                h->default_ref_list[0][i].parent ? (h->default_ref_list[0][i].parent->long_ref ? "LT" : "ST") : "NULL",
                h->default_ref_list[0][i].pic_id,
                h->default_ref_list[0][i].parent ? h->default_ref_list[0][i].parent->f->data[0] : 0);
    }
    if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
        for (i = 0; i < sl->ref_count[1]; i++) {
            ff_tlog(h->avctx, "List1: %s fn:%d 0x%p\n",
                    h->default_ref_list[1][i].parent ? (h->default_ref_list[1][i].parent->long_ref ? "LT" : "ST") : "NULL",
                    h->default_ref_list[1][i].pic_id,
                    h->default_ref_list[1][i].parent ? h->default_ref_list[1][i].parent->f->data[0] : 0);
        }
    }
#endif

    for (j = 0; j<1+(sl->slice_type_nos == AV_PICTURE_TYPE_B); j++) {
        for (i = 0; i < sl->ref_count[j]; i++) {
            if (h->default_ref_list[j][i].parent) {
                if (mismatches_ref(h, h->default_ref_list[j][i].parent)) {
                    av_log(h->avctx, AV_LOG_ERROR, "Discarding mismatching reference\n");
                    memset(&h->default_ref_list[j][i], 0, sizeof(h->default_ref_list[j][i]));
                }
            }
        }
    }

    return 0;
}
Пример #8
0
static int cuvid_h264_start_frame(AVCodecContext *avctx,
                                  const uint8_t *buffer, uint32_t size)
{
    const H264Context *h = avctx->priv_data;
    const PPS *pps = h->ps.pps;
    const SPS *sps = h->ps.sps;

    CUVIDContext       *ctx = avctx->internal->hwaccel_priv_data;
    CUVIDPICPARAMS      *pp = &ctx->pic_params;
    CUVIDH264PICPARAMS *ppc = &pp->CodecSpecific.h264;
    FrameDecodeData *fdd;
    CUVIDFrame *cf;

    int i, dpb_size, ret;

    ret = ff_cuvid_start_frame(avctx, h->cur_pic_ptr->f);
    if (ret < 0)
        return ret;

    fdd = (FrameDecodeData*)h->cur_pic_ptr->f->opaque_ref->data;
    cf  = (CUVIDFrame*)fdd->hwaccel_priv;

    *pp = (CUVIDPICPARAMS) {
        .PicWidthInMbs     = h->mb_width,
        .FrameHeightInMbs  = h->mb_height,
        .CurrPicIdx        = cf->idx,
        .field_pic_flag    = FIELD_PICTURE(h),
        .bottom_field_flag = h->picture_structure == PICT_BOTTOM_FIELD,
        .second_field      = FIELD_PICTURE(h) && !h->first_field,
        .ref_pic_flag      = h->nal_ref_idc != 0,
        .intra_pic_flag    = 0,

        .CodecSpecific.h264 = {
            .log2_max_frame_num_minus4            = sps->log2_max_frame_num - 4,
            .pic_order_cnt_type                   = sps->poc_type,
            .log2_max_pic_order_cnt_lsb_minus4    = FFMAX(sps->log2_max_poc_lsb - 4, 0),
            .delta_pic_order_always_zero_flag     = sps->delta_pic_order_always_zero_flag,
            .frame_mbs_only_flag                  = sps->frame_mbs_only_flag,
            .direct_8x8_inference_flag            = sps->direct_8x8_inference_flag,
            .num_ref_frames                       = sps->ref_frame_count,
            .residual_colour_transform_flag       = sps->residual_color_transform_flag,
            .bit_depth_luma_minus8                = sps->bit_depth_luma - 8,
            .bit_depth_chroma_minus8              = sps->bit_depth_chroma - 8,
            .qpprime_y_zero_transform_bypass_flag = sps->transform_bypass,

            .entropy_coding_mode_flag               = pps->cabac,
            .pic_order_present_flag                 = pps->pic_order_present,
            .num_ref_idx_l0_active_minus1           = pps->ref_count[0] - 1,
            .num_ref_idx_l1_active_minus1           = pps->ref_count[1] - 1,
            .weighted_pred_flag                     = pps->weighted_pred,
            .weighted_bipred_idc                    = pps->weighted_bipred_idc,
            .pic_init_qp_minus26                    = pps->init_qp - 26,
            .deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present,
            .redundant_pic_cnt_present_flag         = pps->redundant_pic_cnt_present,
            .transform_8x8_mode_flag                = pps->transform_8x8_mode,
            .MbaffFrameFlag                         = sps->mb_aff && !FIELD_PICTURE(h),
            .constrained_intra_pred_flag            = pps->constrained_intra_pred,
            .chroma_qp_index_offset                 = pps->chroma_qp_index_offset[0],
            .second_chroma_qp_index_offset          = pps->chroma_qp_index_offset[1],
            .ref_pic_flag                           = h->nal_ref_idc != 0,
            .frame_num                              = h->poc.frame_num,
            .CurrFieldOrderCnt[0]                   = h->cur_pic_ptr->field_poc[0],
            .CurrFieldOrderCnt[1]                   = h->cur_pic_ptr->field_poc[1],
        },
    };

    memcpy(ppc->WeightScale4x4,    pps->scaling_matrix4,    sizeof(ppc->WeightScale4x4));
    memcpy(ppc->WeightScale8x8[0], pps->scaling_matrix8[0], sizeof(ppc->WeightScale8x8[0]));
    memcpy(ppc->WeightScale8x8[1], pps->scaling_matrix8[3], sizeof(ppc->WeightScale8x8[0]));

    dpb_size = 0;
    for (i = 0; i < h->short_ref_count; i++)
        dpb_add(h, &ppc->dpb[dpb_size++], h->short_ref[i], h->short_ref[i]->frame_num);
    for (i = 0; i < 16; i++) {
        if (h->long_ref[i])
            dpb_add(h, &ppc->dpb[dpb_size++], h->long_ref[i], i);
    }

    for (i = dpb_size; i < FF_ARRAY_ELEMS(ppc->dpb); i++)
        ppc->dpb[i].PicIdx = -1;

    return 0;
}
Пример #9
0
int ff_h264_decode_ref_pic_marking(H264SliceContext *sl, GetBitContext *gb,
                                   const H2645NAL *nal, void *logctx)
{
    int i;
    MMCO *mmco = sl->mmco;
    int nb_mmco = 0;

    if (nal->type == H264_NAL_IDR_SLICE) { // FIXME fields
        skip_bits1(gb); // broken_link
        if (get_bits1(gb)) {
            mmco[0].opcode   = MMCO_LONG;
            mmco[0].long_arg = 0;
            nb_mmco          = 1;
        }
        sl->explicit_ref_marking = 1;
    } else {
        sl->explicit_ref_marking = get_bits1(gb);
        if (sl->explicit_ref_marking) {
            for (i = 0; i < MAX_MMCO_COUNT; i++) {
                MMCOOpcode opcode = get_ue_golomb_31(gb);

                mmco[i].opcode = opcode;
                if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG) {
                    mmco[i].short_pic_num =
                        (sl->curr_pic_num - get_ue_golomb_long(gb) - 1) &
                            (sl->max_pic_num - 1);
#if 0
                    if (mmco[i].short_pic_num >= h->short_ref_count ||
                        !h->short_ref[mmco[i].short_pic_num]) {
                        av_log(s->avctx, AV_LOG_ERROR,
                               "illegal short ref in memory management control "
                               "operation %d\n", mmco);
                        return -1;
                    }
#endif
                }
                if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED ||
                    opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG) {
                    unsigned int long_arg = get_ue_golomb_31(gb);
                    if (long_arg >= 32 ||
                        (long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG &&
                                             long_arg == 16) &&
                         !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE(sl)))) {
                        av_log(logctx, AV_LOG_ERROR,
                               "illegal long ref in memory management control "
                               "operation %d\n", opcode);
                        return -1;
                    }
                    mmco[i].long_arg = long_arg;
                }

                if (opcode > (unsigned) MMCO_LONG) {
                    av_log(logctx, AV_LOG_ERROR,
                           "illegal memory management control operation %d\n",
                           opcode);
                    return -1;
                }
                if (opcode == MMCO_END)
                    break;
            }
            nb_mmco = i;
        }
    }

    sl->nb_mmco = nb_mmco;

    return 0;
}