@ -2,15 +2,29 @@ package net.ossrs.yasea;
import android.app.Activity ;
import android.content.Context ;
import android.content.pm.PackageManager ;
import android.content.res.Configuration ;
import android.graphics.ImageFormat ;
import android.graphics.SurfaceTexture ;
import android.hardware.Camera ;
import android.hardware.camera2.CameraAccessException ;
import android.hardware.camera2.CameraCaptureSession ;
import android.hardware.camera2.CameraCharacteristics ;
import android.hardware.camera2.CameraDevice ;
import android.hardware.camera2.CameraManager ;
import android.hardware.camera2.CameraMetadata ;
import android.hardware.camera2.CaptureRequest ;
import android.hardware.camera2.params.StreamConfigurationMap ;
import android.media.ImageReader ;
import android.opengl.GLES20 ;
import android.opengl.GLSurfaceView ;
import android.opengl.Matrix ;
import android.support.annotation.NonNull ;
import android.support.v4.app.ActivityCompat ;
import android.util.AttributeSet ;
import android.util.Log ;
import android.util.Range ;
import android.util.Size ;
import android.view.Surface ;
import com.seu.magicfilter.base.gpuimage.GPUImageFilter ;
@ -21,6 +35,8 @@ import com.seu.magicfilter.utils.OpenGLUtils;
import java.io.IOException ;
import java.nio.ByteBuffer ;
import java.nio.IntBuffer ;
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.List ;
import java.util.concurrent.ConcurrentLinkedQueue ;
@ -59,6 +75,15 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
private ConcurrentLinkedQueue < IntBuffer > mGLIntBufferCache = new ConcurrentLinkedQueue < > ( ) ;
private PreviewCallback mPrevCb ;
private CameraCallbacksHandler cameraCallbacksHandler = new CameraCallbacksHandler ( ) ;
private CameraDevice mCameraDevice ; //摄像头设备
private Size imageDimension ;
private ImageReader imageReader ;
private CaptureRequest . Builder captureRequestBuilder ;
private CameraCaptureSession cameraCaptureSession ;
private CameraManager cameraManager ; //摄像头管理类
private String [ ] cameraNames ; //摄像头名称列表
private CameraItemData curItem ; //当前选中的摄像头参数
private ArrayList < CameraItemData > itemlist = new ArrayList < > ( ) ;
public SrsCameraView ( Context context ) {
this ( context , null ) ;
@ -119,17 +144,17 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
@Override
public void onDrawFrame ( GL10 gl ) {
if ( mSurfaceWidth ! = mPreviewWidth | | mSurfaceHeight ! = mPreviewHeight ) {
if ( mSurfaceWidth ! = mPreviewWidth | | mSurfaceHeight ! = mPreviewHeight ) {
//May be a buffer overflow in enableEncoding()
//mPreviewWidth changed but onSurfaceCreated fired after enable encoding (mIsEncoding == true)
//could be calling magicFilter.onInputSizeChanged(width, height) in setPreviewResolution() after changing mGLPreviewBuffer?
//or start the encoder only after onSurfaceCreated ...
Log . e ( TAG , String . format ( "Surface dimensions differ from Preview. May be a buffer overflow. Surface: %dx%d, Preview: %dx%d " , mSurfaceWidth , mSurfaceHeight , mPreviewWidth , mPreviewHeight ) ) ;
return ;
}
}
GLES20 . glClearColor ( 0.0f , 0.0f , 0.0f , 0.0f ) ;
GLES20 . glClear ( GLES20 . GL_COLOR_BUFFER_BIT | GLES20 . GL_DEPTH_BUFFER_BIT ) ;
@ -140,8 +165,8 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
magicFilter . setTextureTransformMatrix ( mTransformMatrix ) ;
magicFilter . onDrawFrame ( mOESTextureId ) ;
if ( mIsEncoding ) {
mGLIntBufferCache . add ( magicFilter . getGLFboBuffer ( ) ) ;
if ( mIsEncoding ) {
mGLIntBufferCache . add ( magicFilter . getGLFboBuffer ( ) ) ;
synchronized ( writeLock ) {
writeLock . notifyAll ( ) ;
}
@ -151,34 +176,96 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
public void setPreviewCallback ( PreviewCallback cb ) {
mPrevCb = cb ;
}
public Camera getCamera ( ) {
public Camera getCamera ( ) {
return this . mCamera ;
}
public void setPreviewCallback ( Camera . PreviewCallback previewCallback ) {
public void setPreviewCallback ( Camera . PreviewCallback previewCallback ) {
this . mCamera . setPreviewCallback ( previewCallback ) ;
}
public int [ ] setPreviewResolution ( int width , int height ) {
mCamera = openCamera ( ) ;
//设置预览宽高
public int [ ] setPreviewResolution2 ( int width , int height ) {
mPreviewWidth = width ;
mPreviewHeight = height ;
Camera . Size rs = adaptPreviewResolution ( mCamera . new Size ( width , height ) ) ;
if ( rs ! = null ) {
mPreviewWidth = rs . width ;
mPreviewHeight = rs . height ;
// try {
// String s = cameraManager.getCameraIdList()[1];
// CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(s);
// //获取StreamConfigurationMap, 它是管理摄像头支持的所有输出格式和尺寸
// StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
// //根据TextureView的尺寸设置预览尺寸
// Size mPreviewSize = getOptimalSize(map.getOutputSizes(SurfaceTexture.class), width, height);
// mPreviewWidth = mPreviewSize.getWidth();
// mPreviewHeight = mPreviewSize.getHeight();
return new int [ ] { mPreviewWidth , mPreviewHeight } ;
// } catch (CameraAccessException e) {
// throw new RuntimeException(e);
// }
}
//选择sizeMap中大于并且接近width和height的size
private Size getOptimalSize ( Size [ ] outputSizes , int width , int height ) {
Size tempSize = new Size ( width , height ) ;
List < Size > sizes = new ArrayList < > ( ) ;
for ( Size outputSize : outputSizes ) {
if ( width > height ) {
//横屏的时候
if ( outputSize . getHeight ( ) > height & & outputSize . getWidth ( ) > width ) {
sizes . add ( outputSize ) ;
}
} else {
//竖屏的时候
if ( outputSize . getWidth ( ) > height & & outputSize . getHeight ( ) > width ) {
sizes . add ( outputSize ) ;
}
}
}
if ( sizes . size ( ) > 0 ) {
//如果有多个符合条件找到一个差距最小的,最接近预览分辨率的
tempSize = sizes . get ( 0 ) ;
int minnum = 999999 ;
for ( Size size : sizes ) {
int num = size . getHeight ( ) * size . getHeight ( ) - width * height ;
if ( num < minnum ) {
minnum = num ;
tempSize = size ;
}
}
}
return tempSize ;
/ * if ( sizes . size ( ) > 0 ) {
return Collections . min ( sizes , new Comparator < Size > ( ) {
@Override
public int compare ( Size size , Size t1 ) {
return Long . signum ( size . getWidth ( ) * size . getHeight ( ) - t1 . getWidth ( ) * t1 . getHeight ( ) ) ;
}
} ) ;
}
return outputSizes [ 0 ] ; * /
}
public int [ ] setPreviewResolution ( int width , int height ) {
// mCamera = openCamera();
mPreviewWidth = width ;
mPreviewHeight = height ;
// Camera.Size rs = adaptPreviewResolution(mCamera.new Size(width, height));
// if (rs != null) {
// mPreviewWidth = rs.width;
// mPreviewHeight = rs.height;
// }
getHolder ( ) . setFixedSize ( mPreviewWidth , mPreviewHeight ) ;
mCamera . getParameters ( ) . setPreviewSize ( mPreviewWidth , mPreviewHeight ) ;
// mCamera.getParameters().setPreviewSize(mPreviewWidth, mPreviewHeight);
mGLPreviewBuffer = ByteBuffer . allocate ( mPreviewWidth * mPreviewHeight * 4 ) ;
mInputAspectRatio = mPreviewWidth > mPreviewHeight ?
( float ) mPreviewWidth / mPreviewHeight : ( float ) mPreviewHeight / mPreviewWidth ;
mInputAspectRatio = mPreviewWidth > mPreviewHeight ? ( float ) mPreviewWidth / mPreviewHeight : ( float ) mPreviewHeight / mPreviewWidth ;
return new int [ ] { mPreviewWidth , mPreviewHeight } ;
return new int [ ] { mPreviewWidth , mPreviewHeight } ;
}
public boolean setFilter ( final MagicFilterType type ) {
@ -209,14 +296,20 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
queueEvent ( new Runnable ( ) {
@Override
public void run ( ) {
GLES20 . glDeleteTextures ( 1 , new int [ ] { mOESTextureId } , 0 ) ;
GLES20 . glDeleteTextures ( 1 , new int [ ] { mOESTextureId } , 0 ) ;
mOESTextureId = OpenGLUtils . NO_TEXTURE ;
}
} ) ;
}
}
public void setCameraId ( int id ) {
public void setCameraId ( CameraItemData item ) {
stopTorch ( ) ;
curItem = item ;
setPreviewOrientation ( mPreviewOrientation ) ;
}
public void setCameraId2 ( int id ) {
stopTorch ( ) ;
mCamId = id ;
setPreviewOrientation ( mPreviewOrientation ) ;
@ -235,20 +328,38 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
case Surface . ROTATION_270 :
return 270 ;
}
} catch ( Exception e ) {
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
return - 1 ;
}
public void setPreviewOrientation ( int orientation ) {
mPreviewOrientation = orientation ;
try {
String s = cameraManager . getCameraIdList ( ) [ 1 ] ;
CameraCharacteristics cameraCharacteristics = cameraManager . getCameraCharacteristics ( s ) ;
Integer integer = cameraCharacteristics . get ( CameraCharacteristics . LENS_FACING ) ;
if ( integer = = CameraCharacteristics . LENS_FACING_BACK ) {
Log . e ( "yyy" , "fds" ) ;
} else if ( integer = = CameraCharacteristics . LENS_FACING_BACK ) {
Log . e ( "yyy" , "fds" ) ;
} else {
Log . e ( "yyy" , "fds" ) ;
}
} catch ( CameraAccessException e ) {
throw new RuntimeException ( e ) ;
}
}
public void setPreviewOrientation2 ( int orientation ) {
mPreviewOrientation = orientation ;
Camera . CameraInfo info = new Camera . CameraInfo ( ) ;
Camera . getCameraInfo ( mCamId , info ) ;
int rotateDeg = getRotateDeg ( ) ;
if ( orientation = = Configuration . ORIENTATION_PORTRAIT ) {
if ( info . facing = = Camera . CameraInfo . CAMERA_FACING_FRONT ) {
mPreviewRotation = info . orientation % 360 ;
@ -264,11 +375,11 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
mPreviewRotation = ( info . orientation + 90 ) % 360 ;
}
}
if ( rotateDeg > 0 ) {
if ( rotateDeg > 0 ) {
mPreviewRotation = mPreviewRotation % rotateDeg ;
}
}
}
public int getCameraId ( ) {
@ -285,7 +396,7 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
IntBuffer picture = mGLIntBufferCache . poll ( ) ;
mGLPreviewBuffer . asIntBuffer ( ) . put ( picture . array ( ) ) ;
mPrevCb . onGetRgbaFrame ( mGLPreviewBuffer . array ( ) , mPreviewWidth , mPreviewHeight ) ;
} catch ( Exception e ) {
} catch ( Exception e ) {
cameraCallbacksHandler . onError ( e ) ;
e . printStackTrace ( ) ;
worker . interrupt ( ) ;
@ -328,13 +439,104 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
}
}
public boolean startCamera ( ) {
if ( mCamera = = null ) {
mCamera = openCamera ( ) ;
if ( mCamera = = null ) {
return false ;
//相机状态变化时会调用这里的回调函数
private final CameraDevice . StateCallback stateCallback = new CameraDevice . StateCallback ( ) {
@Override
public void onOpened ( @NonNull CameraDevice camera ) {
//相机打开时执行
Log . e ( TAG , "onOpened" ) ;
mCameraDevice = camera ;
//创建相机预览会话
createCameraPreviewSession ( ) ;
}
@Override
public void onDisconnected ( @NonNull CameraDevice camera ) {
//相机链接断开
Log . e ( "dsdsfd" , "fdsdf" ) ;
}
@Override
public void onError ( @NonNull CameraDevice camera , int error ) {
Log . e ( "dsdsfd" , "fdsdf" ) ;
}
} ;
private void createCameraPreviewSession ( ) {
// SurfaceTexture surfaceTexture=new SurfaceTexture();
// assert surfaceTexture!=null;
//
// surfaceTexture.setDefaultBufferSize(imageDimension.getWidth(),imageDimension.getHeight());
//预览的输出画面
Surface surface = new Surface ( surfaceTexture ) ;
try {
//预览请求
captureRequestBuilder = mCameraDevice . createCaptureRequest ( CameraDevice . TEMPLATE_PREVIEW ) ;
captureRequestBuilder . addTarget ( surface ) ;
mCameraDevice . createCaptureSession ( Arrays . asList ( surface , imageReader . getSurface ( ) ) , new CameraCaptureSession . StateCallback ( ) {
@Override
public void onConfigured ( @NonNull CameraCaptureSession session ) {
if ( mCameraDevice = = null ) {
return ;
}
cameraCaptureSession = session ;
updatePreview ( ) ;
}
@Override
public void onConfigureFailed ( @NonNull CameraCaptureSession session ) {
Log . e ( "dkkd" , "fdsa" ) ;
}
} , null ) ;
} catch ( CameraAccessException e ) {
throw new RuntimeException ( e ) ;
}
}
private void updatePreview ( ) {
captureRequestBuilder . set ( CaptureRequest . CONTROL_AF_MODE , CaptureRequest . CONTROL_AF_MODE_CONTINUOUS_PICTURE ) ;
CaptureRequest captureRequest = captureRequestBuilder . build ( ) ;
try {
cameraCaptureSession . setRepeatingRequest ( captureRequest , null , null ) ;
} catch ( CameraAccessException e ) {
throw new RuntimeException ( e ) ;
}
}
public void startCamera ( ) {
try {
if ( curItem = = null ) {
curItem = itemlist . get ( 0 ) ;
}
//通过cameraId获取Camera参数
// String cameraId = curItem.getId();
String cameraId = cameraManager . getCameraIdList ( ) [ 1 ] ;
CameraCharacteristics characteristics = cameraManager . getCameraCharacteristics ( cameraId ) ;
StreamConfigurationMap map = characteristics . get ( CameraCharacteristics . SCALER_STREAM_CONFIGURATION_MAP ) ;
imageDimension = map . getOutputSizes ( SurfaceTexture . class ) [ 0 ] ;
imageReader = ImageReader . newInstance ( 640 , 480 , ImageFormat . YUV_420_888 , 10 ) ;
// imageReader.setOnImageAvailableListener(onImageAvailableListener,null);
if ( ActivityCompat . checkSelfPermission ( getContext ( ) , android . Manifest . permission . CAMERA ) ! = PackageManager . PERMISSION_GRANTED ) {
}
cameraManager . openCamera ( cameraId , stateCallback , null ) ;
} catch ( CameraAccessException e ) {
throw new RuntimeException ( e ) ;
}
}
public boolean startCamera2 ( ) {
// if (mCamera == null) {
// mCamera = openCamera();
// if (mCamera == null) {
// return false;
// }
// }
Camera . Parameters params = mCamera . getParameters ( ) ;
//params.setPictureSize(mPreviewWidth, mPreviewHeight);
@ -387,6 +589,12 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
public void stopCamera ( ) {
disableEncoding ( ) ;
stopTorch ( ) ;
mCameraDevice . close ( ) ;
}
public void stopCamera2 ( ) {
disableEncoding ( ) ;
stopTorch ( ) ;
if ( mCamera ! = null ) {
@ -395,22 +603,26 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
mCamera . release ( ) ;
mCamera = null ;
}
}
protected Camera openCamera ( ) {
protected Camera openCamera 2 ( ) {
Camera camera = null ;
if ( mCamId < 0 ) {
Camera . CameraInfo info = new Camera . CameraInfo ( ) ;
int numCameras = Camera . getNumberOfCameras ( ) ;
int frontCamId = - 1 ;
int backCamId = - 1 ;
int otherCamId = - 1 ;
for ( int i = 0 ; i < numCameras ; i + + ) {
Camera . getCameraInfo ( i , info ) ;
if ( info . facing = = Camera . CameraInfo . CAMERA_FACING_BACK ) {
backCamId = i ;
} else if ( info . facing = = Camera . CameraInfo . CAMERA_FACING_FRONT ) {
frontCamId = i ;
break ;
// break;
} else {
otherCamId = i ;
}
}
if ( frontCamId ! = - 1 ) {
@ -418,28 +630,93 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
} else if ( backCamId ! = - 1 ) {
mCamId = backCamId ;
} else {
mCamId = 0 ;
mCamId = otherCamId ;
}
}
try {
camera = Camera . open ( mCamId ) ;
camera . setErrorCallback ( new Camera . ErrorCallback ( ) {
// if (mCamId == 0) {
// camera = Camera.open(2);
// } else {
camera . stopPreview ( ) ;
camera . release ( ) ;
camera = Camera . open ( ) ;
// }
camera . setErrorCallback ( new Camera . ErrorCallback ( ) {
@Override
public void onError ( int error , Camera camera ) {
//may be Camera.CAMERA_ERROR_EVICTED - Camera was disconnected due to use by higher priority user
stopCamera ( ) ;
}
} ) ;
} catch ( Exception e ) {
} ) ;
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
return camera ;
}
public List < CameraItemData > getCameraData ( ) {
itemlist = new ArrayList ( ) ;
cameraManager = ( CameraManager ) getContext ( ) . getSystemService ( Context . CAMERA_SERVICE ) ; //获取摄像头管理类
try {
cameraNames = cameraManager . getCameraIdList ( ) ; //获取摄像头名称列表
} catch ( CameraAccessException e ) {
throw new RuntimeException ( e ) ;
}
for ( String cameraName : cameraNames ) {
CameraItemData itemData = new CameraItemData ( ) ;
itemData . setId ( cameraName ) ; //摄像头编号
CameraCharacteristics characteristics = null ;
try {
characteristics = cameraManager . getCameraCharacteristics ( cameraName ) ; //获取摄像头各种特性
} catch ( CameraAccessException e ) {
throw new RuntimeException ( e ) ;
}
int sensorOrientation = characteristics . get ( CameraCharacteristics . SENSOR_ORIENTATION ) ;
itemData . setSensorOrientation ( sensorOrientation ) ; //摄像头朝向
Range < Integer > [ ] ranges = characteristics . get ( CameraCharacteristics . CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES ) ;
itemData . setFPS_RANGES ( ranges ) ; //
Long aLong = characteristics . get ( CameraCharacteristics . SENSOR_INFO_MAX_FRAME_DURATION ) ;
itemData . setMAX_FRAME_DURATION ( aLong ) ;
int lensFacing = characteristics . get ( CameraCharacteristics . LENS_FACING ) ;
itemData . setLENS_FACING ( lensFacing ) ;
switch ( lensFacing ) {
case CameraMetadata . LENS_FACING_FRONT :
Log . e ( "lensFacing(前后摄):" , "front" ) ;
break ;
case CameraMetadata . LENS_FACING_BACK :
Log . e ( "lensFacing(前后摄):" , "back" ) ;
break ;
case CameraMetadata . LENS_FACING_EXTERNAL :
Log . e ( "lensFacing(前后摄):" , "external" ) ;
break ;
}
List < int [ ] > list = new ArrayList < > ( ) ;
Size [ ] supportedSizes = characteristics . get ( CameraCharacteristics . SCALER_STREAM_CONFIGURATION_MAP ) . getOutputSizes ( ImageFormat . YUV_420_888 ) ;
for ( Size size : supportedSizes ) {
int width = size . getWidth ( ) ;
int height = size . getHeight ( ) ;
// 在这里处理支持的分辨率格式
int [ ] temp = { width , height } ;
list . add ( temp ) ;
}
itemData . setSupportedSizes ( list ) ; //摄像头输出格式
itemlist . add ( itemData ) ;
}
return itemlist ;
}
private Camera . Size adaptPreviewResolution ( Camera . Size resolution ) {
float diff = 100 f ;
float xdy = ( float ) resolution . width / ( float ) resolution . height ;
@ -494,7 +771,7 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
Camera . Parameters params = mCamera . getParameters ( ) ;
params . setFlashMode ( Camera . Parameters . FLASH_MODE_OFF ) ;
mCamera . setParameters ( params ) ;
} catch ( Exception e ) {
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
}
@ -504,27 +781,28 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
void onGetRgbaFrame ( byte [ ] data , int width , int height ) ;
}
static public class CameraCallbacksHandler implements CameraCallbacks {
static public class CameraCallbacksHandler implements CameraCallbacks {
@Override
public void onCameraParameters ( Camera . Parameters params ) {
}
@Override
public void onError ( Exception e ) {
//stop publish
}
}
}
public interface CameraCallbacks {
void onCameraParameters ( Camera . Parameters params ) ;
void onError ( Exception e ) ;
}
public void setCameraCallbacksHandler ( CameraCallbacksHandler cameraCallbacksHandler ) {
this . cameraCallbacksHandler = cameraCallbacksHandler ;
}
}
}