首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MediaCodec.Callback句柄来自MediaExtractor的IllegalStateException

MediaCodec.Callback句柄来自MediaExtractor的IllegalStateException
EN

Stack Overflow用户
提问于 2018-02-17 01:15:22
回答 1查看 612关注 0票数 1

我根据mstorsjo的例子,在异步模式下使用MediaCodec对视频进行转码。对于一些视频文件,当我调用MediaExtractor.advance()MediaExtractor.getSampleTime()时,会抛出IllegalStateException的异常。例如,在我的音频解码器中:

代码语言:javascript
复制
MediaCodec decoder = MediaCodec.createDecoderByType(type);
decoder.setCallback(new MediaCodec.Callback() {
    public void onInputBufferAvailable(@NonNull MediaCodec codec, int index) {
        ByteBuffer decoderInputBuffer = codec.getInputBuffer(index);
        while (!mExtractorDone) {
            int size = mExtractor.readSampleData(decoderInputBuffer, 0);
            long presentationTimeUs = mExtractor.getSampleTime();
            boolean queuedInputBuffer = false;
            if (size >= 0) {
                codec.queueInputBuffer(
                        index,
                        0,
                        size,
                        presentationTimeUs,
                        mExtractor.getSampleFlags());
                queuedInputBuffer = true;
            }
            mExtractorDone = !mExtractor.advance();
            if (mExtractorDone) {
                queueEOS();
            }
            if (queuedInputBuffer) {
                    break;
            }
        }
    }
    ...
});
decoder.configure(inputFormat, null, null, 0);
decoder.start();

在我的视频解码器中也是类似的,它在单独的HandlerThread中运行。

有没有一种方法可以捕获MediaCodec.Callback中抛出的所有异常,并将它们传递回主awaitEncode函数,这样我就可以关闭所有内容并很好地退出?我是否应该在每个回调周围放置try catchs,然后对主处理线程执行notify

找出导致原始IllegalStateException的原因是很棒的,但知道我的视频转码器的所有问题都会被捕获并向用户解释,我也会感到更舒服。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-21 19:13:07

到目前为止,我最好的解决方案是将所有内容都包装在一个try catch块中。我使用了一个扩展MediaCodec.Callback的实用程序类

代码语言:javascript
复制
public abstract class SafeMediaCodecCallback extends MediaCodec.Callback {

    private final OnExceptionListener exceptionListener;

    public SafeMediaCodecCallback(OnExceptionListener exceptionListener) {
        this.exceptionListener = exceptionListener;
    }

    @Override
    public final void onInputBufferAvailable(@NonNull MediaCodec mediaCodec, int i) {
        try {
            onInputBufferAvailableSafe(mediaCodec, i);
        } catch (Exception exception) {
            handleException(exception);
        }
    }

    @Override
    public final void onOutputBufferAvailable(@NonNull MediaCodec mediaCodec, int i, @NonNull MediaCodec.BufferInfo bufferInfo) {
        try {
            onOutputBufferAvailableSafe(mediaCodec, i, bufferInfo);
        } catch (Exception exception) {
            handleException(exception);
        }
    }

    @Override
    public final void onError(@NonNull MediaCodec mediaCodec, @NonNull MediaCodec.CodecException e) {
        handleException(e);
    }

    @Override
    public final void onOutputFormatChanged(@NonNull MediaCodec mediaCodec, @NonNull MediaFormat mediaFormat) {
        try {
            onOutputFormatChangedSafe(mediaCodec, mediaFormat);
        } catch (Exception exception) {
            handleException(exception);
        }
    }

    private void handleException(Exception e) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (e instanceof CodecException) {
                CodecException codecExc = (CodecException) e;

                if (codecExc.isTransient()) {
                    // We'll let transient exceptions go
                    return;
                }
            }
        }

        exceptionListener.onException(e);
    }

    public abstract void onInputBufferAvailableSafe(@NonNull MediaCodec mediaCodec, int i);

    public abstract void onOutputBufferAvailableSafe(@NonNull MediaCodec mediaCodec, int i, @NonNull MediaCodec.BufferInfo bufferInfo);

    public abstract void onOutputFormatChangedSafe(@NonNull MediaCodec mediaCodec, @NonNull MediaFormat mediaFormat);

}

然后我可以将异常冒泡到顶层线程,如果我们不能恢复,就杀死所有线程,清理并抛出原始的Exception

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48831809

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档