FFMPEG - C API - GIF 制作
FFMPEG - C API - GIF creation
我有一个图像处理管道,我在内存中有图像可以转换成 AVFrame
,我尝试用这些图像创建 GIF。
我从这个 开始,我只是将视频解码器部分替换为将内存中的图像转换为 AVFrame
。
这项工作很好,但我对 GIF 帧率有疑问。
进入init_filters(...)
方法,不明白参数结构的time_base
和pixel_aspect
变量:
snprintf(args, sizeof(args),
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
width, height, in_fmt, time_base.num, time_base.den,
pixel_aspect.num, pixel_aspect.den);
我想要 FPS=12,那么我应该按如下方式定义它们吗?
AVRational time_base = AVRational{1, 12};
AVRational pixel_aspect= AVRational{1, 1};
接下来,在我将帧提供给过滤器缓冲区(对于 palettegen)的循环中,我还有一个我不明白的选项,AVFrame->pts 指的是什么?
// palettegen need a whole stream, just add frame to buffer.
ret = av_buffersrc_add_frame_flags(buffersrc_ctx, picture_rgb24, AV_BUFFERSRC_FLAG_KEEP_REF);
if (ret < 0) {
av_log(nullptr, AV_LOG_ERROR, "error add frame to buffer source %s\n", av_make_error_string(msg_v2, MSG_LEN, ret));
}
picture_rgb24->pts += 1; // HERE
据我了解,它应该是帧的时间戳,在我的情况下,我有一个 GIF,我应该每次增加 1 吗?或 1000 毫秒/12 帧 = 83.33 毫秒?我不确定,我试图找到这些信息,但到目前为止没有运气。
还有init_muxer(...)
方法可以设置输出(GIF)的time_base:
o_codec_ctx->time_base = AVRational{1, 12};
所以我对必须设置帧率的所有地方感到有点困惑。
现在,使用 FFMPEG C API 在内存中很好地生成了 GIF(使用调色板)API,唯一的问题是 GIF 速度太快而且帧率不正确。
终于找到了。您必须根据帧率 (12) 和编解码器 time_base(GIF 为 1/100)增加视频点数。
picture_rgb24->pts += av_rescale_q(1, { 1, 12 }, { 1, 100 });
编辑:
更好的是,我发现我可以通过编解码器访问它,而不是对我的发现进行硬编码,而且只需计算一次。
if (ofmt_ctx && ofmt_ctx->nb_streams > 0)
m_pts_increment = av_rescale_q(1, { 1, m_framerate }, ofmt_ctx->streams[0]->time_base);
else
m_pts_increment = av_rescale_q(1, { 1, m_framerate }, { 1, 100 });
只需要做(每一帧)。
picture_rgb24->pts += m_pts_increment;
我有一个图像处理管道,我在内存中有图像可以转换成 AVFrame
,我尝试用这些图像创建 GIF。
我从这个 AVFrame
。
这项工作很好,但我对 GIF 帧率有疑问。
进入init_filters(...)
方法,不明白参数结构的time_base
和pixel_aspect
变量:
snprintf(args, sizeof(args),
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
width, height, in_fmt, time_base.num, time_base.den,
pixel_aspect.num, pixel_aspect.den);
我想要 FPS=12,那么我应该按如下方式定义它们吗?
AVRational time_base = AVRational{1, 12};
AVRational pixel_aspect= AVRational{1, 1};
接下来,在我将帧提供给过滤器缓冲区(对于 palettegen)的循环中,我还有一个我不明白的选项,AVFrame->pts 指的是什么?
// palettegen need a whole stream, just add frame to buffer.
ret = av_buffersrc_add_frame_flags(buffersrc_ctx, picture_rgb24, AV_BUFFERSRC_FLAG_KEEP_REF);
if (ret < 0) {
av_log(nullptr, AV_LOG_ERROR, "error add frame to buffer source %s\n", av_make_error_string(msg_v2, MSG_LEN, ret));
}
picture_rgb24->pts += 1; // HERE
据我了解,它应该是帧的时间戳,在我的情况下,我有一个 GIF,我应该每次增加 1 吗?或 1000 毫秒/12 帧 = 83.33 毫秒?我不确定,我试图找到这些信息,但到目前为止没有运气。
还有init_muxer(...)
方法可以设置输出(GIF)的time_base:
o_codec_ctx->time_base = AVRational{1, 12};
所以我对必须设置帧率的所有地方感到有点困惑。
现在,使用 FFMPEG C API 在内存中很好地生成了 GIF(使用调色板)API,唯一的问题是 GIF 速度太快而且帧率不正确。
终于找到了。您必须根据帧率 (12) 和编解码器 time_base(GIF 为 1/100)增加视频点数。
picture_rgb24->pts += av_rescale_q(1, { 1, 12 }, { 1, 100 });
编辑:
更好的是,我发现我可以通过编解码器访问它,而不是对我的发现进行硬编码,而且只需计算一次。
if (ofmt_ctx && ofmt_ctx->nb_streams > 0)
m_pts_increment = av_rescale_q(1, { 1, m_framerate }, ofmt_ctx->streams[0]->time_base);
else
m_pts_increment = av_rescale_q(1, { 1, m_framerate }, { 1, 100 });
只需要做(每一帧)。
picture_rgb24->pts += m_pts_increment;