2014-01-03 3 views
13

Как вычислить правильное значение PTS для кадра перед кодированием в API FFmpeg C?Рассчитать PTS до кодирования кадра в FFmpeg

Для кодирования Я использую функцию avcodec_encode_video2, а затем напишу ее av_interleaved_write_frame.

Я нашел несколько формул, но ни один из них не работает.

В doxygen example они используют

frame->pts = 0; 
for (;;) { 
    // encode & write frame 
    // ... 
    frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base); 
} 

This blog говорит, что формула должна быть такой:

(1/FPS) * Частота дискретизации * номер кадра

Кто-то использует только номер кадра для установки очков:

frame->pts = videoCodecCtx->frame_number; 

Или альтернативный способ:

int64_t now = av_gettime(); 
frame->pts = av_rescale_q(now, (AVRational){1, 1000000}, videoCodecCtx->time_base); 

И последнее:

// 40 * 90 means 40 ms and 90 because of the 90kHz by the standard for PTS-values. 
frame->pts = encodedFrames * 40 * 90; 

Какой из них правильный? Думаю, ответ на этот вопрос будет полезен не только для меня.

ответ

2

Существует также опция с настройкой frame->pts = av_frame_get_best_effort_timestamp(frame), но я не уверен, что это правильный подход.

Мне очень жаль, что не было лучшего руководства для практики, как справиться с этим. Вы случайно нашли решение самостоятельно? Было бы здорово, если бы вы могли обновить сообщение своим решением.

+0

Это не отвечает на вопрос. Если у вас есть другой вопрос, вы можете задать его, нажав [Ask Question] (http://stackoverflow.com/questions/ask). Вы также можете [добавить щедрость] (http://stackoverflow.com/help/privileges/set-bounties), чтобы привлечь больше внимания к этому вопросу, как только у вас будет достаточно [репутации] (http://stackoverflow.com/help/ Что-репутация). – Nunser

+0

@Nunser Он не может комментировать еще с 1 репутацией или установить щедрость, так что это его единственный способ показать, что он все еще заинтересован в этом, не задавая еще одного вопроса о PTS/DTS. Во всяком случае, я принял удар по нему ниже. – Jack

+0

@Jack Эти комментарии (например, мои) генерируются автоматически, когда мы делаем время в очередях просмотра и ответах с флагом, поэтому я действительно не могу контролировать то, что опубликовано как комментарий от меня. Я понимаю, что он не может комментировать, но по-прежнему не является правильным ответом ... может быть, если он удалит «нашли ли вы решение? Обновите свой пост с ним», что явно не является ответом, то это не будет отмечено , Например, ваш ответ предлагает решение, это один из способов сделать и добавляет ненужные комментарии, которые могут быть недовольны рецензентами. – Nunser

9

Лучше подумать о PTS более абстрактно, прежде чем пытаться использовать код.

Что вы делаете, так это совокупность 3 «временных наборов». Первое - это время, к которому мы привыкли, на основе 1000 мс в секунду, 60 секунд в минуту и ​​т. Д. Второй - время кодека для конкретного кодека, который вы используете. Каждый кодек имеет определенный способ, чтобы он представлял время, обычно в формате 1/номер, что означает, что на каждую секунду имеется количество «количества» тиков. Третий формат работает аналогично второму, за исключением того, что вы используете временную базу для контейнера.

Некоторые люди предпочитают начинать с фактического времени, другие отсчеты кадров, ни один «неправильный».

Начиная с отсчета кадров, вы должны сначала преобразовать его на основе частоты кадров. Примечание все конверсии Я говорю об использовании av_rescale_q (...). Цель этого преобразования состоит в том, чтобы включить счетчик во времени, так что вы перемасштабируете свою частоту кадров (обычно используется база времени паролей). Затем вам нужно преобразовать это в time_base вашего видеокодека перед кодированием.

Аналогично, в реальном времени ваше первое преобразование должно быть от current_time - start_time, масштабированного до вашего времени видеокодека.

Любой, кто использует только счетчик кадров, вероятно, использует кодек с временем_базой, равным их частоте кадров. Большинство кодеков не работают так, и их хак не переносится.Пример:

frame->pts = videoCodecCtx->frame_number; // BAD 

Кроме того, любое использование жестко закодированных чисел в их av_rescale_q задействует тот факт, что они знают, что их time_base есть и этого следует избегать. Код не переносится в другие видеоформаты. Вместо этого используйте video_st-> time_base, video_st-> codec-> time_base и output_ctx-> time_base, чтобы понять, что происходит.

Я надеюсь, что понимание этого с более высокого уровня поможет вам понять, какие из них являются «правильными» и которые являются «плохой практикой». Нет единого ответа, но, возможно, теперь вы можете решить, какой из них лучше всего подходит для вас.

+0

«ничто не« неправильно ». -конечно некоторые из них. Первый пример пользователя и один сразу после «Или альтернативный способ:» не производят один и тот же PTS. Фактически, только первый производит для меня правильный PTS. –

Смежные вопросы