ffmpeg::avcodec_encode_video setting PTS h264

Ask Question

up vote11down votefavorite

4

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.

c++ h.264 video-encoding avcodec

shareimprove this question

asked Jul 6 '11 at 22:49

Martin Beckett

78.5k18159236

  • 2

    With a newer version off ffmpeg simple setting " ppicture->pts=pCodecCtx->frame_number;" works – Martin Beckett Feb 24 '12 at 1:07

add a comment

4 Answers

activeoldestvotes

up vote6down vote

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)

shareimprove this answer

edited Feb 24 '12 at 0:33

answered Feb 24 '12 at 0:25

Ozone

372511

add a comment

up vote2down vote

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.

shareimprove this answer

edited Oct 10 '12 at 2:04

answered Oct 9 '12 at 16:56

Alanmars

952920

  • What about when your nextPTS function overflows (i.e. static_pts > INT_MAX) ? – tmatth Nov 13 '12 at 19:09

  • If static_pts is in danger of overflowing, just changing its type from int to int64_t. – Alanmars Nov 19 '12 at 6:17

add a comment

up vote0down vote

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

shareimprove this answer

answered Jul 10 '11 at 22:42

Ulterior

1,67522045

add a comment

up vote0down vote

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.

shareimprove this answer

answered Feb 12 '12 at 22:48

manast

863

add a comment

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值