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