⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpeg12enc.c

📁 ffmpeg的完整源代码和作者自己写的文档。不但有在Linux的工程哦
💻 C
📖 第 1 页 / 共 3 页
字号:
{
    if(s->q_scale_type){
        assert(s->qscale>=1 && s->qscale <=12);
        put_bits(&s->pb, 5, inv_non_linear_qscale[s->qscale]);
    }else{
        put_bits(&s->pb, 5, s->qscale);
    }
}

void ff_mpeg1_encode_slice_header(MpegEncContext *s){
    put_header(s, SLICE_MIN_START_CODE + s->mb_y);
    put_qscale(s);
    put_bits(&s->pb, 1, 0); /* slice extra information */
}

void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
{
    mpeg1_encode_sequence_header(s);

    /* mpeg1 picture header */
    put_header(s, PICTURE_START_CODE);
    /* temporal reference */

    // RAL: s->picture_number instead of s->fake_picture_number
    put_bits(&s->pb, 10, (s->picture_number -
                          s->gop_picture_number) & 0x3ff);
    put_bits(&s->pb, 3, s->pict_type);

    s->vbv_delay_ptr= s->pb.buf + put_bits_count(&s->pb)/8;
    put_bits(&s->pb, 16, 0xFFFF); /* vbv_delay */

    // RAL: Forward f_code also needed for B frames
    if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) {
        put_bits(&s->pb, 1, 0); /* half pel coordinates */
        if(s->codec_id == CODEC_ID_MPEG1VIDEO)
            put_bits(&s->pb, 3, s->f_code); /* forward_f_code */
        else
            put_bits(&s->pb, 3, 7); /* forward_f_code */
    }

    // RAL: Backward f_code necessary for B frames
    if (s->pict_type == B_TYPE) {
        put_bits(&s->pb, 1, 0); /* half pel coordinates */
        if(s->codec_id == CODEC_ID_MPEG1VIDEO)
            put_bits(&s->pb, 3, s->b_code); /* backward_f_code */
        else
            put_bits(&s->pb, 3, 7); /* backward_f_code */
    }

    put_bits(&s->pb, 1, 0); /* extra bit picture */

    s->frame_pred_frame_dct = 1;
    if(s->codec_id == CODEC_ID_MPEG2VIDEO){
        put_header(s, EXT_START_CODE);
        put_bits(&s->pb, 4, 8); //pic ext
        if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) {
            put_bits(&s->pb, 4, s->f_code);
            put_bits(&s->pb, 4, s->f_code);
        }else{
            put_bits(&s->pb, 8, 255);
        }
        if (s->pict_type == B_TYPE) {
            put_bits(&s->pb, 4, s->b_code);
            put_bits(&s->pb, 4, s->b_code);
        }else{
            put_bits(&s->pb, 8, 255);
        }
        put_bits(&s->pb, 2, s->intra_dc_precision);

        assert(s->picture_structure == PICT_FRAME);
        put_bits(&s->pb, 2, s->picture_structure);
        if (s->progressive_sequence) {
            put_bits(&s->pb, 1, 0); /* no repeat */
        } else {
            put_bits(&s->pb, 1, s->current_picture_ptr->top_field_first);
        }
        /* XXX: optimize the generation of this flag with entropy
           measures */
        s->frame_pred_frame_dct = s->progressive_sequence;

        put_bits(&s->pb, 1, s->frame_pred_frame_dct);
        put_bits(&s->pb, 1, s->concealment_motion_vectors);
        put_bits(&s->pb, 1, s->q_scale_type);
        put_bits(&s->pb, 1, s->intra_vlc_format);
        put_bits(&s->pb, 1, s->alternate_scan);
        put_bits(&s->pb, 1, s->repeat_first_field);
        s->progressive_frame = s->progressive_sequence;
        put_bits(&s->pb, 1, s->chroma_format == CHROMA_420 ? s->progressive_frame : 0); /* chroma_420_type */
        put_bits(&s->pb, 1, s->progressive_frame);
        put_bits(&s->pb, 1, 0); //composite_display_flag
    }
    if(s->flags & CODEC_FLAG_SVCD_SCAN_OFFSET){
        int i;

        put_header(s, USER_START_CODE);
        for(i=0; i<sizeof(svcd_scan_offset_placeholder); i++){
            put_bits(&s->pb, 8, svcd_scan_offset_placeholder[i]);
        }
    }

    s->mb_y=0;
    ff_mpeg1_encode_slice_header(s);
}

