Как MediaExtractor определяет, что нужно поместить в блоки H264 NAL?

Я изучил выходные данные MediaExtractor на двух устройствах Android, и оказалось, что он создает на них немного разные сэмплы для одного и того же видеофайла.

В одном устройстве блоки NAL, не относящиеся к VCL, объединяются со следующим блоком VCL для создания выборки. На другом устройстве каждый блок, не относящийся к VCL, представляет собой полный образец.

Еще одно отличие: на одном устройстве образцы имеют начальный 0 байт и префикс начального кода (001) в образце; с другой стороны, эти байты опущены.

Если я попытаюсь использовать формат единиц NAL для первого устройства на другом устройстве, видео не будет воспроизводиться.

Если я создаю свои собственные блоки NAL (не используя MediaExtractor), есть ли принципиальный способ узнать, какой формат ожидает декодер MediaCodec H264?


person Paul Steckler    schedule 27.02.2015    source источник
comment
Я должен упомянуть, что я подаю эти блоки NAL во входной буфер MediaCodec.   -  person Paul Steckler    schedule 27.02.2015
comment
почему бы не посмотреть исходник? android.googlesource.com/ платформа/фреймворки/база/+/   -  person szatmary    schedule 28.02.2015
comment
Образец — это то, что производит readSampleData. Исходный код Java не очень помогает, потому что он вызывает собственный код, который сам вызывает код более низкого уровня.   -  person Paul Steckler    schedule 28.02.2015


Ответы (1)


Официальным способом является наличие префиксов начального кода (которые необходимы для наличия нескольких единиц NAL в одном пакете) — это то, что ожидают все декодеры OpenMAX IL (стандарт, используемый внутри MediaCodec) (даже если некоторые также могут поддерживать другие форматы). ). Независимо от того, есть ли у вас SPS/PPS в отдельном буфере (с установленным флагом BUFFER_FLAG_CODEC_CONFIG) или в начале буфера с модулями VCL NAL, не должно иметь значения — я думаю, что декодеры должны иметь возможность обрабатывать и то, и другое. Я не думаю, что вы найдете какой-либо отдельный документ, разъясняющий это для Android, кроме неявного вывода из того, что на самом деле делают устройства.

Можете ли вы назвать, какие устройства (и какие версии платформ) выводят какую комбинацию этих вариантов битового потока, и какая комбинация не работает на каком устройстве? Насколько я знаю, поток с присутствующими стартовыми кодами должен работать везде, но, конечно, могут быть исключения. Начиная с Android 4.3, эти функции должны работать намного лучше, чем в версиях 4.1 и 4.2.

Некоторые поставщики, кажется, делают нестандартные вещи в MediaExtractor - я написал отчет об ошибке по адресу https://code.google.com/p/android/issues/detail?id=74356. В этом случае особое нестандартное поведение Samsung сигнализируется с помощью ключа isDMCMMExtractor=1 в MediaFormat. Я действительно согласен с тем, что MediaExtractor должен быть более строгим, потому что сейчас он в основном используется только для передачи данных в MediaCodec (где предполагается, что он понятен, по крайней мере, для аппаратных кодеков конкретного поставщика), но трудно сказать, что он на самом деле делает. , если приложение хочет сделать что-то еще с выходными данными MediaExtractor (например, декодировать с помощью стороннего декодера или отправить извлеченные данные по сети и т. д.).

Если какое-то устройство не может декодировать де-факто стандартный формат битового потока (но успешно только в том случае, если оно искажено так, как это делает MediaExtractor этой платформы), похоже, требуется еще один тест на совместимость с CTS путем тестирования декодирования необработанных, жестко закодированных пакетов (так что что MediaExtractor не может вмешиваться и преобразовывать вещи). Правильно ли работают на этом устройстве тесты CTS, такие как EncodeDecodeTest (см. http://bigflake.com/mediacodec/)? Если это так, но если декодирование стандартных форматов пакетов не удается, это будет означать, что кодировщик устройства также выдает что-то нестандартное.

person mstorsjo    schedule 01.03.2015
comment
Устройство с префиксом стартового кода и конкатенированными устройствами, не относящимися к VCL, — это Nexus 7 2013 года под управлением Android 5.01. Устройство без префикса стартового кода и отдельных блоков не-VCL - это телефон Huawei (извините, нет модели или версии Android, кто-то еще тестирует). - person Paul Steckler; 01.03.2015
comment
Я еще не пробовал тесты CTS на этих устройствах. - person Paul Steckler; 01.03.2015
comment
Какую комбинацию битового потока вы протестировали, но она не сработала? Я предполагаю, что пакеты без стартовых кодов не будут работать на Nexus 7, а пакеты со стартовыми кодами, вероятно, должны работать на Huawei. - person mstorsjo; 01.03.2015
comment
Правильно, пакеты без стартовых кодов на Нексусе не проходят. - person Paul Steckler; 01.03.2015