X264中的x264_encoder_encode和x264_nal_encode函数

函数原型:

<span style="font-size:18px;">int     x264_encoder_encode( x264_t *h,  
                             x264_nal_t **pp_nal, int *pi_nal,  
                             x264_picture_t *pic_in,  
                             x264_picture_t *pic_out )  </span>

具体的调用例子:

<span style="font-size:18px;">            if( x264_encoder_encode( p264Handle, &p264Nal, &i264Nal, p264Pic ,&pic_out) < 0 )
            {
                fprintf( stderr, "x264_encoder_encode failed/n" );
            }</span>
其中, i264Nal为调用一次 x264_encoder_encode 获得到的NAL单元个数。p264为NAL的首地址。所以需要对每个NAL单元编码。会调用到x264_nal_encode函数。

<span style="font-size:18px;">           for( int i = 0; i < i264Nal; i++ ) //循环获取每个NAL
            {
                int i_size;
                int i_data;  //该变量记录每个NAL的字节数
                i_data = 1024*32;
                if( ( i_size = x264_nal_encode( pNal, &i_data, 1, &p264Nal[i] ) ) > 0 ) //pNal指向每个解码后NAL的指针。
                {
                    if ((pNal[4]&0x60)==0)
                    {
                        continue;
                    }
                    if (pNal[4]==0x67)  //SPS包
                    {
                        continue;
                    }
                    if (pNal[4]==0x68)  //PPS包
                    {
                        continue;
                    }
                    memmove(pNal,pNal+4,i_size-4); //头4个字节为0.
                    pNal+=i_size-4;
                }
                else if( i_size < 0 )
                {
                    fprintf( stderr,"need to increase buffer size (size=%d)/n", -i_size );
                }
            }</span>


x264_nal_encode的函数原型:

<span style="font-size:18px;"> * x264_nal_encode: 
 * x264_nal_encode( mux_buffer, &i_size, 1, &nal[i] ); 
 ****************************************************************************/  
int x264_nal_encode( void *p_data, int *pi_data, int b_annexeb, x264_nal_t *nal )  
{  
    uint8_t *dst = p_data;/*nal首地址*/  
    uint8_t *src = nal->p_payload;/*裸数据的首地址*/  
    uint8_t *end = &nal->p_payload[nal->i_payload];/*下一个裸数据的首地址,-> 和 [] 属于同一优先级,从左到右结合*/  
    int i_count = 0;  
  
    /* FIXME this code doesn't check overflow */  
  
    if( b_annexeb )/*H.264附录B中的方案,此处b_annexeb一直取1,利用RTP打包时去掉下面4个字节的start_code,但在存储介质上时,由于NAL 
                   是依次紧密排列的,解码器将无法在数据流中分辨出每个NAL的起始位置和终止位置,故而采用了start_code*/  
    {  
        /* long nal start code (we always use long ones)*/  
        *dst++ = 0x00;  
        *dst++ = 0x00;  
        *dst++ = 0x00;  
        *dst++ = 0x01;  
    }  
  
    /* nal header */  
    *dst++ = ( 0x00 << 7 ) | ( nal->i_ref_idc << 5 ) | nal->i_type;/*第一个字节*/  
  
    while( src < end )  
    {  
        if( i_count == 2 && *src <= 0x03 )  
        {  
            *dst++ = 0x03;  
            i_count = 0;  
        }  
        if( *src == 0 )/*如果遇到数据中有0x00的,则i_cout++,直到检测到2次0x00,则在其后面添加03以防止与起始码竞争*/  
            i_count++;  
        else  
            i_count = 0;  
        *dst++ = *src++;  
    }  
    *pi_data = dst - (uint8_t*)p_data;/*p_data为nal的首地址,最后pi_data记录的是整个nal的字节数*/  
  
    return *pi_data;  
}  </span>


也可以不调用系统函数自己实现:

<span style="font-size:18px;">static int encode_nals (Ctx *c, x264_nal_t *nals, int nal_cnt)
{
	char *pout = (char*)c->output;
	c->output_datasize = 0;
	for (int i = 0; i < nal_cnt; i++) 
	{
		if (c->output_datasize + nals[i].i_payload > c->output_bufsize) 
		{
			// 扩展
			c->output_bufsize = (c->output_datasize+nals[i].i_payload+4095)/4096*4096;
			c->output = realloc(c->output, c->output_bufsize);
		}
		memcpy(pout+c->output_datasize, nals[i].p_payload, nals[i].i_payload);
		c->output_datasize += nals[i].i_payload;
	}

	return c->output_datasize;
}</span>



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值