Convert yuv to bitmap failed in MediaCodec

232 views Asked by At

I wanted to take buffer out , and convert it bimap images, then save it. But actually, when I used compressToJpeg, it would be crashed.

My code

 ByteBuffer[] encoderOutputBuffers = mEncoder.getOutputBuffers();
    while (true) {
        int encoderStatus = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);//TODO 获取输出buffer的状态

        if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
            // no output available yet
            if (!endOfStream) {
                break;      // out of while
            } else {
                if (VERBOSE) Log.d(TAG, "no output available, spinning to await EOS");
            }
        } else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
            // not expected for an encoder
            encoderOutputBuffers = mEncoder.getOutputBuffers();
        } else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) //TODO 格式改变时,开启muxer
        {
            // should happen before receiving buffers, and should only happen once
            if (mMuxerStarted) {
                throw new RuntimeException("format changed twice");
            }
            MediaFormat newFormat = mEncoder.getOutputFormat();
            Log.d(TAG, "encoder output format changed: " + newFormat);
            System.out.println("mEncoder.getOutputFormat(): " + newFormat);
            mTrackIndex = mMuxer.addTrack(newFormat);   // now that we have the Magic Goodies, start the muxer
            //将获取到的mediacodec的format注册到muxer里面
            mMuxer.start();
            mMuxerStarted = true;
        } else if (encoderStatus < 0) {
            Log.w(TAG, "unexpected result from encoder.dequeueOutputBuffer: " +
                    encoderStatus);
            // let's ignore it
        } else {

            ByteBuffer encodedData = encoderOutputBuffers[encoderStatus];//todo

            if (encodedData == null) {
                throw new RuntimeException("encoderOutputBuffer " + encoderStatus +
                        " was null");
            }

            if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { // TODO BUFFER_FLAG_CODEC_CONFIG 开始编码
                // The codec config data was pulled out and fed to the muxer when we got
                // the INFO_OUTPUT_FORMAT_CHANGED status.  Ignore it.
                if (VERBOSE) Log.d(TAG, "ignoring BUFFER_FLAG_CODEC_CONFIG");
                mBufferInfo.size = 0;
            }

            if (mBufferInfo.size != 0) { // TODO mBufferInfo.size大于0开始写数据
                if (!mMuxerStarted) {
                    throw new RuntimeException("muxer hasn't started");
                }

                // adjust the ByteBuffer values to match BufferInfo (not needed?)
                encodedData.position(mBufferInfo.offset);
                encodedData.limit(mBufferInfo.offset + mBufferInfo.size);

Convert Bitmap code, I think it crashed that related to ByteArrayOutputStream and compressToJpeg

                    try {
                        byte[] b = new byte[encodedData.remaining()];
                        encodedData.get(b);

                        YuvImage yuvImage = new YuvImage(b, ImageFormat.NV21,3840,2160,null);
                        if(yuvImage != null) {

                            ByteArrayOutputStream bs = new ByteArrayOutputStream();
                            yuvImage.compressToJpeg(new Rect(0, 0, 3840, 2160), 80, bs);
                            byte[] data = bs.toByteArray();

                            Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length);
                            bs.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

Error information is :

A/libc: Fatal signal 11 (SIGSEGV), code 2, fault addr 0x8d1e970c in tid 13866 (TextureMovieEnc)

                                                               [ 01-09 16:50:05.455 20274:20274 W/         ]
                                                               debuggerd: handling request: pid=13577 uid=10094 gid=10094 tid=13866

01-09 16:50:05.481 13577-13866/com.example.user.recordtest A/libc: failed to resend signal during crash: Operation not permitted

0

There are 0 answers