Intereting Posts
Использование Android Studio с Vuforia Android Gradle создает TransformException: java.util.zip.ZipException: ошибка при открытии zip-файла во время transformClassesWithDexForRelease Переходы общих элементов не работают в сочетании с координаторомLayout и CollapsingToolbarLayout Как создать экземпляр класса фрагмента с использованием имени класса вместо индекса Масштабный коэффициент для xxhdpi android? Модернизация POST-запроса с базовой аутентификацией HTTP: «Невозможно повторить потоковое тело HTTP» Добавить новый столбец в существующую таблицу MySeQL и без перекрытия существующих значений таблицы Pinch увеличить в android 2.1 Слишком много шаблонов, как я могу уменьшить свои строители POJO? Как добраться, когда произошло последнее касание на экране? Как создать проект Android-градиента, содержащий модули с различными compileSdkVersion, targetSdkVersion и minSdkVersion? Как создать пользовательский счетчик, как рамка вокруг спиннера с треугольником вниз с правой стороны? MediaScannerConnection # scanFile преобразует каталоги в файлы при доступе к ним с помощью USB-MTP на Android 5 Lollipop Как разделить неонные свойства на число с плавающей точкой Байт-коды dalvik с расширенной шириной, отсутствующие на Jellybean

Android MediaCodec декодирует h264 необработанный кадр

Я использую Android MediaCodec API для декодирования кадров h264. Я мог бы декодировать и визуализировать фреймы на представлении. Моя проблема заключается в том, что декодер пропускает множество кадров, особенно первые несколько кадров. DecodeMediaCodec.dequeueOutputBuffer () return -1. AAbout 150 кадров h264, просто декодировано 43 кадра. Я не могу найти, где проблема. Вот мои коды.

/** * init decoder */ private void initDecodeMediaCodec() { mDecodeMediaCodec = MediaCodec.createDecoderByType(MIME_TYPE); MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, VIDEO_WIDTH_640, VIDEO_HEIGHT_480); mDecodeMediaCodec.configure(format, new Surface(mRemoteVideoView.getSurfaceTexture()), null, 0); mDecodeMediaCodec.start(); mDecodeInputBuffers = mDecodeMediaCodec.getInputBuffers(); System.out.println("decode-----" + mDecodeMediaCodec.getCodecInfo().getName()); } 

После начального декодера я начну поток декодера.

  /** * * @param frameData */ private void decode() { new Thread(new Runnable() { @Override public void run() { while (true) { ByteBuffer decodeDataBuffer = null; try { //take h264 frame from cache queue decodeDataBuffer = decodeDataQuene.take(); } catch (InterruptedException e) { e.printStackTrace(); } BufferInfo info = new BufferInfo(); int inputBufferIndex = mDecodeMediaCodec.dequeueInputBuffer(-1); System.out.println("inputBufferIndex: " + inputBufferIndex); if (inputBufferIndex >= 0) { ByteBuffer buffer = mDecodeInputBuffers[inputBufferIndex]; buffer.clear(); buffer.put(decodeDataBuffer.array()); mDecodeMediaCodec.queueInputBuffer(inputBufferIndex, 0, decodeDataBuffer.array().length, 0, 0); decodeDataBuffer.clear(); decodeDataBuffer = null; } int outputBufferIndex = mDecodeMediaCodec.dequeueOutputBuffer(info, 1000); System.out.println("outputBufferIndex: " + outputBufferIndex); do { if (outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) { //no output available yet } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { //encodeOutputBuffers = mDecodeMediaCodec.getOutputBuffers(); } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { MediaFormat formats = mDecodeMediaCodec.getOutputFormat(); //mediaformat changed } else if (outputBufferIndex < 0) { //unexpected result from encoder.dequeueOutputBuffer } else { mDecodeMediaCodec.releaseOutputBuffer(outputBufferIndex, true); outputBufferIndex = mDecodeMediaCodec.dequeueOutputBuffer(info, 0); System.out.println("inner outputBufferIndex: " + outputBufferIndex); } } while (outputBufferIndex > 0); } } }).start(); } 

Кто-нибудь знает почему? Надеюсь, ваша помощь. Мое устройство для Android – это нексус 7.

Получение -1 из MediaCodec#dequeueOutputBuffer() является нормальным. Это просто означает, что у него пока нет готового выхода.

Это не тот случай, когда вы MediaCodec буфер закодированных данных и сразу же возвращаете декодированный буфер обратно. Вы передаете ему буфер данных, который отправляется в процесс mediaserver , который mediaserver его в аппаратный декодер AVC, который все еще может быть инициализирован или, может быть, просто нравится сидеть на нескольких кадрах. Когда процесс декодирования завершается, декодированные данные передаются обратно через mediaserver в ваш процесс приложения.

Фокус в том, что queueInputBuffer() немедленно возвращается. При нормальной работе входная сторона декодера будет запускать несколько кадров перед выходной стороной. Когда вы закончите подавать вход, вы установите флаг конца потока, и когда вы увидите, что EOS установлен на выходе, вы знаете, что достигли конца.

Вы можете найти различные рабочие примеры на большой ленте и в Grafika . Примеры DecodeEditEncodeTest и EncodeDecodeTest работают исключительно с необработанным H.264, другие используют MediaExtractor и MediaMuxer для обработки MediaMuxer файлов MP4.