x264代码剖析(九):x264_encoder_encode()函数之x264_slice's'_write()函数

x264代码剖析(九):x264_encoder_encode()函数之x264_slice's'_write()函数

 

        x264_encoder_encode()函数的核心函数就是x264_slices_write()函数。在x264_slices_write()函数中,最主要的工作就是调用了x264_slice_write()函数(注意“x264_slices_write()”“x264_slice_write()”名字差了一个“s”,x264_slice_write()函数才是真正完成编码的核心函数,如下图所示。




1x264_slices_write()函数

 

        在x264_slices_write()函数中,最主要的工作就是调用了x264_slice_write()函数,需要注意,x264_slices_write()调用了x264_slice_write()。其中x264_slices_write()的单位为帧,而x264_slice_write()的单位为Slice。最常见的情况下一个帧里面只有一个Slice,但是也有可能一个帧里面有多个Slice对应的代码如下:


/******************************************************************/
/******************************************************************/
/*
======Analysed by RuiDong Fang
======Csdn Blog:http://blog.csdn.net/frd2009041510
======Date:2016.03.10
 */
/******************************************************************/
/******************************************************************/

/************====== x264_slices_write()函数 ======************/
/*
功能:编码数据(最关键的步骤),其中调用了x264_slice_write()完成了编码的工作
(注意“x264_slices_write()”和“x264_slice_write()”名字差了一个“s”)。
*/
static void *x264_slices_write( x264_t *h )
{
    int i_slice_num = 0;
    int last_thread_mb = h->sh.i_last_mb;

    /* init stats */
    memset( &h->stat.frame, 0, sizeof(h->stat.frame) );
    h->mb.b_reencode_mb = 0;

	//循环每一个slice(一幅图像可以由多个Slice构成)
    while( h->sh.i_first_mb + SLICE_MBAFF*h->mb.i_mb_stride <= last_thread_mb )
    {
        h->sh.i_last_mb = last_thread_mb;
        if( !i_slice_num || !x264_frame_new_slice( h, h->fdec ) )
        {
            if( h->param.i_slice_max_mbs )
            {
                if( SLICE_MBAFF )
                {
                    // convert first to mbaff form, add slice-max-mbs, then convert back to normal form
                    int last_mbaff = 2*(h->sh.i_first_mb % h->mb.i_mb_width)
                        + h->mb.i_mb_width*(h->sh.i_first_mb / h->mb.i_mb_width)
                        + h->param.i_slice_max_mbs - 1;
                    int last_x = (last_mbaff % (2*h->mb.i_mb_width))/2;
                    int last_y = (last_mbaff / (2*h->mb.i_mb_width))*2 + 1;
                    h->sh.i_last_mb = last_x + h->mb.i_mb_stride*last_y;
                }
                else
                {
                    h->sh.i_last_mb = h->sh.i_first_mb + h->param.i_slice_max_mbs - 1;
                    if( h->sh.i_last_mb < last_thread_mb && last_thread_mb - h->sh.i_last_mb < h->param.i_slice_min_mbs )
                        h->sh.i_last_mb = last_thread_mb - h->param.i_slice_min_mbs;
                }
                i_slice_num++;
            }
            else if( h->param.i_slice_count && !h->param.b_sliced_threads )
            {
                int height = h->mb.i_mb_height >> PARAM_INTERLACED;
                int width = h->mb.i_mb_width << PARAM_INTERLACED;
                i_slice_num++;
                h->sh.i_last_mb = (height * i_slice_num + h->param.i_slice_count/2) / h->param.i_slice_count * width - 1;
            }
        }
        h->sh.i_last_mb = X264_MIN( h->sh.i_last_mb, last_thread_mb );
        
		//真正的编码——编码1个Slice  
        //x264_stack_align()应该是平台优化过程中内存对齐的工作  
        //实际上就是调用x264_slice_write()
		if( x264_stack_align( x264_slice_write, h ) )	//调用x264_slice_write(),进入核心编码函数块
            goto fail;
        h->sh.i_first_mb = h->sh.i_last_mb + 1;//注意这里对i_first_mb进行了赋值
        // if i_first_mb is not the last mb in a row then go to the next mb in MBAFF order
        if( SLICE_MBAFF && h->sh.i_first_mb % h->mb.i_mb_width )
            h->sh.i_first_mb -= h->mb.i_mb_stride;
    }

    return (void *)0;

fail:
    /* Tell other threads we're done, so they wouldn't wait for it */
    if( h->param.b_sliced_threads )
        x264_threadslice_cond_broadcast( h, 2 );
    return (void *)-1;
}


2x264_slice_write()函数

 

        x264_slice_write()是完成编码工作的函数。该函数中包含了去块效应滤波,运动估计,宏块编码,熵编码等模块。x264_slice_write()调用了如下函数:

x264_nal_start()&

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`x264_nal_t`结构体是x264库中用于存储编码后的NAL数据信息的结构体,其中不包含PTS、DTS、Duration和Index等信息,需要使用外部变量或函数进行传递或计算。具体实现时,可以按照以下步骤获取PTS、DTS、Duration和Index等信息: 1. 在调用x264_encoder_encode函数进行编码时,可以将PTS和DTS作为x264_picture_t结构体变量的i_pts和i_dts字段进行设置,例如: ``` x264_picture_t pic_in, pic_out; // 设置图像数据 pic_in.i_pts = pts; pic_in.i_dts = dts; // 编码一帧图像 int ret = x264_encoder_encode(encoder, &nal, &nnal, &pic_in, &pic_out); ``` 2. 在编码完成后,可以根据视频帧率和编码时长计算出Duration信息,例如: ``` int frame_rate = 25; // 视频帧率 int duration = 1000 / frame_rate; // 每帧编码时长(毫秒) ``` 3. 在传递x264_nal_t结构体变量时,可以使用外部变量或函数传递Index信息,例如: ``` int nal_index = 0; // NAL序号 for (int i = 0; i < nnal; i++) { x264_nal_t *nal_ptr = &nal[i]; // 设置NAL信息 nal_ptr->i_ref_idc = 0; nal_ptr->i_type = NAL_SLICE; nal_ptr->i_payload = nal_size[i]; nal_ptr->p_payload = nal_data[i]; nal_ptr->i_nal_units = nnal; nal_ptr->i_nal_unit = i; nal_ptr->i_temporal_reference = nal_index++; } ``` 通过以上步骤,就可以获取到PTS、DTS、Duration和Index等信息,并将编码后的NAL数据存储到x264_nal_t结构体中。需要注意的是,具体实现时还需要根据具体情况进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值