writeSampleData
在多路复用器上调用错误“已经有编解码器特定数据”时,我找不到修复程序。
有人知道这个错误的含义以及如何解决它吗?
我的片段
public void encodeVideoFromBuffer() throws Exception {
try {
// creates encoder
EncoderData encoderData = selectCodec(true);
final MediaCodec enc = encoderData.getEncoder();
final MediaMuxer mux = new MediaMuxer(mOutputPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
final long STEP_PRESENTATION_TIME_US = (long)(1.0 * 1000 * 1000 / mFrameRate);
enc.setCallback(new MediaCodec.Callback() {
private int mIndexFrame = 0;
private int mIndexTrack = -1;
@Override
public void onInputBufferAvailable(@NonNull MediaCodec codec, int index) {
if (mIndexFrame >= mBuffers.length) {
return;
}
int inputOptions = mIndexFrame < mBuffers.length - 1 ? MediaCodec.BUFFER_FLAG_CODEC_CONFIG : MediaCodec.BUFFER_FLAG_END_OF_STREAM;
// https://www.programcreek.com/java-api-examples/?class=android.graphics.YuvImage&method=compressToJpeg
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
byte[] dataToEncode = mBuffers[mIndexFrame++].array();
Bitmap bitmap = BitmapFactory.decodeByteArray(dataToEncode, 0, dataToEncode.length, options);
Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight());
final int length = bitmap.getByteCount();
ByteBuffer dst = ByteBuffer.allocate(length);
bitmap.copyPixelsToBuffer(dst);
ByteBuffer inputBuffer = enc.getInputBuffer(index);
inputBuffer.put(dst.array());
enc.queueInputBuffer(index, 0, length, index * STEP_PRESENTATION_TIME_US, 0);
}
@Override
public void onOutputBufferAvailable(@NonNull MediaCodec codec, int index, @NonNull MediaCodec.BufferInfo info) {
ByteBuffer encodedBuffer = enc.getOutputBuffer(index);
/*
if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
// The codec config data was pulled out and fed to the muxer when we got
// the INFO_OUTPUT_FORMAT_CHANGED status. Ignore it.
info.size = 0;
}
*/
if (info.size != 0) {
// adjust the ByteBuffer values to match BufferInfo (not needed?)
encodedBuffer.position(info.offset);
encodedBuffer.limit(info.offset + info.size);
mux.writeSampleData(mIndexTrack, encodedBuffer, info);
}
enc.releaseOutputBuffer(index, false);
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
enc.stop();
enc.release();
mux.stop();
mux.release();
}
}
@Override
public void onError(@NonNull MediaCodec codec, @NonNull MediaCodec.CodecException e) {
}
@Override
public void onOutputFormatChanged(@NonNull MediaCodec codec, @NonNull MediaFormat format) {
// now that we have the Magic Goodies, start the muxer
MediaFormat test = codec.getOutputFormat();
mIndexTrack = mux.addTrack(format);
mux.start();
}
});
enc.start();
} catch (Exception e) {
e.printStackTrace();
}
}