当使用 COLOR_FormatYUV420Planar 兼容编解码器时,dequeueOutputBuffer 会引发 IllegalStateException

And*_*nih 5 android illegalstateexception android-mediacodec

我正在MediaCodec使用 Android 4.4.2 在 LG G2 上运行这个简单的测试:

public class MyActivity extends Activity {
    private static final String MIME_TYPE = "video/avc";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, 1280, 720);

        int numCodecs = MediaCodecList.getCodecCount();
        for (int i = 0; i < numCodecs; i++) {
            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);

            if (codecInfo.isEncoder()) {
                String[] types = codecInfo.getSupportedTypes();

                for (int j = 0; j < types.length; j++) {
                    if (types[j].equalsIgnoreCase(MIME_TYPE)) {
                        MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(MIME_TYPE);

                        for(int colorFormat : capabilities.colorFormats) {
                            if (colorFormat == MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar) {

                                format.setInteger(MediaFormat.KEY_COLOR_FORMAT,     MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);
                                format.setInteger(MediaFormat.KEY_BIT_RATE,         1000000);
                                format.setInteger(MediaFormat.KEY_FRAME_RATE,       15);
                                format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10);

                                MediaCodec mMediaCodec = MediaCodec.createByCodecName(codecInfo.getName());

                                mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
                                mMediaCodec.start();

                                MediaCodec.BufferInfo mBufferInfo = new MediaCodec.BufferInfo();
                                mMediaCodec.dequeueOutputBuffer(mBufferInfo, 1000);

                                return;
                            }
                        }
                    }
                }
            }
        }


    }
}
Run Code Online (Sandbox Code Playgroud)

它引发了以下错误:

04-21 18:08:29.531    6513-6513/com.example.mediacodec I/OMXClient? Using client-side OMX mux.
04-21 18:08:29.531    6513-6513/com.example.mediacodec E/OMXMaster? A component of name 'OMX.qcom.audio.decoder.aac' already exists, ignoring this one.
04-21 18:08:29.531    6513-6513/com.example.mediacodec I/? @@@VOLOG Info THD 4001A154:    VOOMXPlugin.cpp  VOOMXPlugin  59    open libvoOMXOne.so successfully. 0X5BB9A5B8
04-21 18:08:29.541    6513-6513/com.example.mediacodec E/? VOLOG Info THD 4001A154 voCOMXBaseConfig.cpp Open 368  The config file vomeOne.cfg could not be opened!
04-21 18:08:29.541    6513-6513/com.example.mediacodec I/SoftAVCEncoder? Construct SoftAVCEncoder
04-21 18:08:29.541    6513-6536/com.example.mediacodec I/OMXClient? Using client-side OMX mux.
04-21 18:08:29.541    6513-6536/com.example.mediacodec E/OMXMaster? A component of name 'OMX.qcom.audio.decoder.aac' already exists, ignoring this one.
04-21 18:08:29.541    6513-6536/com.example.mediacodec I/? @@@VOLOG Info THD 60471CD0:    VOOMXPlugin.cpp  VOOMXPlugin  59    open libvoOMXOne.so successfully. 0X5BB9A370
04-21 18:08:29.541    6513-6536/com.example.mediacodec E/? VOLOG Info THD 60471CD0 voCOMXBaseConfig.cpp Open 368  The config file vomeOne.cfg could not be opened!
04-21 18:08:29.541    6513-6536/com.example.mediacodec I/SoftAVCEncoder? Construct SoftAVCEncoder
04-21 18:08:29.541    6513-6536/com.example.mediacodec E/SoftAVCEncoder? internalSetParameter: StoreMetadataInBuffersParams.nPortIndex not zero!
04-21 18:08:29.541    6513-6536/com.example.mediacodec E/OMXNodeInstance? OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x80001001
04-21 18:08:29.541    6513-6536/com.example.mediacodec E/ACodec? [OMX.google.h264.encoder] storeMetaDataInBuffers (output) failed w/ err -2147483648
04-21 18:08:29.541    6513-6536/com.example.mediacodec I/ACodec? setupVideoEncoder succeeded
04-21 18:08:29.541    6513-6537/com.example.mediacodec E/SoftAVCEncoder? Failed to initialize the encoder: -8
04-21 18:08:29.551    6513-6536/com.example.mediacodec E/ACodec? [OMX.google.h264.encoder] ERROR(0x80001001)
04-21 18:08:29.551    6513-6535/com.example.mediacodec E/MediaCodec? Codec reported an error. (omx error 0x80001001, internalError -2147483648)
04-21 18:08:29.551    6513-6513/com.example.mediacodec D/AndroidRuntime? Shutting down VM
04-21 18:08:29.551    6513-6513/com.example.mediacodec W/dalvikvm? threadid=1: thread exiting with uncaught exception (group=0x417a8e48)
04-21 18:08:29.551    6513-6513/com.example.mediacodec E/AndroidRuntime? FATAL EXCEPTION: main
    Process: com.example.mediacodec, PID: 6513
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.mediacodec/com.example.mediacodec.MyActivity}: java.lang.IllegalStateException
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2200)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
            at android.app.ActivityThread.access$800(ActivityThread.java:139)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5105)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.IllegalStateException
            at android.media.MediaCodec.dequeueOutputBuffer(Native Method)
            at com.example.mediacodec.MyActivity.onCreate(MyActivity.java:49)
            at android.app.Activity.performCreate(Activity.java:5275)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2164)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
            at android.app.ActivityThread.access$800(ActivityThread.java:139)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5105)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
            at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)

