MediaCodec 无法在 S9+ 上使输出出队
MediaCodec Fails To Dequeue Output on S9+
我有一个用于 Unity3D 的 Android 插件,可以将 h264 视频解码为表面。这适用于我的 Android 5.1.1 的 S6。但是,在我的 S9 运行 Android 8 上,输出缓冲区永远不会出队。
我创建解码器的代码很简单:
codec = AMediaCodec_createDecoderByType ("video/avc");
AMediaFormat * format = AMediaFormat_new ();
AMediaFormat_setString (format, AMEDIAFORMAT_KEY_MIME, "video/avc");
AMediaFormat_setInt32 (format, AMEDIAFORMAT_KEY_WIDTH, 4096);
AMediaFormat_setInt32 (format, AMEDIAFORMAT_KEY_HEIGHT, 1536);
AMediaFormat_setInt32 (format, AMEDIAFORMAT_KEY_FRAME_RATE, 30);
AMediaCodec_configure (codec, format, window, NULL, 0);
AMediaCodec_start (codec);
AMediaFormat_delete (format);
同样,我排队入codec的代码也比较标准
ssize_t buffIdx = AMediaCodec_dequeueInputBuffer (codec, DequeueTimeoutUS);
if (buffIdx < 0)
continue;
uint8_t* inputBuff = AMediaCodec_getInputBuffer (codec, buffIdx, &buffsize);
// I would copy into the input buffer here...
AMediaCodec_queueInputBuffer (codec, buffIdx, 0, copySize, pts, flags);
以及我从解码器中提取的代码:
AMediaCodecBufferInfo info;
ssize_t status = AMediaCodec_dequeueOutputBuffer (codec, &info, DequeueOutputTimeout);
if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER)
continue;
// I would update the surface texture here...
AMediaCodec_releaseOutputBuffer (codec, status, info.size != 0);
不幸的是,仅出队 returns AMEDIACODEC_INFO_TRY_AGAIN_LATER。这是它在 S9+
上 运行 的日志
02-14 15:00:50.346 8005 8158 I ACodec : [] Now uninitialized
02-14 15:00:50.347 8005 8160 I ACodec : [] onAllocateComponent
02-14 15:00:50.353 8005 8160 I OMXClient: Treble IOmx obtained
02-14 15:00:50.353 8005 8160 I ACodec : Set Google AAC Dec for aacProfile 0
02-14 15:00:50.357 2692 7767 I OMXMaster: makeComponentInstance(OMX.qcom.video.decoder.avc) in omx@1.0-service process
02-14 15:00:50.359 684 684 I android.hardware.wifi@1.0-service: getLinkLayerStats
02-14 15:00:50.365 2692 7767 E : Service not available yet
02-14 15:00:50.388 2692 7767 I OMX-VDEC-1080P: Video slvp perflock acquired
02-14 15:00:50.389 2692 7767 I OMX-VDEC-1080P: component_init: OMX.qcom.video.decoder.avc : fd=22
02-14 15:00:50.389 2692 7767 E OMX-VDEC-1080P: Unsupported output color format for c2d (2141391876)
02-14 15:00:50.389 2692 7767 E OMX-VDEC-1080P: Setting color format failed
02-14 15:00:50.396 2692 7767 I OMX-VDEC-1080P: omx_vdec::component_init() success : fd=22
02-14 15:00:50.397 8005 8160 I ACodec : [OMX.qcom.video.decoder.avc] Now Loaded
02-14 15:00:51.818 8005 8159 D SurfaceUtils: connecting to surface 0xc4b86808, reason connectToSurface
02-14 15:00:51.818 8005 8159 I MediaCodec: [OMX.qcom.video.decoder.avc] setting surface generation to 8197121
02-14 15:00:51.818 8005 8159 D SurfaceUtils: disconnecting from surface 0xc4b86808, reason connectToSurface(reconnect)
02-14 15:00:51.818 8005 8159 D SurfaceUtils: connecting to surface 0xc4b86808, reason connectToSurface(reconnect)
02-14 15:00:51.819 2687 32660 I ResourceManagerService: ResourceManagerService checkCodecCapacity pid 8005 clientId 3218327712 useExtended 0
02-14 15:00:51.820 8005 8160 I ACodec : [HW_HDR] HDR-OFF 0
02-14 15:00:51.820 8005 8160 W DirectStreamingProxy: app-pid not found. use getpid(). pid = 8005
02-14 15:00:51.821 8005 8160 D DirectStreamingProxy: pid = 8005
02-14 15:00:51.823 2692 7767 E OMX-VDEC-1080P: Enable/Disable allocate-native-handle allowed only on input port!
02-14 15:00:51.823 2692 7767 E OMX-VDEC-1080P: set_parameter: Error: 0x80001019, setting param 0x7f00005d
02-14 15:00:51.823 2692 7767 E OMXNodeInstance: setParameter(0xee709444:qcom.decoder.avc, OMX.google.android.index.allocateNativeHandle(0x7f00005d): Output:1 en=0) ERROR: UnsupportedSetting(0x80001019)
02-14 15:00:51.823 2692 7767 E OMX-VDEC-1080P: Extension: OMX.google.android.index.storeANWBufferInMetadata not implemented
02-14 15:00:51.824 8005 8160 I ACodec : [OMX.qcom.video.decoder.avc] OMX_QCOM_FramePacking_OnlyOneCompleteFrame is setting
02-14 15:00:51.824 2676 3409 V APM_AudioPolicyManager: getOutputForDevice() returns output 29
02-14 15:00:51.824 2692 7767 E OMX-VDEC-1080P: Extension: OMX.google.android.index.storeANWBufferInMetadata not implemented
02-14 15:00:51.824 2692 7767 E OMX-VDEC-1080P: Extension: OMX.google.android.index.configureVideoTunnelMode not implemented
02-14 15:00:51.824 2692 7767 E OMX-VDEC-1080P: Extension: OMX.google.android.index.useAndroidNativeBuffer is supported
02-14 15:00:51.824 2692 7767 E OMX-VDEC-1080P: Setparameter: unknown param 2130706434
02-14 15:00:51.824 2692 7767 E OMX-VDEC-1080P: set_parameter: Error: 0x8000101a, setting param 0x7f000002
02-14 15:00:51.824 2692 7767 E OMXNodeInstance: setParameter(0xee709444:qcom.decoder.avc, ??(0x7f000002)) ERROR: UnsupportedIndex(0x8000101a)
02-14 15:00:51.824 8005 8160 W ACodec : Fail to set FramePackingMode(-1010)
02-14 15:00:51.824 2676 3409 I AudioFlinger: add dynamic flag, can move to deep thread, session 601
02-14 15:00:51.824 8005 8160 I ExtendedACodec: setupVideoDecoder()
02-14 15:00:51.828 8005 8160 I ExtendedACodec: Decoder will be in frame by frame mode
02-14 15:00:51.828 2692 2845 E OMX-VDEC-1080P: Setparameter: unknown param 2130706434
02-14 15:00:51.828 2692 2845 E OMX-VDEC-1080P: set_parameter: Error: 0x8000101a, setting param 0x7f000002
02-14 15:00:51.828 2692 2845 E OMXNodeInstance: setParameter(0xee709444:qcom.decoder.avc, ??(0x7f000002)) ERROR: UnsupportedIndex(0x8000101a)
02-14 15:00:51.828 8005 8160 W ExtendedACodec: Failed to set frame packing format on component
02-14 15:00:51.828 8005 8160 I SmartFittingClass: Create SmartFitting Version 2.0
02-14 15:00:51.830 2689 2887 I RemoteDisplayService: There is no RemoteDisplay
02-14 15:00:51.831 8005 8160 I SmartFittingClass: Init, [State:UNINITIALIZED] pid: 8005
02-14 15:00:51.832 3051 3365 D CodecSolution: setSmartFittingPid : 8005
02-14 15:00:51.833 3051 3365 D CodecSolution: setSmartFittingMode : 0
02-14 15:00:51.833 3051 3434 D CodecSolution: handleMessage : 202
02-14 15:00:51.836 2692 7768 E OMX-VDEC-1080P: Does not handle dataspace request
02-14 15:00:51.836 2692 7768 E OMXNodeInstance: getConfig(0xee709444:qcom.decoder.avc, ??(0x7f000062)) ERROR: UnsupportedSetting(0x80001019)
02-14 15:00:51.845 8005 8160 I ACodec : [OMX.qcom.video.decoder.avc] Now Loaded->Idle
02-14 15:00:51.858 2692 2900 E OMX-VDEC-1080P: Extension: OMX.google.android.index.AndroidNativeBufferConsumerUsage not implemented
02-14 15:00:51.858 8005 8160 D SurfaceUtils: set up nativeWindow 0xc4b86808 for 4096x1536, color 0x7fa30c06, rotation 0, usage 0x20402900
02-14 15:00:51.859 8005 8160 I ACodec : [OMX.qcom.video.decoder.avc] configureOutputBuffersFromNativeWindow setBufferCount :17, minUndequeuedBuffers : 5
02-14 15:00:51.860 3051 3365 W CodecSolution: PackageInfo is null.
02-14 15:00:51.860 8005 8175 I SmartFittingClass: InitialCheck, WhiteListStatus returned from CodecSolution : 0
02-14 15:00:51.860 8005 8175 I SmartFittingClass: InitialCheck,
02-14 15:00:51.864 3051 3365 D CodecSolution: reportMediaStatisticsEvent: action=1@1986621044;category=2@1986621044;label=1936222260@1986621044
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: MediaStatisticsEvent: action=1@1986621044;category=2@1986621044;label=1936222260@1986621044
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: Category.valueOf: 2
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: Action.valueOf: 1
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: Label.valueOf: 0x73686834
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: category: VDEC
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: action: INSTANTIATE
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: label: SEC_HW_H264
02-14 15:00:51.865 3051 3434 D CodecSolution: handleMessage : 900
02-14 15:00:51.865 3051 3434 D CodecSolution: event : VDEC
02-14 15:00:51.865 3051 3434 D Logging : appId: com.samsung.android.codecsolution, feature: VDEC, extra: SEC_HW_H264, value: -1
02-14 15:00:51.865 2687 1137 I ResourceManagerService: addMediaInfo -(PID : 8005, clientID : 3218327712)
02-14 15:00:51.865 2687 1137 I ResourceManagerService: MediaInfo add 6291456 (width 4096 height 1536) remained 11403264
02-14 15:00:51.865 2687 1137 I ResourceManagerService: getMediaResourceInfo resourceType : 2, size : 1
02-14 15:00:51.865 2687 1137 I ResourceManagerService: getMediaResourceInfo (PID : 8005, clientID : 3218327712, non-secure-codec/video-codec:1, 4096x1536(fps:30) - SoftCodec : No, Encorder : No)
02-14 15:00:51.865 3051 3365 V ResourceManagerHelper-JNI: JNIMediaResourceHelper::notify eventType : 1, ext1 : 0, ext2 : 0
02-14 15:00:51.865 3051 3365 V ResourceManagerHelper-JNI: notify eventType : 1, ext1 : 0, ext2 : 0
02-14 15:00:51.865 8005 8160 I ACodec : [OMX.qcom.video.decoder.avc] Now Idle->Executing
02-14 15:00:51.866 3051 3365 I SemMediaResourceHelper: makeMediaResourceInfo mOwnResourceEventExcluded : false, mPid : 3051
02-14 15:00:51.866 3051 3365 I SemMediaResourceHelper: [1] makeMediaResourceInfo resourceType : 2 isSecured : false, pid : 8005, client id : 3218327712
02-14 15:00:51.866 8005 8160 I ACodec : [OMX.qcom.video.decoder.avc] Now Executing
02-14 15:00:51.870 8005 8160 W GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
关于无效使用位的最后一行与我排队输入缓冲区大致同步
原来这是因为我不小心用 BUFFER_FLAG_CODEC_CONFIG 标记了每个缓冲区。只有为第一个输入缓冲区添加该标志才能解决问题。
我有一个用于 Unity3D 的 Android 插件,可以将 h264 视频解码为表面。这适用于我的 Android 5.1.1 的 S6。但是,在我的 S9 运行 Android 8 上,输出缓冲区永远不会出队。
我创建解码器的代码很简单:
codec = AMediaCodec_createDecoderByType ("video/avc");
AMediaFormat * format = AMediaFormat_new ();
AMediaFormat_setString (format, AMEDIAFORMAT_KEY_MIME, "video/avc");
AMediaFormat_setInt32 (format, AMEDIAFORMAT_KEY_WIDTH, 4096);
AMediaFormat_setInt32 (format, AMEDIAFORMAT_KEY_HEIGHT, 1536);
AMediaFormat_setInt32 (format, AMEDIAFORMAT_KEY_FRAME_RATE, 30);
AMediaCodec_configure (codec, format, window, NULL, 0);
AMediaCodec_start (codec);
AMediaFormat_delete (format);
同样,我排队入codec的代码也比较标准
ssize_t buffIdx = AMediaCodec_dequeueInputBuffer (codec, DequeueTimeoutUS);
if (buffIdx < 0)
continue;
uint8_t* inputBuff = AMediaCodec_getInputBuffer (codec, buffIdx, &buffsize);
// I would copy into the input buffer here...
AMediaCodec_queueInputBuffer (codec, buffIdx, 0, copySize, pts, flags);
以及我从解码器中提取的代码:
AMediaCodecBufferInfo info;
ssize_t status = AMediaCodec_dequeueOutputBuffer (codec, &info, DequeueOutputTimeout);
if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER)
continue;
// I would update the surface texture here...
AMediaCodec_releaseOutputBuffer (codec, status, info.size != 0);
不幸的是,仅出队 returns AMEDIACODEC_INFO_TRY_AGAIN_LATER。这是它在 S9+
上 运行 的日志 02-14 15:00:50.346 8005 8158 I ACodec : [] Now uninitialized
02-14 15:00:50.347 8005 8160 I ACodec : [] onAllocateComponent
02-14 15:00:50.353 8005 8160 I OMXClient: Treble IOmx obtained
02-14 15:00:50.353 8005 8160 I ACodec : Set Google AAC Dec for aacProfile 0
02-14 15:00:50.357 2692 7767 I OMXMaster: makeComponentInstance(OMX.qcom.video.decoder.avc) in omx@1.0-service process
02-14 15:00:50.359 684 684 I android.hardware.wifi@1.0-service: getLinkLayerStats
02-14 15:00:50.365 2692 7767 E : Service not available yet
02-14 15:00:50.388 2692 7767 I OMX-VDEC-1080P: Video slvp perflock acquired
02-14 15:00:50.389 2692 7767 I OMX-VDEC-1080P: component_init: OMX.qcom.video.decoder.avc : fd=22
02-14 15:00:50.389 2692 7767 E OMX-VDEC-1080P: Unsupported output color format for c2d (2141391876)
02-14 15:00:50.389 2692 7767 E OMX-VDEC-1080P: Setting color format failed
02-14 15:00:50.396 2692 7767 I OMX-VDEC-1080P: omx_vdec::component_init() success : fd=22
02-14 15:00:50.397 8005 8160 I ACodec : [OMX.qcom.video.decoder.avc] Now Loaded
02-14 15:00:51.818 8005 8159 D SurfaceUtils: connecting to surface 0xc4b86808, reason connectToSurface
02-14 15:00:51.818 8005 8159 I MediaCodec: [OMX.qcom.video.decoder.avc] setting surface generation to 8197121
02-14 15:00:51.818 8005 8159 D SurfaceUtils: disconnecting from surface 0xc4b86808, reason connectToSurface(reconnect)
02-14 15:00:51.818 8005 8159 D SurfaceUtils: connecting to surface 0xc4b86808, reason connectToSurface(reconnect)
02-14 15:00:51.819 2687 32660 I ResourceManagerService: ResourceManagerService checkCodecCapacity pid 8005 clientId 3218327712 useExtended 0
02-14 15:00:51.820 8005 8160 I ACodec : [HW_HDR] HDR-OFF 0
02-14 15:00:51.820 8005 8160 W DirectStreamingProxy: app-pid not found. use getpid(). pid = 8005
02-14 15:00:51.821 8005 8160 D DirectStreamingProxy: pid = 8005
02-14 15:00:51.823 2692 7767 E OMX-VDEC-1080P: Enable/Disable allocate-native-handle allowed only on input port!
02-14 15:00:51.823 2692 7767 E OMX-VDEC-1080P: set_parameter: Error: 0x80001019, setting param 0x7f00005d
02-14 15:00:51.823 2692 7767 E OMXNodeInstance: setParameter(0xee709444:qcom.decoder.avc, OMX.google.android.index.allocateNativeHandle(0x7f00005d): Output:1 en=0) ERROR: UnsupportedSetting(0x80001019)
02-14 15:00:51.823 2692 7767 E OMX-VDEC-1080P: Extension: OMX.google.android.index.storeANWBufferInMetadata not implemented
02-14 15:00:51.824 8005 8160 I ACodec : [OMX.qcom.video.decoder.avc] OMX_QCOM_FramePacking_OnlyOneCompleteFrame is setting
02-14 15:00:51.824 2676 3409 V APM_AudioPolicyManager: getOutputForDevice() returns output 29
02-14 15:00:51.824 2692 7767 E OMX-VDEC-1080P: Extension: OMX.google.android.index.storeANWBufferInMetadata not implemented
02-14 15:00:51.824 2692 7767 E OMX-VDEC-1080P: Extension: OMX.google.android.index.configureVideoTunnelMode not implemented
02-14 15:00:51.824 2692 7767 E OMX-VDEC-1080P: Extension: OMX.google.android.index.useAndroidNativeBuffer is supported
02-14 15:00:51.824 2692 7767 E OMX-VDEC-1080P: Setparameter: unknown param 2130706434
02-14 15:00:51.824 2692 7767 E OMX-VDEC-1080P: set_parameter: Error: 0x8000101a, setting param 0x7f000002
02-14 15:00:51.824 2692 7767 E OMXNodeInstance: setParameter(0xee709444:qcom.decoder.avc, ??(0x7f000002)) ERROR: UnsupportedIndex(0x8000101a)
02-14 15:00:51.824 8005 8160 W ACodec : Fail to set FramePackingMode(-1010)
02-14 15:00:51.824 2676 3409 I AudioFlinger: add dynamic flag, can move to deep thread, session 601
02-14 15:00:51.824 8005 8160 I ExtendedACodec: setupVideoDecoder()
02-14 15:00:51.828 8005 8160 I ExtendedACodec: Decoder will be in frame by frame mode
02-14 15:00:51.828 2692 2845 E OMX-VDEC-1080P: Setparameter: unknown param 2130706434
02-14 15:00:51.828 2692 2845 E OMX-VDEC-1080P: set_parameter: Error: 0x8000101a, setting param 0x7f000002
02-14 15:00:51.828 2692 2845 E OMXNodeInstance: setParameter(0xee709444:qcom.decoder.avc, ??(0x7f000002)) ERROR: UnsupportedIndex(0x8000101a)
02-14 15:00:51.828 8005 8160 W ExtendedACodec: Failed to set frame packing format on component
02-14 15:00:51.828 8005 8160 I SmartFittingClass: Create SmartFitting Version 2.0
02-14 15:00:51.830 2689 2887 I RemoteDisplayService: There is no RemoteDisplay
02-14 15:00:51.831 8005 8160 I SmartFittingClass: Init, [State:UNINITIALIZED] pid: 8005
02-14 15:00:51.832 3051 3365 D CodecSolution: setSmartFittingPid : 8005
02-14 15:00:51.833 3051 3365 D CodecSolution: setSmartFittingMode : 0
02-14 15:00:51.833 3051 3434 D CodecSolution: handleMessage : 202
02-14 15:00:51.836 2692 7768 E OMX-VDEC-1080P: Does not handle dataspace request
02-14 15:00:51.836 2692 7768 E OMXNodeInstance: getConfig(0xee709444:qcom.decoder.avc, ??(0x7f000062)) ERROR: UnsupportedSetting(0x80001019)
02-14 15:00:51.845 8005 8160 I ACodec : [OMX.qcom.video.decoder.avc] Now Loaded->Idle
02-14 15:00:51.858 2692 2900 E OMX-VDEC-1080P: Extension: OMX.google.android.index.AndroidNativeBufferConsumerUsage not implemented
02-14 15:00:51.858 8005 8160 D SurfaceUtils: set up nativeWindow 0xc4b86808 for 4096x1536, color 0x7fa30c06, rotation 0, usage 0x20402900
02-14 15:00:51.859 8005 8160 I ACodec : [OMX.qcom.video.decoder.avc] configureOutputBuffersFromNativeWindow setBufferCount :17, minUndequeuedBuffers : 5
02-14 15:00:51.860 3051 3365 W CodecSolution: PackageInfo is null.
02-14 15:00:51.860 8005 8175 I SmartFittingClass: InitialCheck, WhiteListStatus returned from CodecSolution : 0
02-14 15:00:51.860 8005 8175 I SmartFittingClass: InitialCheck,
02-14 15:00:51.864 3051 3365 D CodecSolution: reportMediaStatisticsEvent: action=1@1986621044;category=2@1986621044;label=1936222260@1986621044
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: MediaStatisticsEvent: action=1@1986621044;category=2@1986621044;label=1936222260@1986621044
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: Category.valueOf: 2
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: Action.valueOf: 1
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: Label.valueOf: 0x73686834
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: category: VDEC
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: action: INSTANTIATE
02-14 15:00:51.864 3051 3365 D MediaStatisticsEvent: label: SEC_HW_H264
02-14 15:00:51.865 3051 3434 D CodecSolution: handleMessage : 900
02-14 15:00:51.865 3051 3434 D CodecSolution: event : VDEC
02-14 15:00:51.865 3051 3434 D Logging : appId: com.samsung.android.codecsolution, feature: VDEC, extra: SEC_HW_H264, value: -1
02-14 15:00:51.865 2687 1137 I ResourceManagerService: addMediaInfo -(PID : 8005, clientID : 3218327712)
02-14 15:00:51.865 2687 1137 I ResourceManagerService: MediaInfo add 6291456 (width 4096 height 1536) remained 11403264
02-14 15:00:51.865 2687 1137 I ResourceManagerService: getMediaResourceInfo resourceType : 2, size : 1
02-14 15:00:51.865 2687 1137 I ResourceManagerService: getMediaResourceInfo (PID : 8005, clientID : 3218327712, non-secure-codec/video-codec:1, 4096x1536(fps:30) - SoftCodec : No, Encorder : No)
02-14 15:00:51.865 3051 3365 V ResourceManagerHelper-JNI: JNIMediaResourceHelper::notify eventType : 1, ext1 : 0, ext2 : 0
02-14 15:00:51.865 3051 3365 V ResourceManagerHelper-JNI: notify eventType : 1, ext1 : 0, ext2 : 0
02-14 15:00:51.865 8005 8160 I ACodec : [OMX.qcom.video.decoder.avc] Now Idle->Executing
02-14 15:00:51.866 3051 3365 I SemMediaResourceHelper: makeMediaResourceInfo mOwnResourceEventExcluded : false, mPid : 3051
02-14 15:00:51.866 3051 3365 I SemMediaResourceHelper: [1] makeMediaResourceInfo resourceType : 2 isSecured : false, pid : 8005, client id : 3218327712
02-14 15:00:51.866 8005 8160 I ACodec : [OMX.qcom.video.decoder.avc] Now Executing
02-14 15:00:51.870 8005 8160 W GrallocMapperPassthrough: buffer descriptor with invalid usage bits 0x2000
关于无效使用位的最后一行与我排队输入缓冲区大致同步
原来这是因为我不小心用 BUFFER_FLAG_CODEC_CONFIG 标记了每个缓冲区。只有为第一个输入缓冲区添加该标志才能解决问题。