ffmpeg :: avcodec_encode_video настройка PTS h264 - PullRequest
11 голосов
/ 07 июля 2011

Я пытаюсь кодировать видео как H264, используя libavcodec

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

возвращает ошибку, что у меня не правильно установлено значение avframe-> pts.
Я попытался установить его на 0,1, AV_NOPTS_VALUE и 90 кГц * framenumber, но все равно получаю ошибку non-strictly-monotonic PTS

Пример ffmpeg.c устанавливает package.pts с помощью ffmpeg :: av_rescale_q (), но это вызывается только после того, как вы закодировали кадр!

При использовании с кодеком MP4V функция avcodec_encode_video () сама устанавливает значение pts правильно.

Ответы [ 4 ]

7 голосов
/ 24 февраля 2012

У меня была та же проблема, я решил ее путем вычисления очков перед вызовом avcodec_encode_video следующим образом:

//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 была слишком длинной между кадрами, возможно, придется поиграть с этим значением - здесь не эксперт по кодированию видео, просто хотел что-то, что сработало, и это сработало)

2 голосов
/ 09 октября 2012

У меня тоже была эта проблема. Я решил проблему таким образом:

Перед тем как вызвать

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

Вы устанавливаете значение pts для avframe целочисленного значения, которое имеет начальное значение 0 и увеличивается на единицу каждый раз, как показано ниже:

avframe->pts = nextPTS();

Реализация nextPTS ():

int nextPTS()
{
    static int static_pts = 0;
    return static_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);

Это добавит правильное значение dts для закодированного AVFrame. Среди кода - пакет типа 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.
0 голосов
/ 13 февраля 2012

Строго возрастающая монотонная функция - это функция, где f (x)

0 голосов
/ 11 июля 2011

У меня тоже была эта проблема. Насколько я помню ошибка связана с dts

установка

out_video_packet.dts = AV_NOPTS_VALUE;

помог мне

...