使用libx264将I420编码为H.264
来源:互联网 发布:当当读书软件 编辑:程序博客网 时间:2024/06/06 20:48
使用libx264将I420编码为H.264
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(¶m, "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(¶m, "baseline");15 encoder = x264_encoder_open(¶m);
初始化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
这里有一段I420视频可供测试。
参考
- 使用libx264将I420编码为H.264
- 使用libx264将I420编码为H.264
- 使用libx264将I420编码为H.264
- 使用libx264将I420编码为H.264
- 最简单的视频编码器:基于libx264(编码YUV为H.264)
- 最简单的视频编码器:基于libx264(编码YUV为H.264)
- 【FFmpeg学习笔记005】 libx264和FFmpeg不同方式(YUV编码为H.264)
- 使用FFMPEG将YUV编码为H.264
- 使用ffmpeg接口将YUV编码为h.264
- iOS 使用libx264编码视频
- iOS 使用libx264编码视频
- OpenCV,ffmpeg与libx264进行H.264编码(CPU与GPU版)
- linux下使用ffmpeg将flv、mp4、rmvb转换为libx264的mp4
- 使用ffmpeg接口将h.264解码为YUV
- 【媒体流】libx264 将rgb24格式转换为h264
- NV12转换为I420
- obs之libx264编码
- 将OBJ模型转换为.h文件给Xcode使用
- HTM页面获得本机时间
- 正则。IP验证
- C以二进制读、写、文本
- HTML下拉框、文本框、复选框!
- GDB调试命令!
- 使用libx264将I420编码为H.264
- div隐藏输入框
- FIFO通信 htonl 和memcpy的用法
- Oracle命令--配置SQLplus
- LINUX的一些简单命令 时间修改
- Catalog Item & Build
- HTML中的attribute和property的区别
- 编译环境。路径设置
- HTML连接