Truncate video with MediaCodec

南笙酒味 提交于 2020-06-14 02:45:07

问题


I've used Android MediaCodec library to transcode video files (mainly change the resolution Sample code here)

Another thing I want to achieve is to truncate the video - to only take the beginning 15 seconds. The logic is to check videoExtractor.getSampleTime() if it's greater than the 15 seconds, I'll just write an EOS to the decoder buffer.

But I get an exception Caused by: android.media.MediaCodec$CodecException: Error 0xfffffff3

Here is my code:

        while ((!videoEncoderDone) || (!audioEncoderDone)) {
        while (!videoExtractorDone
                && (encoderOutputVideoFormat == null || muxing)) {
            int decoderInputBufferIndex = videoDecoder.dequeueInputBuffer(TIMEOUT_USEC);
            if (decoderInputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER)
                break;

            ByteBuffer decoderInputBuffer = videoDecoderInputBuffers[decoderInputBufferIndex];
            int size = videoExtractor.readSampleData(decoderInputBuffer, 0);
            long presentationTime = videoExtractor.getSampleTime();

            if (size >= 0) {
                videoDecoder.queueInputBuffer(
                        decoderInputBufferIndex,
                        0,
                        size,
                        presentationTime,
                        videoExtractor.getSampleFlags());
            }
            videoExtractorDone = !videoExtractor.advance();

            if (!videoExtractorDone && videoExtractor.getSampleTime() > mVideoDurationLimit * 1000000) {
                videoExtractorDone = true;
            }

            if (videoExtractorDone)
                videoDecoder.queueInputBuffer(decoderInputBufferIndex,
                        0, 0, 0,  MediaCodec.BUFFER_FLAG_END_OF_STREAM);
            break;
        }

The full source code can be found here.


回答1:


I am not sure if this is the source of the error or not, but i think it is not safe write EOS to decoder buffer at arbitrary point.

The reason is when the input video is using H264 Main Profile or above, pts may not be in increasing order (because the existence of B-frame) so you may miss several frames at the end of the video. Also, when the last frame you send to the decoder is B-frame, decoder might be expecting the next packet but you send the EOS flag and produce error (not quite sure).

What you can do though, you can send EOS flag to the encoder using videoEncoder.signalEndOfInputStream() after you reach your desired frame, (pts of the output of decoder is guaranted to be in increasing order, at least after android version >= 4.3 ?)



来源:https://stackoverflow.com/questions/39568330/truncate-video-with-mediacodec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!