// started from: https://github.com/Kickflip/kickflip-android-sdk/blob/e35e0a5bb7161ccffebd564ec1a76a0e2c053fc8/sdk/src/main/java/io/kickflip/sdk/av/AndroidMuxer.java
package io.cine.android.streaming;
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.util.Log;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* @hide
*/
public class AndroidMuxer extends Muxer {
private static final String TAG = "AndroidMuxer";
private static final boolean VERBOSE = false;
private MediaMuxer mMuxer;
private boolean mStarted;
public AndroidMuxer() {
mStarted = false;
}
@Override
public void prepare(EncodingConfig config) {
super.prepare(config);
try {
switch (config.getFormat()) {
case MPEG4:
mMuxer = new MediaMuxer(config.getOutputPath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
break;
default:
throw new IllegalArgumentException("Unrecognized format!");
}
} catch (IOException e) {
throw new RuntimeException("MediaMuxer creation failed", e);
}
}
@Override
public int addTrack(MediaFormat trackFormat) {
super.addTrack(trackFormat);
if (mStarted)
throw new RuntimeException("format changed twice");
int track = mMuxer.addTrack(trackFormat);
if (allTracksAdded()) {
start();
}
return track;
}
protected void start() {
mMuxer.start();
mStarted = true;
}
public void shutdown() {
mMuxer.stop();
mStarted = false;
release();
mMuxer.release();
}
@Override
public void writeSampleData(MediaCodec encoder, int trackIndex, int bufferIndex, ByteBuffer encodedData, MediaCodec.BufferInfo bufferInfo) {
super.writeSampleData(encoder, trackIndex, bufferIndex, encodedData, bufferInfo);
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
// MediaMuxer gets the codec config info via the addTrack command
if (VERBOSE) Log.d(TAG, "ignoring BUFFER_FLAG_CODEC_CONFIG");
encoder.releaseOutputBuffer(bufferIndex, false);
return;
}
if (bufferInfo.size == 0) {
if (VERBOSE) Log.d(TAG, "ignoring zero size buffer");
encoder.releaseOutputBuffer(bufferIndex, false);
return;
}
if (!mStarted) {
Log.e(TAG, "writeSampleData called before muxer started. Ignoring packet. Track index: " + trackIndex + " tracks added: " + mNumTracks);
encoder.releaseOutputBuffer(bufferIndex, false);
return;
}
bufferInfo.presentationTimeUs = getNextRelativePts(bufferInfo.presentationTimeUs, trackIndex);
Log.d(TAG, "WRITING SAMPLE DATA TO TRACK: " + trackIndex);
mMuxer.writeSampleData(trackIndex, encodedData, bufferInfo);
encoder.releaseOutputBuffer(bufferIndex, false);
if (allTracksFinished()) {
Log.d(TAG, "ALL TRACKS FINISHED");
shutdown();
}
}
}