Вопрос: Почему я ... Я имею в виду, что происходит с моим декодером? Он всегда возвращает время ожидания (-1), когда я пытаюсь получить его сочные выходные данные!Проблемы с декодером MediaCodec с вызовом dequeueOutputBuffer (H.264)
Позвольте мне сказать, что я прочитал относительные темы, но все еще не могу решить проблему. Мне действительно нужно некоторое руководство и помощь здесь. Хорошо, поэтому то, что я делаю, это передача данных, закодированных AVC, на мой декодер. Кодер работает, вытягивая данные из предварительного просмотра камеры, где я делаю преобразование с NV21 на NV12, прежде чем перейти к кодировщику.
Первые данные, доступные в кодере, имеют codec-specific-data
, которые я передаю в функцию ConfigureDecoder(ByteBuffer csd0, ByteBuffer csd1)
для создания и настройки декодера, который не вызывает никаких ошибок.
public void ConfigureDecoder(ByteBuffer csd0, ByteBuffer csd1)
{
try
{
decoder = MediaCodec.createDecoderByType(MIME_TYPE);
}
catch(IOException e)
{
Log.d(TAG, "Decoder codec creation failed: " + e.toString());
}
MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, 320, 240);
format.setByteBuffer("csd-0", csd0);
format.setByteBuffer("csd-1", csd1);
decoder.configure(format, null, null, 0);
try
{
decoder.start();
Log.d(TAG, "Decoder configured");
}
catch(CodecException e)
{
Log.d(TAG, "Decoder config start failed: " + e.getDiagnosticInfo());
}
}
Следующая функция вызывается один раз кодер уведомляет, что есть кодированные данные доступны (после данных конкретного кодека). Во-первых, я получаю доступный буфер ввода декодера, в случае успеха заполняю его закодированными данными (проверенными) и добавляю их в очередь декодирования. Тогда все идет в ад, я пытаюсь извлечь данные из декодера, используя dequeueOutputBuffer(bufferInfo, 0);
, который всегда возвращает -1.
public void offerDecoder(byte[] input, int offset, int size, long presentationTimeUs, int flags)
{
int inputBufIndex = decoder.dequeueInputBuffer(10000);
Log.d(TAG, "Decoder dequeueInputBuffer = " + inputBufIndex);
if(inputBufIndex >= 0)
{
try
{
// Get valid buffer and push into the decoder input buffer
ByteBuffer inputBuf = decoder.getInputBuffer(inputBufIndex);
inputBuf.clear();
inputBuf = ByteBuffer.wrap(input);
decoder.queueInputBuffer(inputBufIndex, 0, size, presentationTimeUs, flags);
}
catch(MediaCodec.CodecException ce)
{
Log.d(TAG, "Decoder adding data error: " + ce.getDiagnosticInfo());
}
}
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int outIndex = decoder.dequeueOutputBuffer(bufferInfo, 0);
Log.d(TAG, "Decoder dequeueOutputBuffer = " + outIndex);
switch(outIndex)
{
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
ByteBuffer outputBuffers = decoder.getOutputBuffer(outIndex);
Log.d(TAG, "Decoder dequeueOutputBuffer = INFO_OUTPUT_BUFFERS_CHANGED");
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
//MediaFormat bufferFormat = decoder.getOutputFormat(outIndex);
Log.d(TAG, "Decoder dequeueOutputBuffer = INFO_OUTPUT_FORMAT_CHANGED");
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
//Total fail, something is really wrong if you are always receiving -1 from dequeueOutputBuffer
//Log.d(TAG, "Decoder dequeueOutputBuffer = INFO_TRY_AGAIN_LATER");
break;
default:
Log.d(TAG, "Decoder out buffer info-->" + bufferInfo.offset + "--" + bufferInfo.size + "--" + bufferInfo.flags + "--" + bufferInfo.presentationTimeUs);
ByteBuffer buffer = decoder.getOutputBuffer(outIndex);
decoder.releaseOutputBuffer(outIndex, false);
break;
}
}
Если ваш достиг этой точки в посте я очень ценю ваше время :)
IIRC, кодеки AVC хотят, чтобы их подавали около четырех блоков доступа, прежде чем они начнут что-либо делать. Я ожидаю, что это изменится между устройствами. http://bigflake.com/mediacodec/ – fadden