当前位置: 首页> 汽车> 维修 > 【视频编码】调用x264库文件实现编码

【视频编码】调用x264库文件实现编码

时间:2025/7/10 12:52:32来源:https://blog.csdn.net/weixin_42877471/article/details/140891271 浏览次数: 0次

调用x264库文件实现编码

整理前面记录的文章时发现还没有记录过如何实际操作x264编码器实现编码的功能,过去是通过FFmpeg调用libx264的接口来实现编码功能,这里记录一下直接调用x264的接口来实现编码的功能,同时存储编码之后的码流和重建的yuv。

代码整体的框架参考example.c文件,文件的存储参考encoder.c中的frame_dump函数。在进行文件存储时需要注意uv分量的存储是按照interleave的方式进行的

// x264_encode.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#pragma warning(disable:4996)#include <stdio.h>
#include <malloc.h>
#include <stdint.h>
#include <inttypes.h>
#include <memory.h>#include "x264.h"
#include "x264_config.h"#define	BUF_SIZE	32 * 1024 * 1024#define ENCODE_STREAM_SAVE	1
#define RECON_YUV_SAVE 1void plane_copy_deinterleave(uint8_t* dsta, intptr_t i_dsta, uint8_t* dstb, intptr_t i_dstb,uint8_t* src, intptr_t i_src, int w, int h)
{for (int y = 0; y < h; y++, dsta += i_dsta, dstb += i_dstb, src += i_src)for (int x = 0; x < w; x++){dsta[x] = src[2 * x];dstb[x] = src[2 * x + 1];}}int main(int argc, int** argv)
{FILE* fp_in_yuv;FILE* fp_out_h264;FILE* fp_out_recon;int width, height;int frames_to_encode;x264_param_t param;x264_picture_t pic_in;x264_picture_t pic_out;x264_t* h;int i_frame = 0;int i_frame_size;x264_nal_t* nals;x264_nal_t* nal;int i_nal;// set default paramx264_param_default(&param);/* Get default params for preset/tuning */if (x264_param_default_preset(&param, "ultrafast", "zerolatency") < 0){printf("set preset failed\n");return -1;}width = 1280;height = 720;/* Configure non-default params */param.i_bitdepth = 8;param.i_csp = X264_CSP_I420;param.i_width = width;param.i_height = height;param.b_vfr_input = 0;param.b_repeat_headers = 1;param.b_annexb = 1;param.b_full_recon = 1;/* Apply profile restrictions. */if (x264_param_apply_profile(&param, "high") < 0){printf("apply profile failed\n");return -1;}h = x264_encoder_open(&param);if (!h){printf("open encoder failed\n");return -1;}if (x264_picture_alloc(&pic_in, param.i_csp, param.i_width, param.i_height) < 0){printf("alloc picture failed\n");return -1;}uint8_t* data_buf = (uint8_t*)malloc(BUF_SIZE * sizeof(uint8_t));if (!data_buf){printf("malloc data buf failed\n");return -1;}fp_in_yuv = fopen("crew.yuv", "rb");if (!fp_in_yuv){printf("open file failed\n");return -1;}#if ENCODE_STREAM_SAVEfp_out_h264 = fopen("crew.h264", "wb");if (!fp_out_h264){printf("open output file failed\b");return -1;}
#endif
#if RECON_YUV_SAVEfp_out_recon = fopen("crew_recon.yuv", "wb");if (!fp_out_recon){printf("open recon file failed\n");return -1;}
#endifint rsz = 0; // read sizeint size = width * height;uint8_t* p = data_buf;int frame_cnt = 0;/* Encode frames */for (;; i_frame++){rsz = fread(p, 1, width * height * 3 / 2, fp_in_yuv);printf("read size:%d\n", rsz);if (!rsz){printf("end of file\n");goto end;}// read input datamemcpy(pic_in.img.plane[0], p, size);memcpy(pic_in.img.plane[1], p + size, size / 4);memcpy(pic_in.img.plane[2], p + size + size / 4, size / 4);pic_in.i_pts = i_frame;i_frame_size = x264_encoder_encode(h, &nals, &i_nal, &pic_in, &pic_out);if (i_frame_size < 0){printf("x264 encode failed\n");goto end;}else if (i_frame_size){
#if ENCODE_STREAM_SAVEfor (nal = nals; nal < nals + i_nal; nal++) {fwrite(nal->p_payload, sizeof(uint8_t), nal->i_payload, fp_out_h264);}
#endif#if RECON_YUV_SAVE// write recon yuvfor (int y = 0; y < height; y++){fwrite(&pic_out.img.plane[0][y * pic_out.img.i_stride[0]], sizeof(uint8_t), width, fp_out_recon);}/*img.plane[1]中存储uv分量的方式为交错存储,即UV UV UV....的方式0		1		2		3...	w_uv - 10		uv		uv		uv		uv		uv1		uv		uv		uv		uv		uv2		uv		uv		uv		uv		uv3		uv		uv		uv		uv		uv...h_uv - 1	uv	uv		uv		uv		uv*/int cw = width >> 1;int ch = height >> 1;uint8_t* planeu = (uint8_t*)malloc(2 * (cw * ch * sizeof(uint8_t) + 32));if (planeu){uint8_t* planev = planeu + cw * ch + 32 / sizeof(uint8_t);plane_copy_deinterleave(planeu, cw, planev, cw, pic_out.img.plane[1], pic_out.img.i_stride[1], cw, ch);fwrite(planeu, 1, cw * ch * sizeof(uint8_t), fp_out_recon);fwrite(planev, 1, cw * ch * sizeof(uint8_t), fp_out_recon);free(planeu);}
#endif}printf("frame_cnt:%d\n", frame_cnt++);}end:x264_encoder_close(h);x264_picture_clean(&pic_in);fclose(fp_in_yuv);
#if ENCODE_STREAM_SAVEfclose(fp_out_h264);
#endif
#if RECON_YUV_SAVEfclose(fp_out_recon);
#endiffree(data_buf);return 0;
}

编码前后yuv对比
原始yuv(crew.yuv)
在这里插入图片描述

重建yuv(crew_recon.yuv)在这里插入图片描述
编码后码流
在这里插入图片描述

关键字:【视频编码】调用x264库文件实现编码

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: