Тут небольшой кусок старого (ещё опенсорсного) erlyvideo (ныне Flussonic).
В этом коде есть баг -- файл не декодируется, хотя после перепаковки другим инструментом декодируется успешно.
erl -make
Собранный байткод кладётся в каталог ebin
.
Файл не читается:
3> element(3, mpegts_reader:read_file("test/bad.ts")).
[]
Файл с теми же данными, но перепакованными, читается корректно, видны #video_frame{}
в возвращаемом значении:
4> element(3, mpegts_reader:read_file("test/repacked.ts")).
mpegts_reader:382 {"New pid",psi,undefined,4095}
mpegts_reader:382 {"New pid",pes,h264,256}
mpegts_reader:382 {"New pid",pes,aac,257}
mpegts_reader:291 {"Synced PES",257}
mpegts_reader:291 {"Synced PES",256}
[{video_frame,audio,19330377.933333334,19330377.933333334,0,
aac,config,
{stereo,bit16,rate44},
<<18,16>>,
undefined},
{video_frame,audio,19330377.933333334,19330377.933333334,0,
aac,frame,
{stereo,bit16,rate44},
<<33,24,79,235,84,0,2,182,144,202,65,138,128,75,128,0,0,
45,...>>,
undefined},
{video_frame,video,19330384.933333334,19330384.933333334,0,
h264,config,
{undefined,undefined,undefined},
<<1,77,0,31,255,225,0,25,103,77,64,31,217,0,176,51,251,...>>,
undefined},
{video_frame,video,19330384.933333334,19330384.933333334,0,
h264,keyframe,
{undefined,undefined,undefined},
<<0,0,121,164,101,136,132,5,127,254,247,173,223,129,77,
195,...>>,
undefined},
...
Доработать модуль mpegts_reader
так, чтобы из файла test/bad.ts
читались фреймы.
Изменения должны быть небольшими.
Кроме самих изменений ожидаем увидеть протокол работы -- какими способами искали проблему,
какие знания дал каждый способ, как принимали решение о том, в каком месте и как дорабатывать.
Формат вкратце описан в википедии: https://ru.wikipedia.org/wiki/MPEG-TS
Устроен MPEG-TS примерно так:
- поток состоит из 188-байтных пакетов, разделённых на логические потоки (
pid
), в заголовке каждого пакета есть pid pid = 0
занят служебной таблицей PAT, в которой содержится список "программ" в видеProgramID -> PMT pid
(нулевая программа, если есть, не считается, она служебная)- На тех pid-ах, которые указаны в PAT, приходят служебные таблицы PMT, в которых указано, из каких медиа-дорожек состоит поток, в виде (условно)
[{MediaPid, Codec, SomeInfo}]
- В pid-ах, которые описаны в PMT, приходят уже данные с видео, аудио и прочими медиа-данными. Фрейм (видео-кадр или 21 миллисекунда аудио) пакуется в т.н. PES, который разбивается по куче пакетов.
- Есть ещё несколько служебных зарезервированных pid-ов (для таблиц SDT, TDT и прочих), но они не влияют на процесс извлечения фреймов.
В примере выше видно, что нет вывода о добавлении новых пидов (записи New pid
). Предлагаем искать проблему исходя из этого различия.