同样的错误可以在 Sony Xperia ZR 上重现。两种设备也都支持 COLOR_FormatYUV420SemiPlanar,并且在相同的参数下运行良好。我试图EncodeDecodeTestandroid.media.cts包中运行并成功通过,但看起来它只测试了第一个支持的编解码器的第一个支持的颜色格式,COLOR_FormatYUV420SemiPlanar在这种情况下。

小智 0

在你的日志中,

\n\n
04-21 18:08:29.541    6513-6536/com.example.mediacodec E/SoftAVCEncoder\xef\xb9\x95 internalSetParameter: StoreMetadataInBuffersParams.nPortIndex not zero!\n04-21 18:08:29.541    6513-6536/com.example.mediacodec E/OMXNodeInstance\xef\xb9\x95 OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x80001001\n04-21 18:08:29.541    6513-6536/com.example.mediacodec E/ACodec\xef\xb9\x95 [OMX.google.h264.encoder] storeMetaDataInBuffers (output) failed w/ err -2147483648\n04-21 18:08:29.541    6513-6536/com.example.mediacodec I/ACodec\xef\xb9\x95 setupVideoEncoder succeeded\n04-21 18:08:29.541    6513-6537/com.example.mediacodec E/SoftAVCEncoder\xef\xb9\x95 Failed to initialize the encoder: -8\n
Run Code Online (Sandbox Code Playgroud)\n\n

AVC 停止 nPortIndex 不为零。\n请参阅以下链接作为参考。\n http://androidxref.com/4.4.2_r2/xref/frameworks/av/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp#684

\n\n
686            StoreMetaDataInBuffersParams *storeParams =\n687                    (StoreMetaDataInBuffersParams*)params;\n688            if (storeParams->nPortIndex != 0) {\n689                ALOGE("%s: StoreMetadataInBuffersParams.nPortIndex not zero!",\n690                        __FUNCTION__);\n691                return OMX_ErrorUndefined;\n692            }\n
Run Code Online (Sandbox Code Playgroud)\n\n

这会在 SoftAVEncoder.cpp 上出错,

\n\n
150  /** There was an error, but the cause of the error could not be determined */\n151  OMX_ErrorUndefined = (OMX_S32) 0x80001001,\n
Run Code Online (Sandbox Code Playgroud)\n\n

http://androidxref.com/4.4.2_r2/xref/frameworks/native/include/media/openmax/OMX_Core.h#151

\n\n

如何检查您的配置或寻找此错误的解决方法?

\n