x264程序框架流程分析

1、x264程序框架流程分析

(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所需要的二维数组的行数。参数argc和argv在进入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的核心部分了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
⒈ 题目 编写前述PASCAL子集的词法分析程序。 1)主程序设计考虑,(参阅后面给出的程序框架) 主程序的说明部分为各种表格和变量安排空间。 数组k为关键字表,每个数组元素存放一个关键字。采用定长的方式,较短的关键字后面补空格。 P 数组存放分界符。为了简单起见,分界符、算术运算符和关系运算符都放在p表中(学生编程时,应建立算术运算符表和关系运算符表,并且各有类号),合并成一类。 id 和ci 数组分别存放标识符和常数。 instring 数组为输入源程序的单词缓存。 outtoken 记录为输出内部表示缓存。 还有一些为造表填表设置的变量。 主程序开始后,先以人工方式输入关键字,造 k 表;再输入分界符等造 p 表。 主程序的工作部分设计成便于调试的循环结构。每个循环处理一个单词;接收键盘上送来的一个单词;调用词法分析过程;输出每个单词的内部码。 2)词法分析过程考虑 该过程取名为 lexical,它根据输入单词的第一个字符(有时还需读第二个字符),判断单词类,产生类号:以字符k表示关键字;i表示标识符;c 表示常数;p 表示分界符;s 表示运算符(学生编程时类号分别为1,2,3,4,5)。 对于标识符和常数,需分别与标识符表和常数表中已登记的元素相比较,如表中已有该元素,则记录其在表中的位置,如未出现过,将标识符按顺序填入数组 id 中,将常数变为二进制形式存入数组中 ci 中,并记录其在表中的位置。 lexical 过程中嵌有两个小过程:一个名为 getchar,其功能为从 instring 中按顺序取出一个字符,并将其指针 pint 加 1 ;另一个名为 error,当出现错误时,调用这个过程,输出错误编号。 将词法分析程序设计成独(入口)立一遍扫描源程序的结构。其流程图见图5-1。 图5-1 词法分析程序流程图 ⒉ 要求 ⑴ 所有识别出的单词都用两个字节的等长表示,称为内部码。第一个字节为 t ,第二个字节为 i 。 t 为单词的种类。关键字的 t=1;分界符的 t=2;算术运算符的 t=3;关系运算符的 t=4;无符号数的 t=5;标识符的 t=6。i 为该单词在各自表中的指针或内部码值。表 5-1 为关键字表;表 5-2 为分界符表;表 5-3 为算术运算符的 i 值;表 5-4 为关系运算符的 i 值。 表5-1 关键字表 表5-2 分界符表 指针1 关键字 指针1 分界符 0 BEGIN 0 , 1 DO 1 ; 2 ELSE 2 . 3 END 3 := 4 IF 4 ( 5 THEN 5 ) 6 VAR 7 WHILE 表5-3 算术运算符 表5-4 关系运算符 i 值 算术运算符 i 值 关系运算符 00H < 10H + 01H 21H / 04H >= 05H 常数表和标识符表是在编译过程中建立起来的。其 i 值是根据它们在源程序中出现的顺序确定的。 ⑵ 常数分析程序、关键字和标识符分析程序、其他单词分析程序请参阅范例自行设计。 ⑶ 本实践题可通过扩充下面给出的程序框架完成。 PROGRAM plexical(input,output); LABEL l; CONST keylen=10; identlen=10; TYPE //定义的类型 tstring=ARRAY[1..identlen] OF char; outreco=RECORD//记录为输出内部表示缓存。 ty: char; point: integer; END; {outreco} VAR cip,ip,pint,i,j,l,m,errorx:integer; charl:CHAR; ci:ARRAY[1..10] OF integer; k,id:ARRAY[1..keylen] OF tstring; token:tstring; //标志符 outtoken:outreco; instring:ARRAY[1..10]OF char; p:ARRAY[1..16] OF ARRAY [1..2] OF char; PROCEDURE lexical; VAR l,m,num:integer; b: boolean; PROCEDURE

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值