shao hua
shao hua

Reputation: 11

android mediacodec decode data to surface and save to mp4

The Byte Stream is being fed live to me from an external source with websocket

  1. I use encoder bind new surface
encodeSurface = encoder.createInputSurface();

  1. bind the decode to the surface
mediaCodecDecoder = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_VIDEO_HEVC);
mediaCodecDecoder.configure(format, encodeSurface , null, 0);
mediaCodecDecoder.start();
  1. when I Received byte[] data,use mediacodec decode
int index = mediaCodecDecoder.dequeueInputBuffer(10_000);
ByteBuffer byteBuffer = mediaCodecDecoder.getInputBuffer(index);
byteBuffer.put(data);
mediaCodecDecoder.queueInputBuffer(index, 0, data.length,System.currentTimeMillis(),0);
int encoderStatus = mediaCodecDecoder.dequeueOutputBuffer(this.decodeBufferInfo, 1_000);
if(encoderStatus>0){
 mediaCodecDecoder.releaseOutputBuffer(encoderStatus, true);
}

  1. Then, I can directly retrieve data from the encoding buffer
while(true){
int outputBufferIndex = mediaCodecEncoder.dequeueOutputBuffer(encodeBufferInfo, 10_000);
ByteBuffer encodedData = mediaCodecEncoder.getOutputBuffer(outputBufferIndex);
encodedData.position(encodeBufferInfo.offset);
encodedData.limit(encodeBufferInfo.offset + encodeBufferInfo.size);
encodeBufferInfo.presentationTimeUs = encodeBufferInfo.presentationTimeUs * 1000;
mediaMuxer.writeSampleData(trackIndex, encodedData, encodeBufferInfo);
mediaCodecEncoder.releaseOutputBuffer(outputBufferIndex, false);

Finally, I obtained the mp4 file, but the steps were cumbersome and required decoding before encoding. How to directly use raw stream data and mediamuxer to obtain MP4 I tried to use it,But this code doesn't work, not a single frame of data has been written to MP4

byte[]data;
 if (!muxerStarted) {
MediaFormat videoFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_HEVC, width, height);
            videoFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
                    MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible);
            videoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
            videoFormat.setInteger(MediaFormat.KEY_BIT_RATE, 1000_000);
            videoFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
            trackIndex = mediaMuxer.addTrack(videoFormat);
            mediaMuxer.start();
 muxerStarted = true;
}
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
bufferInfo.offset = 0;
bufferInfo.presentationTimeUs = System.currentTimeMillis();
bufferInfo.flags = frameType;
bufferInfo.size = data.length;
ByteBuffer encodeData = ByteBuffer.wrap(data);
mediaMuxer.writeSampleData(trackIndex, encodeData, bufferInfo);

Upvotes: 1

Views: 52

Answers (0)

Related Questions