static inline void put_mb_modes(MpegEncContext *s, int n, int bits,
                                int has_mv, int field_motion)
{
    put_bits(&s->pb, n, bits);
    if (!s->frame_pred_frame_dct) {
        if (has_mv)
            put_bits(&s->pb, 2, 2 - field_motion); /* motion_type: frame/field */
        put_bits(&s->pb, 1, s->interlaced_dct);
    }
}

static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s,
                                                   DCTELEM block[6][64],
                                                   int motion_x, int motion_y,
                                                   int mb_block_count)
{
    int i, cbp;
    const int mb_x = s->mb_x;
    const int mb_y = s->mb_y;
    const int first_mb= mb_x == s->resync_mb_x && mb_y == s->resync_mb_y;

    /* compute cbp */
    cbp = 0;
    for(i=0;i<mb_block_count;i++) {
        if (s->block_last_index[i] >= 0)
            cbp |= 1 << (mb_block_count - 1 - i);
    }

    if (cbp == 0 && !first_mb && s->mv_type == MV_TYPE_16X16 &&
        (mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) &&
        ((s->pict_type == P_TYPE && (motion_x | motion_y) == 0) ||
        (s->pict_type == B_TYPE && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) |
        ((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) {
        s->mb_skip_run++;
        s->qscale -= s->dquant;
        s->skip_count++;
        s->misc_bits++;
        s->last_bits++;
        if(s->pict_type == P_TYPE){
            s->last_mv[0][1][0]= s->last_mv[0][0][0]=
            s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0;
        }
    } else {
        if(first_mb){
            assert(s->mb_skip_run == 0);
            encode_mb_skip_run(s, s->mb_x);
        }else{
            encode_mb_skip_run(s, s->mb_skip_run);
        }

        if (s->pict_type == I_TYPE) {
            if(s->dquant && cbp){
                put_mb_modes(s, 2, 1, 0, 0); /* macroblock_type : macroblock_quant = 1 */
                put_qscale(s);
            }else{
                put_mb_modes(s, 1, 1, 0, 0); /* macroblock_type : macroblock_quant = 0 */
                s->qscale -= s->dquant;
            }
            s->misc_bits+= get_bits_diff(s);
            s->i_count++;
        } else if (s->mb_intra) {
            if(s->dquant && cbp){
                put_mb_modes(s, 6, 0x01, 0, 0);
                put_qscale(s);
            }else{
                put_mb_modes(s, 5, 0x03, 0, 0);
                s->qscale -= s->dquant;
            }
            s->misc_bits+= get_bits_diff(s);
            s->i_count++;
            memset(s->last_mv, 0, sizeof(s->last_mv));
        } else if (s->pict_type == P_TYPE) {
            if(s->mv_type == MV_TYPE_16X16){
                if (cbp != 0) {
                    if ((motion_x|motion_y) == 0) {
                        if(s->dquant){
                            put_mb_modes(s, 5, 1, 0, 0); /* macroblock_pattern & quant */
                            put_qscale(s);
                        }else{
                            put_mb_modes(s, 2, 1, 0, 0); /* macroblock_pattern only */
                        }
                        s->misc_bits+= get_bits_diff(s);
                    } else {
                        if(s->dquant){
                            put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */
                            put_qscale(s);
                        }else{
                            put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */
                        }
                        s->misc_bits+= get_bits_diff(s);
                        mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code);    // RAL: f_code parameter added
                        mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code);    // RAL: f_code parameter added
                        s->mv_bits+= get_bits_diff(s);
                    }
                } else {
                    put_bits(&s->pb, 3, 1); /* motion only */
                    if (!s->frame_pred_frame_dct)
                        put_bits(&s->pb, 2, 2); /* motion_type: frame */
                    s->misc_bits+= get_bits_diff(s);
                    mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code);    // RAL: f_code parameter added
                    mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code);    // RAL: f_code parameter added
                    s->qscale -= s->dquant;
                    s->mv_bits+= get_bits_diff(s);
                }
                s->last_mv[0][1][0]= s->last_mv[0][0][0]= motion_x;
                s->last_mv[0][1][1]= s->last_mv[0][0][1]= motion_y;
            }else{
                assert(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD);

                if (cbp) {
                    if(s->dquant){
                        put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */
                        put_qscale(s);
                    }else{
                        put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */
                    }
                } else {
                    put_bits(&s->pb, 3, 1); /* motion only */
                    put_bits(&s->pb, 2, 1); /* motion_type: field */
                    s->qscale -= s->dquant;
                }
                s->misc_bits+= get_bits_diff(s);
                for(i=0; i<2; i++){
                    put_bits(&s->pb, 1, s->field_select[0][i]);
                    mpeg1_encode_motion(s, s->mv[0][i][0] -  s->last_mv[0][i][0]    , s->f_code);
                    mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code);
                    s->last_mv[0][i][0]=   s->mv[0][i][0];
                    s->last_mv[0][i][1]= 2*s->mv[0][i][1];
                }
                s->mv_bits+= get_bits_diff(s);
            }
            if(cbp) {
                if (s->chroma_y_shift) {
                    put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp][1], ff_mpeg12_mbPatTable[cbp][0]);
                } else {
                    put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp>>2][1], ff_mpeg12_mbPatTable[cbp>>2][0]);
                    put_bits(&s->pb, 2, cbp & 3);
                }
            }
            s->f_count++;
        } else{
            if(s->mv_type == MV_TYPE_16X16){
                if (cbp){    // With coded bloc pattern
                    if (s->dquant) {
                        if(s->mv_dir == MV_DIR_FORWARD)
                            put_mb_modes(s, 6, 3, 1, 0);
                        else
                            put_mb_modes(s, 8-s->mv_dir, 2, 1, 0);
                        put_qscale(s);
                    } else {
                        put_mb_modes(s, 5-s->mv_dir, 3, 1, 0);
                    }
                }else{    // No coded bloc pattern
                    put_bits(&s->pb, 5-s->mv_dir, 2);
                    if (!s->frame_pred_frame_dct)
                        put_bits(&s->pb, 2, 2); /* motion_type: frame */
                    s->qscale -= s->dquant;
                }
                s->misc_bits += get_bits_diff(s);
                if (s->mv_dir&MV_DIR_FORWARD){
                    mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code);
                    mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
                    s->last_mv[0][0][0]=s->last_mv[0][1][0]= s->mv[0][0][0];
                    s->last_mv[0][0][1]=s->last_mv[0][1][1]= s->mv[0][0][1];
                    s->f_count++;
                }
                if (s->mv_dir&MV_DIR_BACKWARD){
                    mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code);
                    mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
                    s->last_mv[1][0][0]=s->last_mv[1][1][0]= s->mv[1][0][0];
                    s->last_mv[1][0][1]=s->last_mv[1][1][1]= s->mv[1][0][1];
                    s->b_count++;
                }
            }else{
                assert(s->mv_type == MV_TYPE_FIELD);
                assert(!s->frame_pred_frame_dct);
                if (cbp){    // With coded bloc pattern
                    if (s->dquant) {
                        if(s->mv_dir == MV_DIR_FORWARD)
                            put_mb_modes(s, 6, 3, 1, 1);
                        else
                            put_mb_modes(s, 8-s->mv_dir, 2, 1, 1);
                        put_qscale(s);
                    } else {
                        put_mb_modes(s, 5-s->mv_dir, 3, 1, 1);
                    }
                }else{    // No coded bloc pattern
                    put_bits(&s->pb, 5-s->mv_dir, 2);
                    put_bits(&s->pb, 2, 1); /* motion_type: field */
                    s->qscale -= s->dquant;
                }
                s->misc_bits += get_bits_diff(s);
                if (s->mv_dir&MV_DIR_FORWARD){
                    for(i=0; i<2; i++){
                        put_bits(&s->pb, 1, s->field_select[0][i]);
                        mpeg1_encode_motion(s, s->mv[0][i][0] -  s->last_mv[0][i][0]    , s->f_code);
                        mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code);
                        s->last_mv[0][i][0]=   s->mv[0][i][0];
                        s->last_mv[0][i][1]= 2*s->mv[0][i][1];
                    }
                    s->f_count++;
                }
                if (s->mv_dir&MV_DIR_BACKWARD){
                    for(i=0; i<2; i++){
                        put_bits(&s->pb, 1, s->field_select[1][i]);
                        mpeg1_encode_motion(s, s->mv[1][i][0] -  s->last_mv[1][i][0]    , s->b_code);
                        mpeg1_encode_motion(s, s->mv[1][i][1] - (s->last_mv[1][i][1]>>1), s->b_code);
                        s->last_mv[1][i][0]=   s->mv[1][i][0];
                        s->last_mv[1][i][1]= 2*s->mv[1][i][1];
                    }
                    s->b_count++;
                }
            }
            s->mv_bits += get_bits_diff(s);
            if(cbp) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -