android - Samsung galaxy note 4 中的 MediaCodec CodecException

标签 android android-mediacodec

我正在尝试使用 https://github.com/saki4510t/ScreenRecordingSample/tree/master/app/src/main/java/com/serenegiant/media 录制屏幕并提供了一些相关的代码 fragment :

@Override
void prepare() throws IOException {
    if (DEBUG) Log.i(TAG, "prepare: ");
    mSurface = prepare_surface_encoder(MIME_TYPE, fps, bitrate);
    mMediaCodec.start();
    mIsRecording = true;
    new Thread(mScreenCaptureTask, "ScreenCaptureThread").start();
    if (DEBUG) Log.i(TAG, "prepare finishing");
    if (mListener != null) {
        try {
            mListener.onPrepared(this);
        } catch (final Exception e) {
            Log.e(TAG, "prepare:", e);
        }
    }
}   
protected MediaFormat create_encoder_format(final String mime, final int frame_rate, final int bitrate) {
    if (DEBUG) Log.v(TAG, String.format("create_encoder_format:(%d,%d),mime=%s,frame_rate=%d,bitrate=%d", mWidth, mHeight, mime, frame_rate, bitrate));
    final MediaFormat format = MediaFormat.createVideoFormat(mime, mWidth, mHeight);
    format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);  // API >= 18
    format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate > 0 ? bitrate : calcBitRate(frame_rate)); //800000
    format.setInteger(MediaFormat.KEY_FRAME_RATE,30);
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10);
    return format;
}

protected Surface prepare_surface_encoder(final String mime, final int frame_rate, final int bitrate)
    throws IOException, IllegalArgumentException {

    if (DEBUG) Log.v(TAG, String.format("prepare_surface_encoder:(%d,%d),mime=%s,frame_rate=%d,bitrate=%d", mWidth, mHeight, mime, frame_rate, bitrate));

    mTrackIndex = -1;
    mMuxerStarted = mIsEOS = false;

    final MediaCodecInfo videoCodecInfo = selectVideoCodec(mime);
    if (videoCodecInfo == null) {
        throw new IllegalArgumentException("Unable to find an appropriate codec for " + mime);
    }
    if (DEBUG) Log.i(TAG, "selected codec: " + videoCodecInfo.getName());

    final MediaFormat format = create_encoder_format(mime, frame_rate, bitrate);
    if (DEBUG) Log.i(TAG, "format: " + format);

    mMediaCodec = MediaCodec.createEncoderByType(mime);
    mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    // get Surface for encoder input
    // this method only can call between #configure and #start
    return mMediaCodec.createInputSurface();    // API >= 18
}

它适用于大多数设备,但不适用于运行 android 6.0.1 的 Samsung Galaxy note 4。我在哪里遇到以下错误。

`Non-fatal Exception: android.media.MediaCodec$CodecException: Error 0xffffec77
   at android.media.MediaCodec.native_configure(MediaCodec.java)
   at android.media.MediaCodec.configure(MediaCodec.java:1778)
   at com.urcaddy.utilities.utils.media.MediaVideoEncoderBase.prepare_surface_encoder(MediaVideoEncoderBase.java:90)
   at com.urcaddy.utilities.utils.media.MediaScreenEncoder.prepare(MediaScreenEncoder.java:87)
   at com.urcaddy.utilities.utils.media.MediaMuxerWrapper.prepare(MediaMuxerWrapper.java:74)
   at com.urcaddy.services.backgroundservices.ScreenRecorderService.startScreenRecord(ScreenRecorderService.java:229)
   at com.urcaddy.services.backgroundservices.ScreenRecorderService.onStartCommand(ScreenRecorderService.java:139)
   at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4062)
   at android.app.ActivityThread.access$2400(ActivityThread.java:221)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1897)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:158)
   at android.app.ActivityThread.main(ActivityThread.java:7225)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)`

最佳答案

经过大量的思考,我们发现问题出在高度和宽度上。下面是对我们有用的代码。

protected MediaFormat create_encoder_format(final String mime, final int frame_rate, final int bitrate) {
if (DEBUG) Log.v(TAG, String.format("create_encoder_format:(%d,%d),mime=%s,frame_rate=%d,bitrate=%d", 720, 1280, mime, frame_rate, bitrate));
final MediaFormat format = MediaFormat.createVideoFormat(mime, 720, 1280);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);  // API >= 18
format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate > 0 ? bitrate : calcBitRate(frame_rate)); //800000
format.setInteger(MediaFormat.KEY_FRAME_RATE,30);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10);
return format;
}

关于android - Samsung galaxy note 4 中的 MediaCodec CodecException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44764833/

相关文章:

android - 在工具栏上为 Activity 和 fragment 显示不同的菜单选项

java - Java、Android 上本地存储中的文件

java - Android 抽屉导航中的后退导航不会更改所选项目

RecyclerView 中的 Android TalkBack

android - 从最近的应用程序列表中删除时,我的应用程序被杀死

Android MediaCodec API 视频播放速度太快

android - 如何检测Android设备中的芯片组信息?

Android MediaCodec 不工作

android - 如何从 H264 流中获取 slice-height 和 stride?

java - Android MediaCodec 在异步模式下比在同步模式下慢?