Где хранится пиксельный формат в файле MP.2 H.264? - PullRequest
0 голосов
/ 12 декабря 2018

Я работаю над преобразователем, который преобразует поток RTMP H.264 / AAC в действительный файл MP4.Я в основном готово.Я анализирую тег AMF, читаю AVCDecoderConfigurationRecord и AACSpecificConfig, я генерирую допустимый атом moov и т. Д.

После обнаружения и исправления нескольких ошибок в моем коде у меня появляется в основном действительный файл MP4.Однако, когда я пытаюсь прочитать видео в ffprobe, я получаю следующую ошибку:

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f9fb4000b80] Failed to open codec in avformat_find_stream_info
    Last message repeated 1 times
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f9fb4000b80] Could not find codec parameters for stream 1 (Video: h264 (avc1 / 0x31637661), none, 640x360): unspecified pixel format
Consider increasing the value for the 'analyzeduration' and 'probesize' options

Не удается найти формат пикселей.Просматривая мою логику синтаксического анализа AVCDecoderConfigurationRecord (которая используется для генерации атома avcC как части атома avc1), у меня есть следующее:

// Parsed per: https://github.com/LiminWang/simple-rtmp-server/blob/master/trunk/doc/H.264-AVC-ISO_IEC_14496-15.pdf
var info = parseAVCConfig(packet);

// Fortunately my video sample has one of each of these
// I may need to concatenate multiple in the future
var sps = info.sps[0];
var pps = info.pps[0];

var avcc = box(
    types.avcC,
    new Uint8Array([
        // Version
        0x01,
        // Profile
        info.profile,
        // Profile Compat
        info.compat,
        // Level
        info.level,
        // LengthSizeMinusOne, hard-coded to 4 bytes (copied HLS.js)
        0xfc | 3,
        // 3bit reserved (111) + numOfSequenceParameterSets
        0xE0 | sps.byteLength
    ]
        .concat(Array.from(sps))
        .concat([
            // NumOfPictureParametersets
            pps.byteLength
        ])
        .concat(Array.from(pps))
    )
);

Как вы можете видеть атом avccсодержит профиль, compat и уровень - но после этого я просто копирую SPS и PPS непосредственно из AVCDecoderConfigurationRecord.Нигде в атоме я не определяю формат пикселя, поэтому я предположил, что он является частью SPS или PPS.

Глядя на спецификацию AVCDecoderConfigurationRecord, нет ничего специально называемого «формат пикселя», но есть«chroma_format», «bit_depth_luma_minus8» и «bit_depth_chroma_minus_8» - однако они существуют, только если профиль - 100, 110, 122 или 244. Мой профиль - 66 (и эти байты не существуют для меня)

На данный момент это доказательство концепции, которое я делаю, должно поддерживать только одно видео, поэтому в худшем случае я могу жестко закодировать формат пикселя в yuv420.Но я даже не знаю, куда поместить эту информацию в выходной MP4.Это входит в avcC атом?Или avc1 атом?Или mvhd атом?

Ссылки:

  • buffer.mp4 : это файл, который я создаю, которыйне работает.ffprobe говорит, что не может найти формат пикселей.http://files.stevendesu.com/buffer.mp4
  • test.mp4 : Это сегмент того же видео, преобразованного в MP4 на ffmpeg для сравнения.http://files.stevendesu.com/test.mp4

1 Ответ

0 голосов
/ 12 декабря 2018

Взгляните на chroma_format_idc Рек.МСЭ-T H.264 (04/2017) - 7.3.2.1.1 Синтаксис данных набора параметров последовательности.chroma_format_idc является частью SPS.Для profile_idc 100, 110, 122, 244, 44, 83, 86, 118, 128, 138, 139, 134 или 135 chroma_format_idc хранится внутри SPS.В противном случае вы принимаете 1 (= 4: 2: 0).

7.4.2.1.1 Семантика данных набора параметров последовательности

chroma_format_idc specifies the chroma sampling relative to the luma sampling as specified in clause 6.2. The value of
chroma_format_idc shall be in the range of 0 to 3, inclusive. When chroma_format_idc is not present, it shall be inferred
to be equal to 1 (4:2:0 chroma format).
...