C语言 如何使用 x264 C API 将一系列图像编码为 H264?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2940671/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does one encode a series of images into H264 using the x264 C API?
提问by Rella
How does one use the x264 C API to encode RBG images into H264 frames? I already created a sequence of RBG images, how can I now transform that sequence into a sequence of H264 frames? In particular, how do I encode this sequence of RGB images into a sequence of H264 frame consisting of a single initial H264 keyframe followed by dependent H264 frames?
如何使用 x264 C API 将 RBG 图像编码为 H264 帧?我已经创建了一系列 RBG 图像,现在如何将该序列转换为 H264 帧序列?特别是,如何将此 RGB 图像序列编码为 H264 帧序列,该序列由单个初始 H264 关键帧和相关的 H264 帧组成?
回答by KillianDS
First of all: check the x264.h file, it contains more or less the reference for each function and structure. The x264.c file you can find in the download contains a sample implementation. Most people say to base yourself on that one, but I find it rather complex for beginners, it is good as an example to fall back on however.
首先:检查x264.h文件,它或多或少包含每个函数和结构的参考。您可以在下载中找到的 x264.c 文件包含一个示例实现。大多数人都说要以那个为基础,但我发现它对于初学者来说相当复杂,但是作为一个例子可以依靠。
First you set up some parameters, of the type x264_param_t, a good site describing parameters is http://mewiki.project357.com/wiki/X264_Settings. Also take a look at the x264_param_default_presetfunction which allows you to target some functionality without needing to understand all of the (sometimes quite complex) parameters. Also use x264_param_apply_profileafterwards (you'll probably want the "baseline" profile)
首先设置一些参数,类型为 x264_param_t,一个描述参数的好网站是http://mewiki.project357.com/wiki/X264_Settings。还可以查看该x264_param_default_preset函数,该函数允许您定位某些功能,而无需了解所有(有时非常复杂)参数。x264_param_apply_profile之后也使用(您可能需要“基线”配置文件)
This is some example setup from my code:
这是我的代码中的一些示例设置:
x264_param_t param;
x264_param_default_preset(¶m, "veryfast", "zerolatency");
param.i_threads = 1;
param.i_width = width;
param.i_height = height;
param.i_fps_num = fps;
param.i_fps_den = 1;
// Intra refres:
param.i_keyint_max = fps;
param.b_intra_refresh = 1;
//Rate control:
param.rc.i_rc_method = X264_RC_CRF;
param.rc.f_rf_constant = 25;
param.rc.f_rf_constant_max = 35;
//For streaming:
param.b_repeat_headers = 1;
param.b_annexb = 1;
x264_param_apply_profile(¶m, "baseline");
After this you can initialize the encoder as follows
在此之后,您可以按如下方式初始化编码器
x264_t* encoder = x264_encoder_open(¶m);
x264_picture_t pic_in, pic_out;
x264_picture_alloc(&pic_in, X264_CSP_I420, w, h)
X264 expects YUV420P data (I guess some others also, but that's the common one). You can use libswscale (from ffmpeg) to convert images to the right format. Initializing this is like this (i assume RGB data with 24bpp).
X264 需要 YUV420P 数据(我想还有其他一些数据,但这是常见的数据)。您可以使用 libswscale(来自 ffmpeg)将图像转换为正确的格式。初始化是这样的(我假设 RGB 数据为 24bpp)。
struct SwsContext* convertCtx = sws_getContext(in_w, in_h, PIX_FMT_RGB24, out_w, out_h, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);
encoding is as simple as this then, for each frame do:
编码就是这样简单,然后对每一帧执行以下操作:
//data is a pointer to you RGB structure
int srcstride = w*3; //RGB stride is just 3*width
sws_scale(convertCtx, &data, &srcstride, 0, h, pic_in.img.plane, pic_in.img.stride);
x264_nal_t* nals;
int i_nals;
int frame_size = x264_encoder_encode(encoder, &nals, &i_nals, &pic_in, &pic_out);
if (frame_size >= 0)
{
// OK
}
I hope this will get you going ;), I spent a long time on it myself to get started. X264 is an insanely strong but sometimes complex piece of software.
我希望这能让你继续前进;),我自己花了很长时间才开始。X264 是一个非常强大但有时很复杂的软件。
edit: When you use other parameters there will be delayed frames, this is not the case with my parameters (mostly due to the nolatency option). If this is the case, frame_size will sometimes be zero and you'll have to call x264_encoder_encodeas long as the function x264_encoder_delayed_framesdoes not return 0. But for this functionality you should take a deeper peek into x264.c and x264.h .
编辑:当你使用其他参数时会有延迟帧,我的参数不是这种情况(主要是由于 nolatency 选项)。如果是这种情况, frame_size 有时会为零,x264_encoder_encode只要函数x264_encoder_delayed_frames不返回 0 ,您就必须调用。但是对于此功能,您应该更深入地查看 x264.c 和 x264.h 。
回答by roxlu
I've uploaded an example which generates raw yuv frames and then encodes them using x264. Full code can be found here: https://gist.github.com/roxlu/6453908
我上传了一个示例,它生成原始 yuv 帧,然后使用 x264 对它们进行编码。完整代码可以在这里找到:https: //gist.github.com/roxlu/6453908

