c - 如何使用 x264 C API 将一系列图像编码为 H264?

标签 c image h.264 x264

如何使用 x264 C API 将 RBG 图像编码为 H264 帧?我已经创建了一系列 RBG 图像,现在如何将该序列转换为一系列 H264 帧?特别是,我如何将此 RGB 图像序列编码为 H264 帧序列,该帧由单个初始 H264 关键帧和后跟相关 H264 帧组成?

最佳答案

首先:检查x264.h文件,它或多或少包含了对每个函数和结构的引用。您可以在下载中找到的 x264.c 文件包含一个示例实现。大多数人说以那个为基础,但我发现它对初学者来说相当复杂,但是作为一个很好的例子可以依靠。

首先设置一些 x264_param_t 类型的参数,一个描述参数的好网站是 http://mewiki.project357.com/wiki/X264_Settings .另请查看 x264_param_default_preset 函数,它允许您针对某些功能而无需了解所有(有时非常复杂)参数。之后还使用 x264_param_apply_profile(您可能需要“基准”配置文件)

这是我的代码中的一些示例设置:

x264_param_t param;
x264_param_default_preset(&param, "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(&param, "baseline");

在此之后,您可以按如下方式初始化编码器

x264_t* encoder = x264_encoder_open(&param);
x264_picture_t pic_in, pic_out;
x264_picture_alloc(&pic_in, X264_CSP_I420, w, h)

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);

编码就这么简单,对每一帧做:

//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
}

我希望这能让你继续下去 ;),我自己花了很长时间才开始。 X264 是一款非常强大但有时也很复杂的软件。

编辑:当你使用其他参数时会有延迟帧,我的参数不是这种情况(主要是由于 nolatency 选项)。如果是这种情况,frame_size 有时会为零,只要函数 x264_encoder_delayed_frames 不返回 0,您就必须调用 x264_encoder_encode。但是对于此功能,您应该深入了解 x264.c 和 x264.h。

关于c - 如何使用 x264 C API 将一系列图像编码为 H264?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2940671/

相关文章:

c - (希望)我的刽子手游戏的最后一个循环,

c - AIX loadquery() 返回值解释(也是 64 位模式下的 SEGV)

c# - 我可以在 azure 函数应用程序中包含图像等资源吗?

javascript - 使用 image.complete 查找图像是否缓存在 chrome 上?

c - FFmpeg - H264 编码器找不到有效设备并且无法配置编码器

ffmpeg - 是否可以使用一个命令将一个 yuv 文件编码为 3 个具有不同比特率的 h.264 文件?

c++ - 为什么C/C++中没有||=运算符?

c - 动态分配 'sizeof(char)' 冗余时是否使用 'char'?

python - 从 .qrc 文件(使用 pyside-rcc )编译的 .py 文件不起作用

video - 如何从 h.264 视频流中获取帧率?