diff --git a/library-common/src/main/java/com/common/commonlib/utils/BitmapUtils.kt b/library-common/src/main/java/com/common/commonlib/utils/BitmapUtils.kt index 871137e..51eb7bc 100644 --- a/library-common/src/main/java/com/common/commonlib/utils/BitmapUtils.kt +++ b/library-common/src/main/java/com/common/commonlib/utils/BitmapUtils.kt @@ -31,4 +31,43 @@ object BitmapUtils { // backBitmap.recycle() return backBitmap } + + private var rgbaData: ByteArray? = null + + fun nv12ToRgba(nv12Data: ByteArray, width: Int, height: Int): ByteArray { + if (rgbaData == null) { + rgbaData = ByteArray(width * height * 4) + } + val frameSize = width * height + val uvIndex = frameSize + + for (j in 0 until height) { + val rgbIndex = j * width + val uvIndexLine = (j shr 1) * width + for (i in 0 until width) { + val uvIndexOffset = (i shr 1) * 2 + val y = 0xff and nv12Data[rgbIndex + i].toInt() + val u = 0xff and nv12Data[uvIndex + uvIndexOffset].toInt() - 128 + val v = 0xff and nv12Data[uvIndex + uvIndexOffset + 1].toInt() - 128 + + // 转换YUV到RGB + val r = y + 1.402f * v + val g = y - 0.344f * u - 0.714f * v + val b = y + 1.772f * u + + // 将RGB值限制在0-255范围内 + val pixelR = r.coerceIn(0f, 255f).toInt() + val pixelG = g.coerceIn(0f, 255f).toInt() + val pixelB = b.coerceIn(0f, 255f).toInt() + + // 设置RGBA值 + val rgbaIndex = (j * width + i) * 4 + rgbaData!![rgbaIndex] = pixelR.toByte() + rgbaData!![rgbaIndex + 1] = pixelG.toByte() + rgbaData!![rgbaIndex + 2] = pixelB.toByte() + rgbaData!![rgbaIndex + 3] = 255.toByte() + } + } + return rgbaData!! + } } \ No newline at end of file diff --git a/library-push/src/main/java/com/yinuo/library/vlc/encoder/MediaCodecManager.java b/library-push/src/main/java/com/yinuo/library/vlc/encoder/MediaCodecManager.java index 60b83d9..41bed30 100644 --- a/library-push/src/main/java/com/yinuo/library/vlc/encoder/MediaCodecManager.java +++ b/library-push/src/main/java/com/yinuo/library/vlc/encoder/MediaCodecManager.java @@ -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 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"); }); } diff --git a/library-push/src/main/java/com/yinuo/library/vlc/encoder/VideoEncoderCoreAvc.java b/library-push/src/main/java/com/yinuo/library/vlc/encoder/VideoEncoderCoreAvc.java index 058b0bb..6b56178 100644 --- a/library-push/src/main/java/com/yinuo/library/vlc/encoder/VideoEncoderCoreAvc.java +++ b/library-push/src/main/java/com/yinuo/library/vlc/encoder/VideoEncoderCoreAvc.java @@ -165,7 +165,7 @@ public class VideoEncoderCoreAvc extends MediaEncoderCore { outData = iframeData; } //save(outData, 0, outData.length, Environment.getExternalStorageDirectory() + "/easy.h264", true); - PushHelper.INSTANCE.pushData(outData, outData.length, mBufferInfo.presentationTimeUs / 1000); + PushHelper.INSTANCE.pushData(outData, outData.length, mBufferInfo.presentationTimeUs / 1000, 1); } mEncoder.releaseOutputBuffer(encoderStatus, false); diff --git a/library-push/src/main/java/com/yinuo/library/vlc/encoder/VideoEncoderCoreHevc.java b/library-push/src/main/java/com/yinuo/library/vlc/encoder/VideoEncoderCoreHevc.java index bf3e061..8f1e1b7 100644 --- a/library-push/src/main/java/com/yinuo/library/vlc/encoder/VideoEncoderCoreHevc.java +++ b/library-push/src/main/java/com/yinuo/library/vlc/encoder/VideoEncoderCoreHevc.java @@ -173,7 +173,7 @@ public class VideoEncoderCoreHevc extends MediaEncoderCore { System.arraycopy(outData, 0, newBuf, vps_sps_pps_buf.length, outData.length); outData = newBuf; } - PushHelper.INSTANCE.pushData(outData, outData.length, mBufferInfo.presentationTimeUs / 1000); + PushHelper.INSTANCE.pushData(outData, outData.length, mBufferInfo.presentationTimeUs / 1000, 1); } mEncoder.releaseOutputBuffer(encoderStatus, false); diff --git a/library-push/src/main/java/org/easydarwin/PushHelper.kt b/library-push/src/main/java/org/easydarwin/PushHelper.kt index 8b100e3..66b06f9 100644 --- a/library-push/src/main/java/org/easydarwin/PushHelper.kt +++ b/library-push/src/main/java/org/easydarwin/PushHelper.kt @@ -72,7 +72,10 @@ object PushHelper { mPusher = null } - fun pushData(h264: ByteArray, length: Int, timeStamp: Long) { + fun pushData(h264: ByteArray, length: Int, timeStamp: Long, type: Int = 1) { + if (!switchOpen) { + return + } if (mIp.isNullOrEmpty() || mPort.isNullOrEmpty() || mId.isNullOrEmpty()) { LogUtils.e("PushHelper error, please setPushUrl before!!") return @@ -81,7 +84,7 @@ object PushHelper { LogUtils.e("PushHelper error, please init first!!") return } - mPusher?.push(h264, 0, length, timeStamp, 1) + mPusher?.push(h264, 0, length, timeStamp, type) } private fun initHelper(hevc: Boolean) {