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