X264代码学习(五)

1. x264_encoder_encode( x264_t *h,  x264_nal_t **pp_nal, int *pi_nal,

                                           x264_picture_t *pic_in,   x264_picture_t *pic_out )          //encoder.c中

  (1)x264_frame_t   *frame_psnr = h->fdec; // just to keep the current decoded frame for psnr calculation

    (2)  x264_frame_t *fenc = x264_frame_get( h->frames.unused );//返回h->frames.unused[0]的值,即得到了一幀图像给编码器fenc, x264_frame_get函数在encoder.c中,原型为:

static x264_frame_t *x264_frame_get( x264_frame_t *list[X264_BFRAME_MAX+1] )
{
    x264_frame_t *frame = list[0];
    int i;
    for( i = 0; list[i]; i++ )
        list[i] = list[i+1];
    return frame;
}

    (3)  x264_frame_copy_picture( h, fenc, pic_in );   //  pic_in复制到 fenc ,把要编码的帧存放到 fenc

该函数在frame.c中,原型为:

void x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
{
    dst->i_type     = src->i_type;
    dst->i_qpplus1  = src->i_qpplus1;
    dst->i_pts      = src->i_pts;

    switch( src->img.i_csp & X264_CSP_MASK )
    {
        case X264_CSP_I420:
            h->csp.i420( dst, &src->img, h->param.i_width, h->param.i_height );
            break;
        ....

        default:
            x264_log( h, X264_LOG_ERROR, "Arg invalid CSP\n" );
            break;
    }
}

(4) if( h->param.i_width % 16 || h->param.i_height % 16 )      x264_frame_expand_border_mod16( h, fenc );

      fenc->i_frame = h->frames.i_input++;

//若图像宽或高不是16的整数倍,调用 x264_frame_expand_border_mod16( h, fenc );

x264_frame_put( h->frames.next, fenc );//将fenc拷贝给h->frames.next数组中第一个不为0的位置,该函数在encoder.c中,原型为:

static void x264_frame_put( x264_frame_t *list[X264_BFRAME_MAX], x264_frame_t *frame )
{
    int i = 0;
    while( list[i] ) i++;
    list[i] = frame;
}

(5)x264_slicetype_decide( h );      //判断slice的类型,在slicetype_decision.c中,如下:

void x264_slicetype_decide( x264_t *h )
{
    ...

    if( h->param.rc.b_stat_read )
    {
        /* Use the frame types from the first pass */
        for( i = 0; h->frames.next[i] != NULL; i++ )
            h->frames.next[i]->i_type =
                x264_ratecontrol_slice_type( h, h->frames.next[i]->i_frame );
    }
    else if( h->param.i_bframe && h->param.b_bframe_adaptive )
        x264_slicetype_analyse( h );//x264_slicetype_analyse函数在slicetype_decision.c中。

        //这里要注意默认的x264里面是没有B帧的,如果需要用到B帧可以在最初的参数设置的时候,

        //用语句“--frames 数字”来定义,x264_slicetype_analyse 也只有在定义了“--frames 数字”时候,

        //才会执行。

    ...
}

(6)   /*  move some B-frames and 1 non-B to encode queue */

       while( IS_X264_TYPE_B( h->frames.next[bframes]->i_type ) )
            bframes++;
        x264_frame_put( h->frames.current, x264_frame_get( &h->frames.next[bframes] ) );

//将当前要编码的帧h->frames.current送给编码器,然后开始编码

(7)  h->fenc = x264_frame_get( h->frames.current );//将当前要编码的帧给编码器

(8)   if( h->fenc->i_type == X264_TYPE_IDR )
    {
        h->frames.i_last_idr = h->fenc->i_frame;
    }

TIMER_START( i_mtime_encode_frame );

// 如果是解码即时刷新片,则h->frames.i_last_idr = h->fenc->i_frame;然后计时开

(9)if( h->fenc->i_type == X264_TYPE_IDR )
    {
        /* reset ref pictures */
        x264_reference_reset( h );

        i_nal_type    = NAL_SLICE_IDR;
        i_nal_ref_idc = NAL_PRIORITY_HIGHEST;
        i_slice_type = SLICE_TYPE_I;
    }
    else if( h->fenc->i_type == X264_TYPE_I )
    {
        i_nal_type    = NAL_SLICE;
        i_nal_ref_idc = NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/
        i_slice_type = SLICE_TYPE_I;
    }
    else if( h->fenc->i_type == X264_TYPE_P )
    {
        i_nal_type    = NAL_SLICE;
        i_nal_ref_idc = NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/
        i_slice_type = SLICE_TYPE_P;
    }
    else if( h->fenc->i_type == X264_TYPE_BREF )
    {
        i_nal_type    = NAL_SLICE;
        i_nal_ref_idc = NAL_PRIORITY_HIGH; /* maybe add MMCO to forget it? -> low */
        i_slice_type = SLICE_TYPE_B;
    }
    else    /* B frame */
    {
        i_nal_type    = NAL_SLICE;
        i_nal_ref_idc = NAL_PRIORITY_DISPOSABLE;
        i_slice_type = SLICE_TYPE_B;
    }

//根据帧的类型初始化数据。总共有五种片的类型IDR,I,P,BREF,B 。如果是解码即时刷新片(idr),则要对参考帧重新设置
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值