Ручное кодирование в MPEG-TS

ТАК...

Я пытаюсь взять потоковое видео байта Приложения B H264 и кодировать его в MPEG-TS на чистой Java. Моя цель - создать минимальный MPEG-TS, единую программу, действительный поток и не включать какую-либо информацию о времени (PCR, PTS, DTS).

В настоящее время я нахожусь в точке, где мой сгенерированный файл может быть передан в отчеты ffmpeg (ffmpeg -i myVideo.ts) и ffmpeg...

[NULL @ 0x7f8103022600] start time is not set in estimate_timings_from_pts

Input #0, mpegts, from 'video.ts':
Duration: N/A, bitrate: N/A
Program 1 
  Stream #0:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc

... кажется, что это предупреждение для времени запуска не имеет большого значения... и ffmpeg не может определить, как долго это видео. Если я создаю другой файл mpeg-ts из моего видеофайла (ffmpeg -i myVideo.ts -vcodec copy validVideo.ts) и запускаю ffmpeg -i validVideo.ts, я получаю...

Input #0, mpegts, from 'video2.ts':
Duration: 00:00:11.61, start: 1.400000, bitrate: 3325 kb/s
Program 1 
  Metadata:
    service_name    : Service01
    service_provider: FFmpeg
  Stream #0:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc

... так что вы можете видеть информацию о времени и битрейте, а также метаданные.

Мое видео H264 состоит только из I и P-кадров (с SPS и PPS, предшествующими I-кадру, конечно), и способ, которым я создаю свой поток MPEG-TS,...

  1. Написать один PAT в начале файла
  2. Написать один PMT в начале файла
  3. Создайте пакеты TS и PES из SPS, PPS и I-кадра (тоже AUD NAL, если это требуется?)
  4. Создание пакетов TS и PES из P-кадра (опять же, AUD NAL тоже, если требуется)
  5. Для последней полезной нагрузки I-кадра или P-кадра добавьте байты-заполнители в поле адаптации, чтобы убедиться, что он вписывается в полный пакет TS
  6. Повторите 3-5 для всего файла

... мой PAT выглядит так...

4740 0010 0000 b00d 0001 c100 0000 01f0
002a b104 b2ff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff

... и мой PMT выглядит так...

4750 0010
0002 b012 0001 c100 00ff fff0 001b e100
f000 c15b 41e0 ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff

... обратите внимание, после c100 00, "ff ff", f0... говорит, что мы не используем PCR... Также обратите внимание, что я обновил свой CRC, чтобы отразить это изменение в PMT. Мой первый пакет I Frame выглядит так...

4741 0010 0000 01e0
0000 8000 0000 0000 0109 f000 0000 0127
4d40 288d 8d60 2802 dd80 b501 0101 4000
00fa 4000 3a98 3a18 00b7 2000 3380 2ef2
e343 0016 e400 0670 05de 5c16 345d c000
0000 0128 ee3c 8000 0000 0165 8880 0020
0000 4fe5 63b5 4e90 b11c 9f8f f891 10f3
13b1 666b 9fc6 03e9 e321 36bf 1788 347b
eb23 fc89 5772 6e2e 1714 96df ed16 9b30
252d ceb7 07e9 a0c7 c6e7 9515 be87 2df1
81f3 b9d2 ba5f 243e 2d5c cba2 8ca5 b798
6bec 8c43 0b5d bbda bc5b 6e7c e15c 84e8
2f13 be84 

... вы заметите, что после 01e0 0000, 8000 00 - это расширение заголовка PES, где я не указываю PTS / DTS, а оставшаяся длина равна нулю. Мой первый пакет P Frame выглядит так...

4741 001d
0000 01e0 0000 8000 0000 0000 0109 f000
0000 0141 9a00 0200 0593 ff45 a7ae 1acd
f2d7 f9ec 557f cdb6 ba38 60d6 a626 5edb
4bb9 9783 89e2 d7e1 102e 4625 2fbf ce16
f952 d8c9 f027 e55a 6b2a 81c3 48d4 6a45
050a f355 fbec db01 6562 6405 04aa e011
50ec 0b45 45e5 0df7 2fed a3f8 ac13 2e69
6739 6d81 f13d 2455 e6ca 1c6b dc96 65d5
3bad f250 7dab 42e4 7ba9 f564 ee61 29fb
1b2c 974c 6924 1a1f 99ef 063c b99a c507
8c22 b0f8 b14c 3e4d 01d0 6120 4e19 8725
2fda 6550 f907 3f87

... и когда I-кадр или P-кадр заканчиваются, у меня есть пакет TS с полем адаптации, например...

4701 003c b000 ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff

... где первые b0 байтов являются байтами заполнения поля адаптации, а оставшиеся - последними байтами I или P кадра. Итак, как вы можете сказать, я могу использовать ffmpeg и передать его в свой файл, чтобы создать действительный фильм в любом формате. Тем не менее, мне нужно, чтобы файл, который я создаю, был в правильном формате, и я не могу понять, какая последняя часть мне не хватает. Есть идеи?

1 ответ

Решение

У вас противоречивые требования. "действительный поток" и "не включать в себя какую-либо временную информацию" несовместимы. Требование TS - проводить ПЦР как минимум каждые 100 миллисекунд. И хотя они специфичны для каждого игрока, большинство игроков не будут "представлять" кадр без "отметки времени представления". Вы можете получить временную метку из данных VUI, но она должна существовать в контейнере.

Другие вопросы по тегам