流媒体直播之七X264实现H.264的软件编码

Author: CaoHu
E-Mail: hnu_xiaohu@163.com Version:0.1 Date: 2018-01-29 10:28
Description: My level is limited, if there are some weaknesses, welcome criticism. If the content of the blog is involved in infringement, please contact my mailbox, it will be deleted immediately, welcome to exchange, learn from each other!


http://www.cnblogs.com/fojian/archive/2012/09/01/2666627.html此笔记参考博客地址】

libx264
libx264是一个自由的H.264编码库,是x264项目的一部分,使用广泛,ffmpeg的H.264实现就是用的libx264。
代码
要把一个I420视频文件编码为H264格式。I420是YUV中planar格式的一种,一张I420图片中有三个plane,分别存放整张图片的Y、U、V分量;采样比例为4:2:0,12bpp,Y:U:V的分量长度是4:1:1。
头文件

1 #include <stdint.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <fcntl.h>
5 #include <unistd.h>
6 #include <x264.h>

变量声明和参数

1 int width = 480;
 2 int height = 360;
 3 int fps = 25;
 4 size_t yuv_size = width * height * 3 / 2;
 5 x264_t *encoder;
 6 x264_picture_t pic_in, pic_out;
 7 int inf, outf;
 8 uint8_t *yuv_buffer;
 9 
10 if (argc != 3) {
11     printf("usage: %s input output\n", argv[0]);
12 }

视频尺寸是480×360,YUV I420格式,每个像素1.5个字节,所以一张YUV图片大小是width * height * 1.5
encoder就是编码器,x264_t格式在x264.h文件中只有
typedef struct x264_t x264_t
编码器类型只需要也只能声明为x264_t的指针类型
每次编码时,YUV图片的信息都保存在pic_in中
输入输出的文件描述符
从文件读入的YUV的缓冲区
初始化encoder

1 x264_param_t param;
 2 x264_param_default_preset(&param, "veryfast", "zerolatency");
 3 param.i_threads = 1;
 4 param.i_width = width;
 5 param.i_height = height;
 6 param.i_fps_num = fps;
 7 param.i_fps_den = 1;
 8 
 9 param.i_keyint_max = 25;
10 param.b_intra_refresh = 1;
11 
12 param.b_annexb = 1;
13 
14 x264_param_apply_profile(&param, "baseline");
15 encoder = x264_encoder_open(&param);

初始化pic_in

1 x264_picture_alloc(&pic_in, X264_CSP_I420, width, height);
2 
3 yuv_buffer = malloc(yuv_size);
4 
5 pic_in.img.plane[0] = yuv_buffer;
6 pic_in.img.plane[1] = pic_in.img.plane[0] + width * height;
7 pic_in.img.plane[2] = pic_in.img.plane[1] + width * height / 4;

pic_in.img中保存YUV图片各分量的信息

typedef struct {
    int i_csp;
    int i_plane;
    int i_stride[4];
    uint8_t *plane[4];
} x264_image_t;

其中icsp, iplane, istride的值在picin初始化的时候已经被赋值,代码中只需要将plane数组指向正确的位置
程序中每一帧的图片都是读取到yuv_buffer中,所以在这里设置一次就行了
初始化文件描述符

1 inf = open(argv[1], O_RDONLY);
2 if (inf < 0) {
3     return -1;
4 }
5 outf = open(argv[2], O_CREAT | O_WRONLY, 444);
6 if (outf < 0) {
7     return -1;
8 }

编码

 1 int64_t i_pts = 0;
 2 
 3 x264_nal_t *nals;
 4 int nnal;
 5 while (read(inf, yuv_buffer, yuv_size) > 0) {
 6     pic_in.i_pts = i_pts++;
 7     x264_encoder_encode(encoder, &nals, &nnal, &pic_in, &pic_out);
 8     x264_nal_t *nal;
 9     for (nal = nals; nal < nals + nnal; nal++) {
10         write(outf, nal->p_payload, nal->i_payload);
11     }
12 }

关于ffmpeg的pts,网上有好多种公式,其实只要步长为1递增就行了
H.264的NAL层是为了适应网络传输的需要,将大的编码后的帧分成多个块
p_payload就是编码后的H.264的帧数据,写入输出文件
扫尾

1 x264_encoder_close(encoder);
2 close(inf);
3 close(outf);
4 free(yuv_buffer);
5 return 0;

编译
gcc sourcefile -lx264 -Wall -o execfile

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值