|
|
@ -14,7 +14,6 @@ import com.yinuo.library.vlc.utils.LogUtils;
|
|
|
|
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.File;
|
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
import java.nio.ByteOrder;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Created by liwentian on 2017/10/12.
|
|
|
|
* Created by liwentian on 2017/10/12.
|
|
|
@ -22,41 +21,42 @@ import java.nio.ByteOrder;
|
|
|
|
|
|
|
|
|
|
|
|
public class RtspSurfaceRender2 implements RtspHelper.RtspCallback {
|
|
|
|
public class RtspSurfaceRender2 implements RtspHelper.RtspCallback {
|
|
|
|
|
|
|
|
|
|
|
|
private ByteBuffer mBuffer;
|
|
|
|
private final SurfaceView mSurfaceView;
|
|
|
|
|
|
|
|
|
|
|
|
private SurfaceView mSurfaceView;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String mRtspUrl;
|
|
|
|
private String mRtspUrl;
|
|
|
|
|
|
|
|
|
|
|
|
private BaseMovieEncoder mVideoEncoder;
|
|
|
|
private BaseMovieEncoder mVideoEncoder;
|
|
|
|
|
|
|
|
|
|
|
|
Bitmap videoBitmap = null;
|
|
|
|
private final Object mBitmapLock = new Object();
|
|
|
|
Bitmap overLayBitmap = null;
|
|
|
|
private Bitmap mVideoBitmap = null;
|
|
|
|
TxtOverlay overlay = null;
|
|
|
|
private TxtOverlay mOverlay = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean mIsResumed = false;
|
|
|
|
|
|
|
|
private boolean mRecording = false;
|
|
|
|
|
|
|
|
|
|
|
|
// mSurfaceView 渲染线程
|
|
|
|
// mSurfaceView 渲染线程
|
|
|
|
Thread renderThread = new Thread(new Runnable() {
|
|
|
|
Thread renderThread = new Thread(new Runnable() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
public void run() {
|
|
|
|
while (true) {
|
|
|
|
while (true) {
|
|
|
|
if (videoBitmap != null) {
|
|
|
|
if (mIsResumed) {
|
|
|
|
|
|
|
|
if (mVideoBitmap != null) {
|
|
|
|
Canvas canvas = mSurfaceView.getHolder().lockCanvas();
|
|
|
|
Canvas canvas = mSurfaceView.getHolder().lockCanvas();
|
|
|
|
if (canvas != null) {
|
|
|
|
if (canvas != null) {
|
|
|
|
if (videoBitmap != null) {
|
|
|
|
synchronized (mBitmapLock) {
|
|
|
|
synchronized (videoBitmap) {
|
|
|
|
canvas.drawBitmap(mVideoBitmap, null, new Rect(0, 0, canvas.getWidth(), canvas.getHeight()), null);
|
|
|
|
canvas.drawBitmap(videoBitmap, null, new Rect(0, 0, canvas.getWidth(), canvas.getHeight()), null);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mSurfaceView.getHolder().unlockCanvasAndPost(canvas);
|
|
|
|
mSurfaceView.getHolder().unlockCanvasAndPost(canvas);
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
Thread.sleep(20);
|
|
|
|
Thread.sleep(25);
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
public RtspSurfaceRender2(SurfaceView surfaceView) {
|
|
|
|
public RtspSurfaceRender2(SurfaceView surfaceView) {
|
|
|
@ -65,22 +65,23 @@ public class RtspSurfaceRender2 implements RtspHelper.RtspCallback {
|
|
|
|
holder.addCallback(new SurfaceHolder.Callback() {
|
|
|
|
holder.addCallback(new SurfaceHolder.Callback() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void surfaceCreated(SurfaceHolder holder) {
|
|
|
|
public void surfaceCreated(SurfaceHolder holder) {
|
|
|
|
overlay = new TxtOverlay();
|
|
|
|
mOverlay = new TxtOverlay();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
|
|
|
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
|
|
|
LogUtils.v(String.format("onSurfaceChanged: width = %d, height = %d", width, height));
|
|
|
|
LogUtils.v(String.format("onSurfaceChanged: width = %d, height = %d", width, height));
|
|
|
|
mBuffer = ByteBuffer.allocateDirect(width * height * 4).order(ByteOrder.nativeOrder());
|
|
|
|
if (mVideoEncoder == null) {
|
|
|
|
|
|
|
|
LogUtils.v("init");
|
|
|
|
mVideoEncoder = new MovieEncoder1(mSurfaceView.getContext(), width, height);
|
|
|
|
mVideoEncoder = new MovieEncoder1(mSurfaceView.getContext(), width, height);
|
|
|
|
renderThread.start();
|
|
|
|
mVideoBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
|
|
videoBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
|
|
|
|
|
|
RtspHelper.getInstance().createPlayer(mRtspUrl, width, height, RtspSurfaceRender2.this);
|
|
|
|
RtspHelper.getInstance().createPlayer(mRtspUrl, width, height, RtspSurfaceRender2.this);
|
|
|
|
|
|
|
|
renderThread.start();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
|
|
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -95,6 +96,7 @@ public class RtspSurfaceRender2 implements RtspHelper.RtspCallback {
|
|
|
|
File output = CameraHelper.getOutputMediaFile(CameraHelper.MEDIA_TYPE_VIDEO, "");
|
|
|
|
File output = CameraHelper.getOutputMediaFile(CameraHelper.MEDIA_TYPE_VIDEO, "");
|
|
|
|
LogUtils.v(String.format("startRecording: %s", output));
|
|
|
|
LogUtils.v(String.format("startRecording: %s", output));
|
|
|
|
mVideoEncoder.startRecording(new BaseMovieEncoder.EncoderConfig(output, EGL14.eglGetCurrentContext()));
|
|
|
|
mVideoEncoder.startRecording(new BaseMovieEncoder.EncoderConfig(output, EGL14.eglGetCurrentContext()));
|
|
|
|
|
|
|
|
mRecording = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -103,33 +105,29 @@ public class RtspSurfaceRender2 implements RtspHelper.RtspCallback {
|
|
|
|
mSurfaceView.post(() -> {
|
|
|
|
mSurfaceView.post(() -> {
|
|
|
|
if (mVideoEncoder.isRecording()) {
|
|
|
|
if (mVideoEncoder.isRecording()) {
|
|
|
|
mVideoEncoder.stopRecording();
|
|
|
|
mVideoEncoder.stopRecording();
|
|
|
|
|
|
|
|
mRecording = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void onSurfaceDestoryed() {
|
|
|
|
public void onDestoryed() {
|
|
|
|
|
|
|
|
stopRecording();
|
|
|
|
RtspHelper.getInstance().releasePlayer();
|
|
|
|
RtspHelper.getInstance().releasePlayer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void onPreviewFrame(final ByteBuffer buffer, int width, int height) {
|
|
|
|
public void onPreviewFrame(final ByteBuffer buffer, int width, int height) {
|
|
|
|
ByteBuffer newBuffer = null;
|
|
|
|
synchronized (mBitmapLock) {
|
|
|
|
synchronized (videoBitmap) {
|
|
|
|
Bitmap overLayBitmap = mOverlay.javaOverlayBm("1111111@2222222@333333");
|
|
|
|
overLayBitmap = overlay.javaOverlayBm("1111111@2222222@333333");
|
|
|
|
mVideoBitmap.copyPixelsFromBuffer(buffer.position(0));
|
|
|
|
videoBitmap.copyPixelsFromBuffer(buffer.position(0));
|
|
|
|
mVideoBitmap = mergeBitmap(mVideoBitmap, overLayBitmap);
|
|
|
|
videoBitmap = mergeBitmap(videoBitmap, overLayBitmap);
|
|
|
|
buffer.clear();
|
|
|
|
newBuffer = ByteBuffer.allocateDirect(videoBitmap.getByteCount()).order(ByteOrder.nativeOrder());
|
|
|
|
mVideoBitmap.copyPixelsToBuffer(buffer);
|
|
|
|
videoBitmap.copyPixelsToBuffer(newBuffer);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ByteBuffer finalNewBuffer = newBuffer;
|
|
|
|
if (mRecording) {
|
|
|
|
mSurfaceView.post(() -> {
|
|
|
|
mSurfaceView.post(() -> mVideoEncoder.frameAvailable(buffer.array(), System.nanoTime()));
|
|
|
|
if (finalNewBuffer != null) {
|
|
|
|
|
|
|
|
mVideoEncoder.frameAvailable(finalNewBuffer.array(), System.nanoTime());
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
mVideoEncoder.frameAvailable(buffer.array(), System.nanoTime());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -159,4 +157,12 @@ public class RtspSurfaceRender2 implements RtspHelper.RtspCallback {
|
|
|
|
cv.restore();//存储
|
|
|
|
cv.restore();//存储
|
|
|
|
return newbmp;
|
|
|
|
return newbmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void onResume() {
|
|
|
|
|
|
|
|
this.mIsResumed = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void onPause() {
|
|
|
|
|
|
|
|
this.mIsResumed = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|