android - декодер MediaCodec 1080p вывод в формате yuv

Android MediaCodec можно использовать для декодирования выходного формата yuv420. Я предполагаю, что это должен быть формат NV12, но когда я пробую его на устройстве Nexus6 7.1.1. Результат очень странный:

  1. Для видео 720p он работает нормально, выходной yuv можно воспроизвести с помощью ffplay с помощью следующей команды:

    ffplay -v info -f rawvideo -pixel_format yuv420p -video_size 1280x720 out.yuv

    И размер файла out.yuv в точности равен ширине * высоте * 3/2.

  2. Для видео 1080p цвет yuv на выходе вверху не корректируется. Размер файла out.yuv равен 3133440, но ширина * высота * 3/2 должна быть 3110400, так что есть еще 23040 байт. Похоже, цвет верхнего слоя неправильный.

введите описание изображения здесь

Когда пытаешься расшифровать это на поверхность, это выглядит хорошо. поэтому я предполагаю, что проблема возникает только из пакета YUV 1080p.


person lucky1928    schedule 25.04.2017    source источник
comment
Не используйте вывод yuv, используйте вместо него вывод изображения. см. developer.android.com/reference/android/media /.   -  person beetlej    schedule 25.04.2017


Ответы (1)


Для 1080p очень вероятно, что высота фактического декодированного изображения будет 1920x1088, а не 1920x1080. (1920x1088 в сумме дает размер 3133440.) Самые нижние 8 пикселей декодируются и возвращаются, но вы не должны их показывать.

В этом случае поле MediaFormat.KEY_HEIGHT в выходных данных MediaFormat, вероятно, равно 1088, в то время как поле crop-top равно 0, а crop-bottom - 1079. См. https://android.googlesource.com/platform/cts/+/jb.-mr2-release/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java#976, чтобы посмотреть, как читаются эти поля.

Как предложил beetlej, если вы используете класс Image, полученный от < метод href = "https://developer.android.com/reference/android/media/MediaCodec.html#getOutputImage(int)" rel = "nofollow noreferrer"> _ 6_ (доступен с Android 5.0), о деталях позаботимся.

person mstorsjo    schedule 25.04.2017
comment
@mstrosjo точно, вывод составляет 1920x1088, а размер кадрирования - 1079. Если я скармливаю такой yuv кодировщику, должен ли я также добавить свойство кадрирования, если нет, означает ли это, что кодировщик выполнит преобразование из 1920x1088 в 1920x1080? - person lucky1928; 25.04.2017
comment
На самом деле не определено, как передавать такие данные в кодировщик - официальное предложение состоит в том, чтобы использовать Surface или Image для ввода, который должен позаботиться обо всем этом. На практике, насколько я знаю, вам не нужно делать это заполнение для высоты при кодировании на любом устройстве, насколько я помню. Однако ширина, которая не делится на 16, является более проблематичной; на некоторых устройствах он отлично работает с любой шириной, в то время как другие требуют, чтобы вы увеличивали ширину входных данных до 16 пикселей. - person mstorsjo; 25.04.2017