Итак, я пытаюсь декодировать поток необработанных данных h264 и рендерить их на поверхность на Android.Вот шаги:
- Получить пакет из потока h264
- Собрать его и попытаться извлечь единицы NAL (байтовые последовательности, начинающиеся с 00 00 00 01 (Заголовок NAL) и до следующего заголовка NAL.
- Для каждого извлеченного блока NAL, вызовите feedFrame (data), где data - это байт [], который начинается с заголовка NAL и содержит извлеченный блок.
- Смотрите видео, предоставленное на предоставленной мной поверхности.
В следующем коде используется AVC-декодер:
public StreamReceiver(DashCamActivity activity, Surface surface, int width, int height, byte[] sps, byte[] pps) {
this.activity = activity;
decoder = MediaCodec.createDecoderByType("video/avc");
format.setByteBuffer("csd-0", ByteBuffer.wrap(sps));
format.setByteBuffer("csd-1", ByteBuffer.wrap(pps));
decoder.configure(format, surface, null, 0);
decoder.start();
}
public void shutdown()
{
decoder.stop();
decoder.release();
}
public void feedFrame(byte[] data)
{
BufferInfo info = new BufferInfo();
int inputIndex = decoder.dequeueInputBuffer(1000);
if(inputIndex == -1)
return;
ByteBuffer inputBuffer = decoder.getInputBuffers()[inputIndex];
if (inputIndex >= 0) {
inputBuffer.clear();
inputBuffer.put(data, 0, data.length);
inputBuffer.clear();
decoder.queueInputBuffer(inputIndex, 0, data.length, 0, 0);
}
int outIndex = decoder.dequeueOutputBuffer(info, 1000);
switch (outIndex) {
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
break;
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
break;
default:
decoder.releaseOutputBuffer(outIndex, true);
break;
}
}
Для меньших разрешений (1024x768, 1280x800) все работает отличноОднако при больших разрешениях (1920x1080, 1900x600), где длина предоставляемого мною байтового массива превышает 65535 (64 КБ), видео начинает иметь заикания и артефакты, а Logcat сообщает о странных ошибках декодера (например, IOCTL_MFC_DEC_EXE не удалось (ret: -2001)на Galaxy S3). Это также происходит на относительно новом устройстве, которое может воспроизводить 4k с удвоенной частотой кадров, которую я предоставляю.и я не знаю, есть ли в моей теории 64k какая-то истина, это всего лишь наблюдение.
Итак, резюмируем:
- Я предоставляю отдельные блоки NAL декодеру,начиная с заголовка.
- Поток h264 имеет базовый профиль, уровень 4.0.
- Запись содержимого блоков NAL в файл в порядке их поступления приводит к созданию видеофайла, который полностьюВоспроизведение с помощью основных медиаплееров
Как заставить его играть в высоком разрешении?