Тестовое задание

Тут небольшой кусок старого (ещё опенсорсного) 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). Предлагаем искать проблему исходя из этого различия.