Может ли ffmpeg av libs вернуть точную PTS?

Я работаю с потоком mpeg, который использует последовательность IBBP ... GOP. Значения (DTS, PTS), возвращаемые для первых 4 AVPackets, следующие: I = (0,3) B = (1,1) B = (2,2) P = (3,6)

PTS в I-кадре выглядит так, как будто это законно, но тогда PTS на B-кадрах не может быть прав, так как B-кадры не должны отображаться перед I-фреймом, поскольку их значения PTS указывают. Я также пробовал декодировать пакеты и использовать значение pts в полученном AVFrame, поставить, что PTS всегда устанавливается на ноль.

Есть ли способ получить точную PTS из ffmpeg? Если нет, то какой способ лучше синхронизировать аудио?

0
добавлено
Просмотры: 39

2 ответы

Думаю, я, наконец, понял, что происходит на основе комментария, сделанного в http: //www.dranger. ком/FFmpeg/tutorial05.html :

ffmpeg переупорядочивает пакеты так, что DTS пакета, обрабатываемого avcodec_decode_video (), будет всегда быть тем же самым , что и PTS кадра, который он возвращает

Перевод: если я подаю пакет в avcodec_decode_video (), у которого есть PTS из 12, avcodec_decode_video() не вернет декодированный кадр, содержащийся в этом пакете, пока я не передам ему пакет later , у которого есть DTS 12. Если PTS пакета совпадает с его DTS, тогда указанный пакет совпадает с возвращенным фреймом. Если PTS пакета находится на 2 кадра позже, чем его DTS, avcodec_decode_video() задержит фрейм и не вернет его, пока я не предоставит еще 2 пакета.

Основываясь на этом поведении, я предполагаю, что av_read_frame (), возможно, переупорядочивает пакеты от IPBB до IBBP, так что avcodec_decode_video() должен только буферизовать P кадров для 3 кадров вместо 5. Например, разница между входом и выход P-кадра с этим порядком равен 3 (6 - 3):

|                  I B B P B B P
|             DTS: 0 1 2 3 4 5 6
| decode() result:       I B B P

против разницы 5 со стандартным порядком (6 - 1):

|                  I P B B P B B
|             DTS: 0 1 2 3 4 5 6
| decode() result:       I B B P

but that is pure conjecture.

0
добавлено

Я уверен, что вы получаете точные значения. Это может помочь, если вы используете поток MPEG, а также поток. В этом случае перед IBBPBB, который вы видите, обычно будет другой GOP. Может быть, что-то вроде этого (используя ту же нотацию, что и исходный вопрос):

P(-3,-2)  B(-2,-1)  B(-1,0)

В основном B-кадры после I-фреймов основаны на I-кадре и последнем P-кадре с предыдущей GOP.

Хотя логический смысл для видео начинается с этого:

Start GOP: IPBBPBBPBB...

Позже это должно быть

Start GOP: IBBPBBPBBPBB
Start GOP: IBBPBBPBBPBB
Start GOP: IBB... 

Помните, что для декодирования любого кадра B требуется полный кадр перед ним и после него. Поэтому каждая пара кадров B должна отображаться перед кадром I или P непосредственно перед ним в файле.

FFMPEG может просто отказаться от «специального случая» первой GOP.

Поскольку первые два кадра B не имеют предыдущего кадра для управления, вы должны быть в состоянии безопасно отбросить их. Просто переустановите временные метки с первого кадра I и отрегулируйте аудиопоток равной суммы.

Будет ли это фактически приводить к потере кадров, будет зависеть от реализации FFMPEG, но худший сценарий заключается в том, что вы теряете 83 миллисекунды (2 кадра со скоростью 24 кадра/сек).

0
добавлено
Эти виды хаков (принятие потери в 2 кадра) - это ... hacky :) Позорная документация написана настолько скучно, что почти никто не беспокоится.
добавлено автор Roman Starkov, источник