FFMPEG Intro - AvCodecContext time_base Set

来源:互联网 发布:不想上班 知乎 编辑:程序博客网 时间:2024/09/21 09:02




static inline int decode_vui_parameters(H264Context *h, SPS *sps)
{
    int aspect_ratio_info_present_flag;
    unsigned int aspect_ratio_idc;

    aspect_ratio_info_present_flag = get_bits1(&h->gb);

    if (aspect_ratio_info_present_flag) {
        aspect_ratio_idc = get_bits(&h->gb, 8);
        if (aspect_ratio_idc == EXTENDED_SAR) {
            sps->sar.num = get_bits(&h->gb, 16);
            sps->sar.den = get_bits(&h->gb, 16);
        } else if (aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)) {
            sps->sar = pixel_aspect[aspect_ratio_idc];
        } else {
            av_log(h->avctx, AV_LOG_ERROR, "illegal aspect ratio\n");
            return AVERROR_INVALIDDATA;
        }
    } else {
        sps->sar.num =
        sps->sar.den = 0;
    }

    if (get_bits1(&h->gb))      /* overscan_info_present_flag */
        get_bits1(&h->gb);      /* overscan_appropriate_flag */

    sps->video_signal_type_present_flag = get_bits1(&h->gb);
    if (sps->video_signal_type_present_flag) {
        get_bits(&h->gb, 3);                 /* video_format */
        sps->full_range = get_bits1(&h->gb); /* video_full_range_flag */

        sps->colour_description_present_flag = get_bits1(&h->gb);
        if (sps->colour_description_present_flag) {
            sps->color_primaries = get_bits(&h->gb, 8); /* colour_primaries */
            sps->color_trc       = get_bits(&h->gb, 8); /* transfer_characteristics */
            sps->colorspace      = get_bits(&h->gb, 8); /* matrix_coefficients */
            if (sps->color_primaries >= AVCOL_PRI_NB)
                sps->color_primaries = AVCOL_PRI_UNSPECIFIED;
            if (sps->color_trc >= AVCOL_TRC_NB)
                sps->color_trc = AVCOL_TRC_UNSPECIFIED;
            if (sps->colorspace >= AVCOL_SPC_NB)
                sps->colorspace = AVCOL_SPC_UNSPECIFIED;
        }
    }

    /* chroma_location_info_present_flag */
    if (get_bits1(&h->gb)) {
        /* chroma_sample_location_type_top_field */
        h->avctx->chroma_sample_location = get_ue_golomb(&h->gb) + 1;
        get_ue_golomb(&h->gb);  /* chroma_sample_location_type_bottom_field */
    }

    if (show_bits1(&h->gb) && get_bits_left(&h->gb) < 10) {
        av_log(h->avctx, AV_LOG_WARNING, "Truncated VUI\n");
        return 0;
    }

    sps->timing_info_present_flag = get_bits1(&h->gb);
    if (sps->timing_info_present_flag) {

        // sps->num_units_in_tick will be set to time_base.num of AvCodecContext

        // sps->time_scale will be set to time_base.den of AvCodecContext

        // see h264_slice_header_init function below
       

        sps->num_units_in_tick = get_bits_long(&h->gb, 32);
        sps->time_scale        = get_bits_long(&h->gb, 32);


        if (!sps->num_units_in_tick || !sps->time_scale) {
            av_log(h->avctx, AV_LOG_ERROR,
                   "time_scale/num_units_in_tick invalid or unsupported (%"PRIu32"/%"PRIu32")\n",
                   sps->time_scale, sps->num_units_in_tick);
            return AVERROR_INVALIDDATA;
        }
        sps->fixed_frame_rate_flag = get_bits1(&h->gb);
    }

    sps->nal_hrd_parameters_present_flag = get_bits1(&h->gb);
    if (sps->nal_hrd_parameters_present_flag)
        if (decode_hrd_parameters(h, sps) < 0)
            return AVERROR_INVALIDDATA;
    sps->vcl_hrd_parameters_present_flag = get_bits1(&h->gb);
    if (sps->vcl_hrd_parameters_present_flag)
        if (decode_hrd_parameters(h, sps) < 0)
            return AVERROR_INVALIDDATA;
    if (sps->nal_hrd_parameters_present_flag ||
        sps->vcl_hrd_parameters_present_flag)
        get_bits1(&h->gb);     /* low_delay_hrd_flag */
    sps->pic_struct_present_flag = get_bits1(&h->gb);
    if (!get_bits_left(&h->gb))
        return 0;
    sps->bitstream_restriction_flag = get_bits1(&h->gb);
    if (sps->bitstream_restriction_flag) {
        get_bits1(&h->gb);     /* motion_vectors_over_pic_boundaries_flag */
        get_ue_golomb(&h->gb); /* max_bytes_per_pic_denom */
        get_ue_golomb(&h->gb); /* max_bits_per_mb_denom */
        get_ue_golomb(&h->gb); /* log2_max_mv_length_horizontal */
        get_ue_golomb(&h->gb); /* log2_max_mv_length_vertical */
        sps->num_reorder_frames = get_ue_golomb(&h->gb);
        get_ue_golomb(&h->gb); /*max_dec_frame_buffering*/

        if (get_bits_left(&h->gb) < 0) {
            sps->num_reorder_frames         = 0;
            sps->bitstream_restriction_flag = 0;
        }

        if (sps->num_reorder_frames > 16U
            /* max_dec_frame_buffering || max_dec_frame_buffering > 16 */) {
            av_log(h->avctx, AV_LOG_ERROR,
                   "Clipping illegal num_reorder_frames %d\n",
                   sps->num_reorder_frames);
            sps->num_reorder_frames = 16;
            return AVERROR_INVALIDDATA;
        }
    }

    if (get_bits_left(&h->gb) < 0) {
        av_log(h->avctx, AV_LOG_ERROR,
               "Overread VUI by %d bits\n", -get_bits_left(&h->gb));
        return AVERROR_INVALIDDATA;
    }

    return 0;
}



