Chinaunix首页 | 论坛 | 博客
  • 博客访问: 28310
  • 博文数量: 12
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2
  • 用 户 组: 普通用户
  • 注册时间: 2015-01-05 23:21
文章分类
文章存档

2016年(1)

2015年(11)

我的朋友

分类: 嵌入式

2015-06-16 14:59:39

原文地址:x264学习笔记 作者:apple_zhangwei

1x264程序框架流程分析

(1) 进入x264.c int main( int argc, char **argv ) 函数

    main 函数中主要有以下三个主要的步骤,分别调用了3个函数。

第一步、对编码器进行参数设定。函数实现如下:

x264_param_default( x264_param_t *param );此函数在common.c中定义,完成一个x264_param_t 结构体的初始化。

第二步、分析参数,读入运行参数完成文件打开。函数实现如下:

Parse( argc, argv, x264_param_t *param, &opt );此函数在 x264.c 中定义。

VC的运行参数我们可以设置: -o out.264 football.yuv 352x288

则具体到Parse函数,其输入的参数 argc == 5 ,这个数值大小等于要放下下面的 argv所需要的二维数组的行数。参数argcargv在进入main 函数之前就已经确定了。

argv 为字符串char **的类型的,相当于一个二维数组,其具体内容如下:

argv[0][] == F:\x264-snapshot-20070331-2245\build\win32\bin\x264.exe

argv[1][] == -o

argv[2][] == out.264

argv[3][] == football.yuv

argv[4][] == 352x288

第三步、开始编码。函数实现如下:

Encode( x264_param_t *param, &opt ); 此函数在 x264.c 中定义。

(2) static int Parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt )

分析参数,读入运行参数。

其中比较重要的语句是

   int c = getopt_long( argc, argv, "8A:B:b:f:hI:i:m:o:p:q:r:t:Vvw",

                    long_options, &long_options_index);

getopt_long()解析入口地址的向量,最后int c 得到的是 运行参数(“-o out.264 football.yuv 352x288)中前面“-o中“o”的ASCII c = 111 。这个getopt_long函数的实现在官方网站上下的程序中没有实现,需要自己来写。

Parse 在解析了入口地址后,用下面的语句打开文件

p_open_infile( psz_filename, &opt->hin, param )

{

    yuv_input_t *h = malloc(sizeof(yuv_input_t));

    h->width = p_param->i_width;

    h->height = p_param->i_height;

    h->next_frame = 0;

    if( !strcmp(psz_filename, "-") )

        h->fh = stdin;

    else

        h->fh = fopen(psz_filename, "rb");

    if( h->fh == NULL )

        return -1;

    *p_handle = (hnd_t)h;

    return 0;

}

这样就在下面Encode函数中一开始,得到总的编码帧数,调用这个函数

int get_frame_total_yuv( hnd_t handle )

{

    yuv_input_t *h = handle;

    int i_frame_total = 0;

    if( !fseek( h->fh, 0, SEEK_END ) )

    {

        uint64_t i_size = ftell( h->fh );//得到文件的大小。

        fseek( h->fh, 0, SEEK_SET );

        i_frame_total = (int)(i_size / ( h->width * h->height * 3 / 2 ));     

              //计算总的帧数

   /// 这里乘以1.5是因为一个编码单位是一个亮度块加2个色度块,大小上等于1.5个亮度块

    }

    return i_frame_total;

}

(3) static int Encode( x264_param_t *param, cli_opt_t *opt )

   前面都是读取默认参数,如果设置了参数的话,可以修改 param的。编码的主要部分还是在这个函数里面进行调用。

   Encode 函数主要分为以下几步:

   第一步、读取输入文件的总帧数,存放在 param->i_frame_total

   第二步、调用 h = x264_encoder_open( param ) 函数对不正确的264_t结构体(h的类型是264_t * )参数进行修改,并对各结构体参数、编码、预测等需要的参数进行初始化。

   第三步、构造一个图像帧的初始化空间。

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

   第四步、利用下面一个for循环,开始一帧一帧进行编码。

      for( i_frame = 0, i_file = 0, i_progress = 0;

         b_ctrl_c == 0 && (i_frame < i_frame_total || i_frame_total == 0); )

      在这个for循环中,

      读取 p_read_frame( &pic, opt->hin, i_frame + opt->i_seek )

       编码并保存 i_file += Encode_frame( h, opt->hout, &pic );

(4) static int Encode_frame( x264_t *h, hnd_t hout, x264_picture_t *pic )

这个函数主要是调用了 x264_encoder_encode( h, &nal, &i_nal, pic, &pic_out ) 来实现编码。这个函数也是x264的核心部分了。

阅读(963) | 评论(0) | 转发(0) |
0

上一篇:内存映射

下一篇:getopt ,getopt_long使用方法

给主人留下些什么吧!~~