ffmpeg::avcodec_encode_video 设置 PTS h264

发布于 2024-11-18 19:50:42 字数 389 浏览 6 评论 0原文

我尝试使用 libavcodec 将视频编码为 H264

ffmpeg::avcodec_encode_video(codec,output,size,avframe);

返回错误,指出我没有正确设置 avframe->pts 值.
我尝试将其设置为 0,1、AV_NOPTS_VALUE 和 90khz * 帧号,但仍然收到错误 non-strictly-monotonic PTS

ffmpeg.c 示例使用 ffmpeg::av_rescale_q() 设置 packet.pts但这仅在对帧进行编码后才会调用!

当与 MP4V 编解码器一起使用时,avcodec_encode_video() 本身会正确设置 pts 值。

I'm trying to encode video as H264 using libavcodec

ffmpeg::avcodec_encode_video(codec,output,size,avframe);

returns an error that I don't have the avframe->pts value set correctly.
I have tried setting it to 0,1, AV_NOPTS_VALUE and 90khz * framenumber but still get the error non-strictly-monotonic PTS

The ffmpeg.c example sets the packet.pts with ffmpeg::av_rescale_q() but this is only called after you have encoded the frame !

When used with the MP4V codec the avcodec_encode_video() sets the pts value correctly itself.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无言温柔 2024-11-25 19:50:42

我遇到了同样的问题,通过在调用 avcodec_encode_video 之前计算 pts 来解决它,如下所示:

//Calculate PTS: (1 / FPS) * sample rate * frame number
//sample rate 90KHz is for h.264 at 30 fps
picture->pts = (1.0 / 30) * 90 * frame_count;
out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);

这篇有用的博客文章

(注意:将采样率更改为 khz,以 hz 表示,帧之间的时间太长,可能需要使用此价值 - 不是这里的视频编码专家,只是想要一些有用的东西,而这确实)

I had the same problem, solved it by calculating pts before calling avcodec_encode_video as follows:

//Calculate PTS: (1 / FPS) * sample rate * frame number
//sample rate 90KHz is for h.264 at 30 fps
picture->pts = (1.0 / 30) * 90 * frame_count;
out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);

Solution stolen from this helpful blog post

(Note: Changed sample rate to khz, expressed in hz was far too long between frames, may need to play with this value - not a video encoding expert here, just wanted something that worked and this did)

七月上 2024-11-25 19:50:42

我也有这个问题。我用这种方式解决了这个问题:

在调用之前,

ffmpeg::avcodec_encode_video(codec,output,size,avframe);

将 avframe 的 pts 值设置为一个整数值,该值的初始值是 0 并且每次递增 1,就像这样:

avframe->pts = nextPTS();

nextPTS() 的实现是:

int nextPTS()
{
    static int static_pts = 0;
    return static_pts ++;
}

在给出 pts 之后avframe 的值,然后对其进行编码。如果编码成功。添加以下代码:

    if (packet.pts != AV_NOPTS_VALUE)
        packet.pts = av_rescale_q(packet.pts, mOutputCodecCtxPtr->time_base, mOutputStreamPtr->time_base);
    if (packet.dts != AV_NOPTS_VALUE)
         packet.dts = av_rescale_q(packet.dts, mOutputCodecCtxPtr->time_base, mOutputStreamPtr->time_base);

它将为编码的 AVFrame 添加正确的 dts 值。其中代码中,packe类型为AVPacket,mOutputCodeCtxPtr类型为AVCodecContext*,mOutputStreamPtr类型为AVStream。

avcodec_encode_video 返回 0 表示当前帧已缓冲,您必须在所有帧编码后刷新所有缓冲帧。该代码刷新所有缓冲的帧,有点像:

int ret;
while((ret = ffmpeg::avcodec_encode_video(codec,output,size,NULL)) >0)
    ;// place your code here.

I had this problem too. I sloved the problem in this way:

Before you invoke

ffmpeg::avcodec_encode_video(codec,output,size,avframe);

you set the pts value of avframe an integer value which has an initial value 0 and increments by one every time, just like this:

avframe->pts = nextPTS();

The implementation of nextPTS() is:

int nextPTS()
{
    static int static_pts = 0;
    return static_pts ++;
}

After giving the pts of avframe a value, then encoded it. If encoding successfully. Add the following code:

    if (packet.pts != AV_NOPTS_VALUE)
        packet.pts = av_rescale_q(packet.pts, mOutputCodecCtxPtr->time_base, mOutputStreamPtr->time_base);
    if (packet.dts != AV_NOPTS_VALUE)
         packet.dts = av_rescale_q(packet.dts, mOutputCodecCtxPtr->time_base, mOutputStreamPtr->time_base);

It'll add correct dts value for the encoded AVFrame. Among the code, packe of type AVPacket, mOutputCodeCtxPtr of type AVCodecContext* and mOutputStreamPtr of type AVStream.

avcodec_encode_video returns 0 indicates the current frame is buffered, you have to flush all buffered frames after all frames have been encoded. The code flushs all buffered frame somewhat like:

int ret;
while((ret = ffmpeg::avcodec_encode_video(codec,output,size,NULL)) >0)
    ;// place your code here.
梓梦 2024-11-25 19:50:42

我也有这个问题。据我记得,该错误与 dts

设置

out_video_packet.dts = AV_NOPTS_VALUE;

有关帮助我

I had this problem too. As far as I remember, the error is related to dts

setting

out_video_packet.dts = AV_NOPTS_VALUE;

helped me

辞旧 2024-11-25 19:50:42

严格递增单调函数是 f(x) < 的函数。 f(y) 如果 x < y。
所以这意味着你不能像你所做的那样使用相同的 PTS 编码 2 个帧......例如用计数器检查,它不应该再返回错误。

A strictly increase monotonic function is a function where f(x) < f(y) if x < y.
So it means you cannot encode 2 frames with the same PTS as you were doing... check for example with a counter and it should not return error anymore.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文