登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

面包会有的

... ...

 
 
 

日志

 
 

X264代码学习(四)  

2011-06-12 03:58:13|  分类: VC++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

1. if( p_set_outfile_param( opt->hout, param ) )  // p_set_outfile_param = set_param_bsf 判断输出文件
    {
        fprintf( stderr, "can't set outfile param\n" );
        p_close_infile( opt->hin );
        p_close_outfile( opt->hout );
        return -1;
    }

 p_set_outfile_param = set_param_bsf , 在muxers.c中,函数原型为:

int set_param_bsf( hnd_t handle, x264_param_t *p_param )
{
    return 0;
}

2.  x264_picture_alloc( &pic, X264_CSP_I420, param->i_width, param->i_height );

                                                                   //构造一个图像帧的初始化空间,在common.c中,函数原型为:

void x264_picture_alloc( x264_picture_t *pic, int i_csp, int i_width, int i_height )
{
    pic->i_type = X264_TYPE_AUTO;
    pic->i_qpplus1 = 0;
    pic->img.i_csp = i_csp;
    switch( i_csp & X264_CSP_MASK )
    {
        case X264_CSP_I420:
        case X264_CSP_YV12:
            pic->img.i_plane = 3;
            pic->img.plane[0] = x264_malloc( 3 * i_width * i_height / 2 );
            pic->img.plane[1] = pic->img.plane[0] + i_width * i_height;
            pic->img.plane[2] = pic->img.plane[1] + i_width * i_height / 4;
            pic->img.i_stride[0] = i_width;
            pic->img.i_stride[1] = i_width / 2;
            pic->img.i_stride[2] = i_width / 2;
            break;

        case X264_CSP_I422:
            ...

    }
}

3. i_start = x264_mdate();  //用于编码用时的计算,设定起始时间,在 mdate.c中,函数原型为:

int64_t x264_mdate( void )
{
#if !(defined(_MSC_VER) || defined(__MINGW32__))
    struct timeval tv_date;

    gettimeofday( &tv_date, NULL );
    return( (int64_t) tv_date.tv_sec * 1000000 + (int64_t) tv_date.tv_usec );
#else
    struct _timeb tb;
    _ftime(&tb);
    return ((int64_t)tb.time * (1000) + (int64_t)tb.millitm) * (1000);
#endif
}   

4.  进入编码帧 /* Encode frames */
    for( i_frame = 0, i_file = 0, i_progress = 0;
         b_ctrl_c == 0 && (i_frame < i_frame_total || i_frame_total == 0); )
    {
        if( p_read_frame( &pic, opt->hin, i_frame + opt->i_seek ) )//读取
            break;

       //p_read_frame() 按照h->hin提供的输入文件的地址,读入图像的内容到&pic提供的存储区的首地址

        pic.i_pts = (int64_t)i_frame * param->i_fps_den;

        i_file += Encode_frame( h, opt->hout, &pic );//编码并保存,
                                               //Encode_frame( h, opt->hout, &pic )实现编码,是x264的核心部分

        i_frame++;

        /* update status line (up to 1000 times per input file) */
        if( opt->b_progress && param->i_log_level < X264_LOG_DEBUG &&
            ( i_frame_total ? i_frame * 1000 / i_frame_total > i_progress
                            : i_frame % 10 == 0 ) )
        {
            int64_t i_elapsed = x264_mdate() - i_start;
            double fps = i_elapsed > 0 ? i_frame * 1000000. / i_elapsed : 0;
            if( i_frame_total )
            {
                int eta = i_elapsed * (i_frame_total - i_frame) / ((int64_t)i_frame * 1000000);
                i_progress = i_frame * 1000 / i_frame_total;
                fprintf( stderr, "encoded frames: %d/%d (%.1f%%), %.2f fps, eta %d:%02d:%02d  \r",
                         i_frame, i_frame_total, (float)i_progress / 10, fps,
                         eta/3600, (eta/60)%60, eta%60 );
            }
            else
                fprintf( stderr, "encoded frames: %d, %.2f fps   \r", i_frame, fps );
            fflush( stderr ); // needed in windows
        }
    }

      注1: //在本文环境下,p_read_frame=read_frame_yuv,read_frame_yuv()定义在muxers.c中,原型为:

int read_frame_yuv( x264_picture_t *p_pic, hnd_t handle, int i_frame )
{
    yuv_input_t *h = handle;

    if( i_frame != h->next_frame )
        if( fseek( h->fh, (uint64_t)i_frame * h->width * h->height * 3 / 2, SEEK_SET ) )
            return -1;

    if( fread( p_pic->img.plane[0], 1, h->width * h->height, h->fh ) <= 0
            || fread( p_pic->img.plane[1], 1, h->width * h->height / 4, h->fh ) <= 0
            || fread( p_pic->img.plane[2], 1, h->width * h->height / 4, h->fh ) <= 0 )
        return -1;

    h->next_frame = i_frame+1;

    return 0;
}

从文件中分别读取288*352(亮度信息),144*176(Cr),144*176(Cb)的数据放入p_pic->img.plane[0],p_pic->img.plane[1],p_pic->img.plane[2],如果成功则继续执行一下程序;如果不成功则打断程序,返回-1.

注2: i_file += Encode_frame( h, opt->hout, &pic );//编码并保存,
                      //Encode_frame( h, opt->hout, &pic )实现编码,是x264的核心部分,在X264.c中,

              //这个函数主要是调用了 x264_encoder_encode( h, &nal, &i_nal, pic, &pic_out ) 来实现编码。

// 原型为:

static int  Encode_frame( x264_t *h, hnd_t hout, x264_picture_t *pic )
{
    x264_picture_t pic_out;
    x264_nal_t *nal;
    int i_nal, i;
    int i_file = 0;

    /* Do not force any parameters */
    if( pic )
    {
        pic->i_type = X264_TYPE_AUTO;
        pic->i_qpplus1 = 0;
    }
    if( x264_encoder_encode( h, &nal, &i_nal, pic, &pic_out ) < 0 )
    {
        fprintf( stderr, "x264_encoder_encode failed\n" );
    }

    for( i = 0; i < i_nal; i++ )
    {
        int i_size;
        int i_data;

        i_data = DATA_MAX;
        if( ( i_size = x264_nal_encode( data, &i_data, 1, &nal[i] ) ) > 0 )
        {
            i_file += p_write_nalu( hout, data, i_size );
        }
        else if( i_size < 0 )
        {
            fprintf( stderr, "need to increase buffer size (size=%d)\n", -i_size );
        }
    }
    if (i_nal)
        p_set_eop( hout, &pic_out );

    return i_file;
}

  评论这张
 
阅读(1814)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018