MediaCodec / MediaExtractor - 尝试从第二个MediaExtractor到第二个解码器

时间:2016-10-06 10:02:56

标签: android mediacodec mediaextractor

在尝试使用MediaCodec连接视频时,我尝试使用两个MediaExtractor,每个MediaCodecprivate void videoExtractorLoop(MediaExtractor localVideoExtractor, MediaCodec destinationDecoder, ByteBuffer[] destinationDecoderInputBuffers) { boolean localExtractorIsOrig = (localVideoExtractor == videoExtractor); boolean localDoneIndicator = localExtractorIsOrig ? videoExtractorDone : videoExtractorAppendDone; while (mCopyVideo && !localDoneIndicator && (encoderOutputVideoFormat == null || muxing)) { int decoderInputBufferIndex = destinationDecoder.dequeueInputBuffer(TIMEOUT_USEC); if (decoderInputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) { if (VERBOSE) Log.d(TAG, "no video decoder input buffer"); break; } if (VERBOSE) { Log.d(TAG, "video decoder: returned input buffer: " + decoderInputBufferIndex); } ByteBuffer decoderInputBuffer = destinationDecoderInputBuffers[decoderInputBufferIndex]; int size = localVideoExtractor.readSampleData(decoderInputBuffer, 0); long presentationTime = localVideoExtractor.getSampleTime(); if (VERBOSE) { Log.d(TAG, (localVideoExtractor == videoExtractor) + " video extractor: returned buffer of size " + size); Log.d(TAG, (localVideoExtractor == videoExtractor) + " video extractor: returned buffer for time " + presentationTime); } if (size >= 0) { if(localExtractorIsOrig)firstDecoderFinalFrameTimestamp = presentationTime; destinationDecoder.queueInputBuffer(decoderInputBufferIndex, 0, size, presentationTime, localVideoExtractor.getSampleFlags()); } if(localExtractorIsOrig) {videoExtractorDone = !localVideoExtractor.advance();} else { videoExtractorAppendDone = !localVideoExtractor.advance(); } if (videoExtractorDone) { if (VERBOSE) Log.d(TAG, "video extractor: EOS"); if(localExtractorIsOrig && destinationDecoder == videoDecoder){destinationDecoder.queueInputBuffer(decoderInputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);} else if(!localExtractorIsOrig && destinationDecoder == videoDecoderAppend){destinationDecoder.queueInputBuffer(decoderInputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);} //videoDecoder.queueInputBuffer(decoderInputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); } videoExtractedFrameCount++; break; } //Video Extractor code end } private void localizedVideoDecoderLoop(MediaCodec localVideoDecoder, OutputSurface localVidDecoderOutputSurface, InputSurface dstEncoderInputSurface, ByteBuffer[] locDecoderOutputBuffers) { boolean localDecoderIsOrig = (localVideoDecoder == videoDecoder); boolean localDoneIndicator = localDecoderIsOrig ? videoDecoderDone : videoDecoderAppendDone; MediaFormat localDecoderOutFormat = localDecoderIsOrig ? decoderOutputVideoFormat : decoderOutputAppendVideoFormat; Log.i("check_local_decoder", localDecoderIsOrig+""); MediaCodec.BufferInfo localDecoderOutBufInfo = localDecoderIsOrig ? videoDecoderOutputBufferInfo : videoDecoderAppendOutputBufferInfo; //Video Decoder code begin while (mCopyVideo && !localDoneIndicator && (encoderOutputVideoFormat == null || muxing)) { int decoderOutputBufferIndex = localVideoDecoder.dequeueOutputBuffer(localDecoderOutBufInfo, TIMEOUT_USEC); if (decoderOutputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) { if (VERBOSE) Log.d(TAG, "no video decoder output buffer"); break; } if (decoderOutputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { if (VERBOSE) Log.d(TAG, "video decoder: output buffers changed"); if(localDecoderIsOrig){videoDecoderOutputBuffers = localVideoDecoder.getOutputBuffers();} else {videoDecoderAppendOutputBuffers = localVideoDecoder.getOutputBuffers();} break; } if (decoderOutputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { if(localDecoderIsOrig){decoderOutputVideoFormat = localVideoDecoder.getOutputFormat();} else{decoderOutputAppendVideoFormat = localVideoDecoder.getOutputFormat();} Log.i("decoder_vid_out_format", localDecoderOutFormat+""); if (VERBOSE) { Log.d(TAG, "video decoder: output format changed: " + localDecoderOutFormat); } break; } if (VERBOSE) { Log.d(TAG, "video decoder: returned output buffer: " + decoderOutputBufferIndex); Log.d(TAG, "video decoder: returned buffer of size " + localDecoderOutBufInfo.size); Log.d(TAG, "video decoder: returned buffer for time " + localDecoderOutBufInfo.presentationTimeUs); } ByteBuffer decoderOutputBuffer = locDecoderOutputBuffers[decoderOutputBufferIndex]; if ((localDecoderOutBufInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { if (VERBOSE) Log.d(TAG, "video decoder: codec config buffer"); localVideoDecoder.releaseOutputBuffer(decoderOutputBufferIndex, false); break; } if (VERBOSE) { Log.d(TAG, "video decoder: returned buffer for time " + localDecoderOutBufInfo.presentationTimeUs); } boolean render = localDecoderOutBufInfo.size != 0; localVideoDecoder.releaseOutputBuffer(decoderOutputBufferIndex, render); if (render) { renderingFrameSection(localVidDecoderOutputSurface, dstEncoderInputSurface, localDecoderOutBufInfo.presentationTimeUs); } videoDecodedFrameCount++; if ((localDecoderOutBufInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { if (VERBOSE) Log.d(TAG, "video decoder: EOS"); if(localDecoderIsOrig){videoDecoderDone = true;} else{videoDecoderAppendDone = true;} if(!localDecoderIsOrig){videoEncoder.signalEndOfInputStream();} } break; } //Video Decoder code end } s配对作为解码器。我尝试本地化Extractor和Decoder循环,使它们看起来像这样:

MediaExtractor

我在通常的ExtractDecodeEditEncodeTest中分别代替Extractor代码和Decoder代码使用这些函数。我只是传递了MediaCodec和我想要使用的解码器destinationDecoder.queueInputBuffer(decoderInputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);,我希望该函数能够使用所述提取器和解码器进行通常的提取/解码循环。

当我将这些函数用于第一个提取器 - 解码器对时,它们工作正常。但是,当我在第一个工作完成后立即将它们用于第二个提取器 - 解码器对时,我从第W/System.err: android.media.MediaCodec$CodecException: Error 0xfffffff3行得到以下异常:

10-07 10:37:39.697 3061-25956/? I/EXYNOS_BASE_COMP: [0xf1459700][Exynos_OMX_ComponentStateSet] current:(OMX_StateLoaded) dest:(OMX_StateIdle) 10-07 10:37:39.697 23904-25949/com.picmix.mobile I/ACodec: [OMX.Exynos.avc.dec] Now Loaded->Idle 10-07 10:37:39.707 23904-25949/com.picmix.mobile D/SurfaceUtils: set up nativeWindow 0x7f76e82010 for 400x224, color 0x105, rotation 0, usage 0x2900 10-07 10:37:39.707 23904-25949/com.picmix.mobile I/ACodec: [OMX.Exynos.avc.dec] configureOutputBuffersFromNativeWindow setBufferCount : 7, minUndequeuedBuffers : 5 10-07 10:37:39.707 3061-25956/? D/libexynosv4l2: try node: /dev/video6 10-07 10:37:39.707 3061-25956/? I/libexynosv4l2: node found for device s5p-mfc-dec: /dev/video6 10-07 10:37:39.707 23904-25929/com.picmix.mobile I/check_local_decoder: false 10-07 10:37:39.707 3061-25956/? I/libexynosv4l2: open video device /dev/video6 10-07 10:37:39.717 3061-25956/? I/EXYNOS_BASE_COMP: [0xf1459700][Exynos_OMX_ComponentStateSet]:567 OMX_EventCmdComplete 10-07 10:37:39.717 3061-25956/? I/EXYNOS_BASE_COMP: [0xf1459700][Exynos_OMX_ComponentStateSet] current:(OMX_StateIdle) dest:(OMX_StateExecuting) 10-07 10:37:39.717 3061-25956/? I/EXYNOS_BASE_COMP: [0xf1459700][Exynos_OMX_ComponentStateSet]:567 OMX_EventCmdComplete 10-07 10:37:39.717 23904-25949/com.picmix.mobile I/ACodec: [OMX.Exynos.avc.dec] Now Idle->Executing 10-07 10:37:39.717 23904-25949/com.picmix.mobile I/ACodec: [OMX.Exynos.avc.dec] Now Executing 10-07 10:37:39.717 3061-25979/? E/libexynosv4l2: failed to ioctl: VIDIOC_S_CTRL (22) 10-07 10:37:39.717 3061-25979/? E/EXYNOS_H264_DEC: Failed to set buffer process type(not supported) 10-07 10:37:39.717 3061-25979/? E/libexynosv4l2: failed to ioctl: VIDIOC_G_CTRL (22 - Invalid argument)

编辑:

我在堆栈跟踪中仔细观察并发现了这些:

class Vehicle {
    ...
}

class Car extends Vehicle {
    ...
}

class Motorcycle extends Vehicle {
    ...
}

我需要在解码器设置中更改什么?

0 个答案:

没有答案