static int h264_slice_header_init(H264Context *h, int reinit)
{
    int nb_slices = (HAVE_THREADS &&
                     h->avctx->active_thread_type & FF_THREAD_SLICE) ?
                    h->avctx->thread_count : 1;
    int i, ret;
    ff_set_sar(h->avctx, h->sps.sar);
    av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt,
                                     &h->chroma_x_shift, &h->chroma_y_shift);
    if (h->sps.timing_info_present_flag) {
        int64_t den = h->sps.time_scale;
        if (h->x264_build < 44U)
            den *= 2;
        av_reduce(&h->avctx->time_base.num, &h->avctx->time_base.den,
                  h->sps.num_units_in_tick, den, 1 << 30);
    }
    if (reinit)
        ff_h264_free_tables(h, 0);
    h->first_field           = 0;
    h->prev_interlaced_frame = 1;
    init_scan_tables(h);
    ret = ff_h264_alloc_tables(h);
    if (ret < 0) {
        av_log(h->avctx, AV_LOG_ERROR, "Could not allocate memory\n");
        return ret;
    }
    if (nb_slices > H264_MAX_THREADS || (nb_slices > h->mb_height && h->mb_height)) {
        int max_slices;
        if (h->mb_height)
            max_slices = FFMIN(H264_MAX_THREADS, h->mb_height);
        else
            max_slices = H264_MAX_THREADS;
        av_log(h->avctx, AV_LOG_WARNING, "too many threads/slices %d,"
               " reducing to %d\n", nb_slices, max_slices);
        nb_slices = max_slices;
    }
    h->slice_context_count = nb_slices;
    if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_SLICE)) {
        ret = ff_h264_context_init(h);
        if (ret < 0) {
            av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
            return ret;
        }
    } else {
        for (i = 1; i < h->slice_context_count; i++) {
            H264Context *c;
            c                    = h->thread_context[i] = av_mallocz(sizeof(H264Context));
            if (!c)
                return AVERROR(ENOMEM);
            c->avctx             = h->avctx;
            if (CONFIG_ERROR_RESILIENCE) {
                c->dsp               = h->dsp;
            }
            c->vdsp              = h->vdsp;
            c->h264dsp           = h->h264dsp;
            c->h264qpel          = h->h264qpel;
            c->h264chroma        = h->h264chroma;
            c->sps               = h->sps;
            c->pps               = h->pps;
            c->pixel_shift       = h->pixel_shift;
            c->cur_chroma_format_idc = h->cur_chroma_format_idc;
            c->width             = h->width;
            c->height            = h->height;
            c->linesize          = h->linesize;
            c->uvlinesize        = h->uvlinesize;
            c->chroma_x_shift    = h->chroma_x_shift;
            c->chroma_y_shift    = h->chroma_y_shift;
            c->qscale            = h->qscale;
            c->droppable         = h->droppable;
            c->data_partitioning = h->data_partitioning;
            c->low_delay         = h->low_delay;
            c->mb_width          = h->mb_width;
            c->mb_height         = h->mb_height;
            c->mb_stride         = h->mb_stride;
            c->mb_num            = h->mb_num;
            c->flags             = h->flags;
            c->workaround_bugs   = h->workaround_bugs;
            c->pict_type         = h->pict_type;
            init_scan_tables(c);
            clone_tables(c, h, i);
            c->context_initialized = 1;
        }
        for (i = 0; i < h->slice_context_count; i++)
            if ((ret = ff_h264_context_init(h->thread_context[i])) < 0) {
                av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
                return ret;
            }
    }
    h->context_initialized = 1;
    return 0;
}


0 1
原创粉丝点击