|
|
|
@ -8,6 +8,7 @@ import android.os.Build;
|
|
|
|
|
import android.os.Bundle;
|
|
|
|
|
import android.os.Handler;
|
|
|
|
|
import android.os.HandlerThread;
|
|
|
|
|
import android.util.Log;
|
|
|
|
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
|
|
|
|
|
@ -29,7 +30,6 @@ public class MediaCodecManager {
|
|
|
|
|
private ArrayBlockingQueue<byte[]> frameBytes;
|
|
|
|
|
private MediaCodec mMediaCodec;
|
|
|
|
|
private int mColorFormat;
|
|
|
|
|
private long mStartTime = 0;
|
|
|
|
|
private MediaFormat mediaFormat;
|
|
|
|
|
private volatile boolean isStart = false;
|
|
|
|
|
private volatile boolean isPause = false;
|
|
|
|
@ -40,11 +40,8 @@ public class MediaCodecManager {
|
|
|
|
|
|
|
|
|
|
private boolean isInitCodec;
|
|
|
|
|
|
|
|
|
|
private boolean isFlush = false;
|
|
|
|
|
|
|
|
|
|
private Handler mHandler;
|
|
|
|
|
|
|
|
|
|
private int off_y = 50, off_x = 100;
|
|
|
|
|
private int rotation;
|
|
|
|
|
|
|
|
|
|
private AndroidMuxer androidMuxer;
|
|
|
|
@ -73,7 +70,6 @@ public class MediaCodecManager {
|
|
|
|
|
* @param dstHeight
|
|
|
|
|
*/
|
|
|
|
|
public void initCodecManager(int dstWidth, int dstHeight, int rotation) {
|
|
|
|
|
isFlush = false;
|
|
|
|
|
if (!isInitCodec) {
|
|
|
|
|
mHandler.post(() -> {
|
|
|
|
|
frameBytes = new ArrayBlockingQueue<>(100);
|
|
|
|
@ -140,7 +136,6 @@ public class MediaCodecManager {
|
|
|
|
|
if (mMediaCodec != null) {
|
|
|
|
|
frameBytes.clear();
|
|
|
|
|
mHandlerThread.quit();
|
|
|
|
|
// YuvOsdUtils.releaseOsd();
|
|
|
|
|
stopMediaCodec();
|
|
|
|
|
sInstance = null;
|
|
|
|
|
if (androidMuxer != null) {
|
|
|
|
@ -155,7 +150,6 @@ public class MediaCodecManager {
|
|
|
|
|
public void addFrameData(byte[] data) {
|
|
|
|
|
if (isStart && !isPause) {
|
|
|
|
|
boolean isOffer = frameBytes.offer(data);
|
|
|
|
|
// Logger1.i(TAG, "addFrameData: isOffer=%s", isOffer);
|
|
|
|
|
if (!isOffer) {
|
|
|
|
|
frameBytes.poll();
|
|
|
|
|
frameBytes.offer(data);
|
|
|
|
@ -184,9 +178,9 @@ public class MediaCodecManager {
|
|
|
|
|
int bitRate = dstWidth * dstHeight * 3 * 8 * frameRate / compressRatio;
|
|
|
|
|
|
|
|
|
|
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
|
|
|
|
|
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
|
|
|
|
|
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, (int) (frameRate * 0.3));
|
|
|
|
|
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, mColorFormat);
|
|
|
|
|
mediaFormat.setFloat(MediaFormat.KEY_I_FRAME_INTERVAL, 5f);
|
|
|
|
|
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 3);
|
|
|
|
|
LogUtils.w("prepare format: " + mediaFormat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -208,11 +202,12 @@ public class MediaCodecManager {
|
|
|
|
|
mMediaCodec = MediaCodec.createEncoderByType(MIME_TYPE);
|
|
|
|
|
mMediaCodec.configure(mediaFormat, null, null,
|
|
|
|
|
MediaCodec.CONFIGURE_FLAG_ENCODE);
|
|
|
|
|
|
|
|
|
|
Bundle params = new Bundle();
|
|
|
|
|
params.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);
|
|
|
|
|
mMediaCodec.setParameters(params);
|
|
|
|
|
mMediaCodec.setCallback(new MediaCodec.Callback() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onInputBufferAvailable(@NonNull MediaCodec codec, int index) {
|
|
|
|
|
|
|
|
|
|
byte[] data = null;
|
|
|
|
|
try {
|
|
|
|
|
data = frameBytes.take();
|
|
|
|
@ -221,7 +216,6 @@ public class MediaCodecManager {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ByteBuffer inputBuffer = codec.getInputBuffer(index);
|
|
|
|
|
if (inputBuffer == null)
|
|
|
|
|
return;
|
|
|
|
@ -259,8 +253,10 @@ public class MediaCodecManager {
|
|
|
|
|
offset = 3;
|
|
|
|
|
}
|
|
|
|
|
int type = (outData[offset] & 0x7E) >> 1;
|
|
|
|
|
Log.i("cyy", "type = " + type);
|
|
|
|
|
if (type == NAL_VPS) {
|
|
|
|
|
vps_sps_pps_buf = outData;
|
|
|
|
|
PushHelper.INSTANCE.pushData(outData, outData.length, info.presentationTimeUs / 1000, 2);
|
|
|
|
|
} else {
|
|
|
|
|
if (type == NAL_I && vps_sps_pps_buf != null) {
|
|
|
|
|
byte[] newBuf = new byte[vps_sps_pps_buf.length + outData.length];
|
|
|
|
@ -268,8 +264,8 @@ public class MediaCodecManager {
|
|
|
|
|
System.arraycopy(outData, 0, newBuf, vps_sps_pps_buf.length, outData.length);
|
|
|
|
|
outData = newBuf;
|
|
|
|
|
}
|
|
|
|
|
PushHelper.INSTANCE.pushData(outData, outData.length, info.presentationTimeUs / 1000, type == 19 ? 2 : 1);
|
|
|
|
|
}
|
|
|
|
|
PushHelper.INSTANCE.pushData(outData, outData.length, info.presentationTimeUs / 1000);
|
|
|
|
|
codec.releaseOutputBuffer(index, false);
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
@ -305,10 +301,10 @@ public class MediaCodecManager {
|
|
|
|
|
long timeStamp = -1L;
|
|
|
|
|
|
|
|
|
|
void buildKeyFrame() {
|
|
|
|
|
if (System.currentTimeMillis() - timeStamp >= 5000) {//1000毫秒后,设置参数
|
|
|
|
|
if (System.currentTimeMillis() - timeStamp >= 3000) {
|
|
|
|
|
timeStamp = System.currentTimeMillis();
|
|
|
|
|
Bundle params = new Bundle();
|
|
|
|
|
params.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);
|
|
|
|
|
params.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 50);
|
|
|
|
|
mMediaCodec.setParameters(params);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -319,11 +315,6 @@ public class MediaCodecManager {
|
|
|
|
|
public synchronized void flushMediaCodec() {
|
|
|
|
|
LogUtils.w(TAG, "flushMediaCodec");
|
|
|
|
|
frameBytes.clear();
|
|
|
|
|
isFlush = true;
|
|
|
|
|
// lastPauseTime = (System.nanoTime()) / 1000;//记录
|
|
|
|
|
//
|
|
|
|
|
// isHasKeyFrame = false;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void stopMediaCodec() {
|
|
|
|
@ -339,7 +330,6 @@ public class MediaCodecManager {
|
|
|
|
|
}
|
|
|
|
|
isStart = false;
|
|
|
|
|
isPause = true;
|
|
|
|
|
// isHasKeyFrame = false;
|
|
|
|
|
LogUtils.w(TAG, "stopMediaCodec video");
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|