下面列出了android.graphics.SurfaceTexture#setDefaultBufferSize ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void setSurfaceTexture(SurfaceTexture aTexture, final int aWidth, final int aHeight, Runnable aFirstDrawCallback) {
mFirstDrawCallback = aFirstDrawCallback;
if (mView != null) {
super.setSurfaceTexture(aTexture, aWidth, aHeight, aFirstDrawCallback);
} else {
GeckoSession session = mSession.getGeckoSession();
if (session == null) {
return;
}
if (aTexture == null) {
setWillNotDraw(true);
return;
}
mWidth = aWidth;
mHeight = aHeight;
mTexture = aTexture;
aTexture.setDefaultBufferSize(aWidth, aHeight);
mSurface = new Surface(aTexture);
callSurfaceChanged();
}
}
/**
* 映像入力用SurfaceTexture/Surfaceを再生成する
*/
@SuppressLint("NewApi")
@WorkerThread
protected void handleReCreateInputSurface() {
if (DEBUG) Log.v(TAG, "handleReCreateInputSurface:");
synchronized (mSync) {
mEglTask.makeCurrent();
handleReleaseInputSurface();
mEglTask.makeCurrent();
if (isOES3()) {
mTexId = com.serenegiant.glutils.es3.GLHelper.initTex(
GL_TEXTURE_EXTERNAL_OES, GLES30.GL_TEXTURE0, GLES30.GL_NEAREST);
} else {
mTexId = com.serenegiant.glutils.es2.GLHelper.initTex(
GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE0, GLES20.GL_NEAREST);
}
mInputTexture = new SurfaceTexture(mTexId);
mInputSurface = new Surface(mInputTexture);
if (BuildCheck.isAndroid4_1()) {
// XXX getIntrinsicWidth/getIntrinsicHeightの代わりにmImageWidth/mImageHeightを使うべきかも?
mInputTexture.setDefaultBufferSize(getIntrinsicWidth(), getIntrinsicHeight());
}
mInputTexture.setOnFrameAvailableListener(mOnFrameAvailableListener);
}
onCreateSurface(mInputSurface);
}
@Override
protected void onStart() {
if (DEBUG) Log.d(TAG,"mScreenCaptureTask#onStart:");
mDrawer = new GLDrawer2D(true);
mTexId = mDrawer.initTex();
mSourceTexture = new SurfaceTexture(mTexId);
mSourceTexture.setDefaultBufferSize(mWidth, mHeight); // これを入れないと映像が取れない
mSourceSurface = new Surface(mSourceTexture);
mSourceTexture.setOnFrameAvailableListener(mOnFrameAvailableListener, mHandler);
mEncoderSurface = getEgl().createFromSurface(mSurface);
if (DEBUG) Log.d(TAG,"setup VirtualDisplay");
intervals = (long)(1000f / fps);
display = mMediaProjection.createVirtualDisplay(
"Capturing Display",
mWidth, mHeight, mDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mSourceSurface, mCallback, mHandler);
if (DEBUG) Log.v(TAG, "screen capture loop:display=" + display);
// 録画タスクを起床
queueEvent(mDrawTask);
}
/**
* Initializes GL state. Call this after the EGL surface has been created and made current.
*/
public void initGl(Context context, int streamWidth, int streamHeight) {
isPortrait = CameraHelper.isPortrait(context);
this.streamWidth = streamWidth;
this.streamHeight = streamHeight;
GlUtil.checkGlError("initGl start");
String vertexShader = GlUtil.getStringFromRaw(context, R.raw.simple_vertex);
String fragmentShader = GlUtil.getStringFromRaw(context, R.raw.camera_fragment);
program = GlUtil.createProgram(vertexShader, fragmentShader);
aPositionHandle = GLES20.glGetAttribLocation(program, "aPosition");
aTextureCoordHandle = GLES20.glGetAttribLocation(program, "aTextureCoord");
uMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix");
uSTMatrixHandle = GLES20.glGetUniformLocation(program, "uSTMatrix");
//camera texture
GlUtil.createExternalTextures(1, texturesID, 0);
textureID = texturesID[0];
surfaceTexture = new SurfaceTexture(textureID);
surfaceTexture.setDefaultBufferSize(streamWidth, streamHeight);
surface = new Surface(surfaceTexture);
GlUtil.checkGlError("initGl end");
}
@Override
public void initGl(int width, int height, Context context, int previewWidth,
int previewHeight) {
this.width = width;
this.height = height;
GlUtil.checkGlError("initGl start");
String vertexShader = GlUtil.getStringFromRaw(context, R.raw.simple_vertex);
String fragmentShader = GlUtil.getStringFromRaw(context, R.raw.camera_fragment);
program = GlUtil.createProgram(vertexShader, fragmentShader);
aPositionHandle = GLES20.glGetAttribLocation(program, "aPosition");
aTextureCameraHandle = GLES20.glGetAttribLocation(program, "aTextureCoord");
uMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix");
uSTMatrixHandle = GLES20.glGetUniformLocation(program, "uSTMatrix");
uSTMatrixHandle = GLES20.glGetUniformLocation(program, "uSTMatrix");
//camera texture
GlUtil.createExternalTextures(1, textureID, 0);
surfaceTexture = new SurfaceTexture(textureID[0]);
surfaceTexture.setDefaultBufferSize(width, height);
surface = new Surface(surfaceTexture);
initFBO(width, height);
GlUtil.checkGlError("initGl end");
}
@Override
protected void initGlFilter(Context context) {
String vertexShader = GlUtil.getStringFromRaw(context, R.raw.object_vertex);
String fragmentShader = GlUtil.getStringFromRaw(context, R.raw.surface_fragment);
program = GlUtil.createProgram(vertexShader, fragmentShader);
aPositionHandle = GLES20.glGetAttribLocation(program, "aPosition");
aTextureHandle = GLES20.glGetAttribLocation(program, "aTextureCoord");
aTextureObjectHandle = GLES20.glGetAttribLocation(program, "aTextureObjectCoord");
uMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix");
uSTMatrixHandle = GLES20.glGetUniformLocation(program, "uSTMatrix");
uSamplerHandle = GLES20.glGetUniformLocation(program, "uSampler");
uSamplerSurfaceHandle = GLES20.glGetUniformLocation(program, "uSamplerSurface");
uAlphaHandle = GLES20.glGetUniformLocation(program, "uAlpha");
GlUtil.createExternalTextures(1, surfaceId, 0);
surfaceTexture = new SurfaceTexture(surfaceId[0]);
surfaceTexture.setDefaultBufferSize(getWidth(), getHeight());
surface = new Surface(surfaceTexture);
if (surfaceReadyCallback != null) surfaceReadyCallback.surfaceReady(surfaceTexture);
}
@Override
public void onOpened(CameraDevice camera) {
checkIsOnCameraThread();
Logging.d(TAG, "Camera opened.");
cameraDevice = camera;
final SurfaceTexture surfaceTexture = surfaceTextureHelper.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(captureFormat.width, captureFormat.height);
surface = new Surface(surfaceTexture);
List<Surface> surfaces = new ArrayList<Surface>();
surfaces.add(surface);
if (mediaRecorderSurface != null) {
Logging.d(TAG, "Add MediaRecorder surface to capture session.");
surfaces.add(mediaRecorderSurface);
}
try {
camera.createCaptureSession(surfaces, new CaptureSessionCallback(), cameraThreadHandler);
} catch (CameraAccessException e) {
reportError("Failed to create capture session. " + e);
return;
}
}
/**
* Updates the stored videoSize and updates the default buffer size
* in the backing texture view.
*
* @param width The width for the video
* @param height The height for the video
* @return True if the surfaces DefaultBufferSize was updated
*/
protected boolean updateVideoSize(int width, int height) {
matrixManager.setIntrinsicVideoSize(width, height);
updateMatrixOnLayout();
videoSize.x = width;
videoSize.y = height;
if (width == 0 || height == 0) {
return false;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
SurfaceTexture surfaceTexture = getSurfaceTexture();
if(surfaceTexture != null) {
surfaceTexture.setDefaultBufferSize(width, height);
} else {
return false;
}
}
return true;
}
private synchronized void startPreview(SurfaceTexture surfaceTexture) {
if (cameraHandler == null) {
final CameraThread thread = new CameraThread(cameraRecordListener, new CameraThread.OnStartPreviewListener() {
@Override
public void onStart(Size previewSize, boolean flash) {
Log.d(TAG, "previewSize : width " + previewSize.getWidth() + " height = " + previewSize.getHeight());
if (glPreviewRenderer != null) {
glPreviewRenderer.setCameraResolution(new Size(previewSize.getWidth(), previewSize.getHeight()));
}
flashSupport = flash;
if (cameraRecordListener != null) {
cameraRecordListener.onGetFlashSupport(flashSupport);
}
final float previewWidth = previewSize.getWidth();
final float previewHeight = previewSize.getHeight();
glSurfaceView.post(new Runnable() {
@Override
public void run() {
if (glPreviewRenderer != null) {
glPreviewRenderer.setAngle(degrees);
glPreviewRenderer.onStartPreview(previewWidth, previewHeight, isLandscapeDevice);
}
}
});
if (glPreviewRenderer != null) {
final SurfaceTexture st = glPreviewRenderer.getPreviewTexture().getSurfaceTexture();
st.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
}
}
}, surfaceTexture, cameraManager, lensFacing);
thread.start();
cameraHandler = thread.getHandler();
}
cameraHandler.startPreview(cameraWidth, cameraHeight);
}
@Override
public void initialize(SurfaceTexture surfaceTexture)
{
MainThread.checkMainThread();
// TODO: Use preview sizes from Camera API here instead of using the
// default.
surfaceTexture.setDefaultBufferSize(DEFAULT_PREVIEW_WIDTH, DEFAULT_PREVIEW_HEIGHT);
// Detach from GL context, to allow frame distributor to attach to the
// GL context.
surfaceTexture.detachFromGLContext();
mSurfaceTextureContainer.set(new SurfaceTextureContainer(surfaceTexture));
}
private synchronized void startPreview(SurfaceTexture surfaceTexture) {
if (cameraHandler == null) {
final CameraThread thread = new CameraThread(cameraRecordListener, new CameraThread.OnStartPreviewListener() {
@Override
public void onStart(Size previewSize, boolean flash) {
Log.d(TAG, "previewSize : width " + previewSize.getWidth() + " height = " + previewSize.getHeight());
if (glPreviewRenderer != null) {
glPreviewRenderer.setCameraResolution(new Resolution(previewSize.getWidth(), previewSize.getHeight()));
}
flashSupport = flash;
if (cameraRecordListener != null) {
cameraRecordListener.onGetFlashSupport(flashSupport);
}
final float previewWidth = previewSize.getWidth();
final float previewHeight = previewSize.getHeight();
glSurfaceView.post(new Runnable() {
@Override
public void run() {
if (glPreviewRenderer != null) {
glPreviewRenderer.setAngle(degrees);
glPreviewRenderer.onStartPreview(previewWidth, previewHeight, isLandscapeDevice);
}
}
});
if (glPreviewRenderer != null) {
final SurfaceTexture st = glPreviewRenderer.getPreviewTexture().getSurfaceTexture();
st.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
}
}
}, surfaceTexture, cameraManager, lensFacing);
thread.start();
cameraHandler = thread.getHandler();
}
cameraHandler.startPreview(cameraWidth, cameraHeight);
}
/**
* SurfaceTextureManager を作成します.
*/
private synchronized void createStManager() {
if (mStManager != null) {
return;
}
mStManager = new SurfaceTextureManager();
// SurfaceTexture に解像度を設定
VideoQuality quality = getVideoQuality();
SurfaceTexture st = mStManager.getSurfaceTexture();
st.setDefaultBufferSize(quality.getVideoWidth(), quality.getVideoHeight());
}
private void initCamera() {
CameraInfo info = null;
ArrayList<CameraInfo> cameraInfos = CameraController.getInstance().getCameras();
if (cameraInfos == null) {
return;
}
for (int a = 0; a < cameraInfos.size(); a++) {
CameraInfo cameraInfo = cameraInfos.get(a);
if (isFrontface && cameraInfo.frontCamera != 0 || !isFrontface && cameraInfo.frontCamera == 0) {
info = cameraInfo;
break;
}
}
if (info == null) {
return;
}
float size4to3 = 4.0f / 3.0f;
float size16to9 = 16.0f / 9.0f;
float screenSize = (float) Math.max(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) / Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y);
org.telegram.messenger.camera.Size aspectRatio;
int wantedWidth;
int wantedHeight;
if (initialFrontface) {
aspectRatio = new Size(16, 9);
wantedWidth = 480;
wantedHeight = 270;
} else {
if (Math.abs(screenSize - size4to3) < 0.1f) {
aspectRatio = new Size(4, 3);
wantedWidth = 1280;
wantedHeight = 960;
} else {
aspectRatio = new Size(16, 9);
wantedWidth = 1280;
wantedHeight = 720;
}
}
if (textureView.getWidth() > 0 && textureView.getHeight() > 0) {
int width = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y);
int height = width * aspectRatio.getHeight() / aspectRatio.getWidth();
previewSize = CameraController.chooseOptimalSize(info.getPreviewSizes(), width, height, aspectRatio);
}
org.telegram.messenger.camera.Size pictureSize = CameraController.chooseOptimalSize(info.getPictureSizes(), wantedWidth, wantedHeight, aspectRatio);
if (pictureSize.getWidth() >= 1280 && pictureSize.getHeight() >= 1280) {
if (Math.abs(screenSize - size4to3) < 0.1f) {
aspectRatio = new Size(3, 4);
} else {
aspectRatio = new Size(9, 16);
}
org.telegram.messenger.camera.Size pictureSize2 = CameraController.chooseOptimalSize(info.getPictureSizes(), wantedHeight, wantedWidth, aspectRatio);
if (pictureSize2.getWidth() < 1280 || pictureSize2.getHeight() < 1280) {
pictureSize = pictureSize2;
}
}
SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
if (previewSize != null && surfaceTexture != null) {
surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
cameraSession = new CameraSession(info, previewSize, pictureSize, ImageFormat.JPEG);
CameraController.getInstance().open(cameraSession, surfaceTexture, new Runnable() {
@Override
public void run() {
if (cameraSession != null) {
cameraSession.setInitied();
}
checkPreviewMatrix();
}
}, new Runnable() {
@Override
public void run() {
if (delegate != null) {
delegate.onCameraCreated(cameraSession.cameraInfo.camera);
}
}
});
}
}
@CalledByNative
private static void setDefaultBufferSize(SurfaceTexture surfaceTexture, int width,
int height) {
surfaceTexture.setDefaultBufferSize(width, height);
}
public void prepareCamera(SurfaceTexture surfaceTexture, int width, int height) {
surfaceTexture.setDefaultBufferSize(width, height);
this.surfaceEncoder = new Surface(surfaceTexture);
prepared = true;
}
public void initCamera() {
CameraInfo info = null;
ArrayList<CameraInfo> cameraInfos = CameraController.getInstance().getCameras();
if (cameraInfos == null) {
return;
}
for (int a = 0; a < cameraInfos.size(); a++) {
CameraInfo cameraInfo = cameraInfos.get(a);
if (isFrontface && cameraInfo.frontCamera != 0 || !isFrontface && cameraInfo.frontCamera == 0) {
info = cameraInfo;
break;
}
}
if (info == null) {
return;
}
float size4to3 = 4.0f / 3.0f;
float size16to9 = 16.0f / 9.0f;
float screenSize = (float) Math.max(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) / Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y);
org.telegram.messenger.camera.Size aspectRatio;
int wantedWidth;
int wantedHeight;
if (initialFrontface) {
aspectRatio = new Size(16, 9);
wantedWidth = 480;
wantedHeight = 270;
} else {
if (Math.abs(screenSize - size4to3) < 0.1f) {
aspectRatio = new Size(4, 3);
wantedWidth = 1280;
wantedHeight = 960;
} else {
aspectRatio = new Size(16, 9);
wantedWidth = 1280;
wantedHeight = 720;
}
}
if (textureView.getWidth() > 0 && textureView.getHeight() > 0) {
int width;
if (useMaxPreview) {
width = Math.max(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y);
} else {
width = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y);
}
int height = width * aspectRatio.getHeight() / aspectRatio.getWidth();
previewSize = CameraController.chooseOptimalSize(info.getPreviewSizes(), width, height, aspectRatio);
}
org.telegram.messenger.camera.Size pictureSize = CameraController.chooseOptimalSize(info.getPictureSizes(), wantedWidth, wantedHeight, aspectRatio);
if (pictureSize.getWidth() >= 1280 && pictureSize.getHeight() >= 1280) {
if (Math.abs(screenSize - size4to3) < 0.1f) {
aspectRatio = new Size(3, 4);
} else {
aspectRatio = new Size(9, 16);
}
org.telegram.messenger.camera.Size pictureSize2 = CameraController.chooseOptimalSize(info.getPictureSizes(), wantedHeight, wantedWidth, aspectRatio);
if (pictureSize2.getWidth() < 1280 || pictureSize2.getHeight() < 1280) {
pictureSize = pictureSize2;
}
}
SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
if (previewSize != null && surfaceTexture != null) {
surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
cameraSession = new CameraSession(info, previewSize, pictureSize, ImageFormat.JPEG);
if (optimizeForBarcode) {
cameraSession.setOptimizeForBarcode(optimizeForBarcode);
}
CameraController.getInstance().open(cameraSession, surfaceTexture, () -> {
if (cameraSession != null) {
cameraSession.setInitied();
}
checkPreviewMatrix();
}, () -> {
if (delegate != null) {
delegate.onCameraCreated(cameraSession.cameraInfo.camera);
}
});
}
}
@CalledByNative
private static void setDefaultBufferSize(SurfaceTexture surfaceTexture, int width, int height) {
surfaceTexture.setDefaultBufferSize(width, height);
}
@CalledByNative
private static void setDefaultBufferSize(SurfaceTexture surfaceTexture, int width,
int height) {
surfaceTexture.setDefaultBufferSize(width, height);
}
/**
* internalOnStartの下請け、GLES2用
*/
@SuppressLint("NewApi")
@WorkerThread
private void internalOnStartES2() {
if (DEBUG) Log.v(TAG, String.format("internalOnStartES2:init mix texture(%dx%d)",
width(), height()));
mDrawer.updateShader(MY_FRAGMENT_SHADER_EXT_ES2);
final int uTex1 = mDrawer.glGetUniformLocation("sTexture");
GLES20.glUniform1i(uTex1, 0);
// アルファブレンド用テクスチャ/SurfaceTexture/Surfaceを生成
final int uTex2 = mDrawer.glGetUniformLocation("sTexture2");
mTexId2 = GLHelper.initTex(
GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE1,
GLES20.GL_LINEAR, GLES20.GL_LINEAR, GLES20.GL_CLAMP_TO_EDGE);
mMasterTexture2 = new SurfaceTexture(mTexId2);
mMasterTexture2.setDefaultBufferSize(width(), height());
mMasterSurface2 = new Surface(mMasterTexture2);
if (BuildCheck.isAndroid5()) {
mMasterTexture2.setOnFrameAvailableListener(
mOnFrameAvailableListener, mAsyncHandler);
} else {
mMasterTexture2.setOnFrameAvailableListener(
mOnFrameAvailableListener);
}
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexId2);
GLES20.glUniform1i(uTex2, 1);
// マスク用テクスチャ/SurfaceTexture/Surfaceを生成
final int uTex3 = mDrawer.glGetUniformLocation("sTexture3");
mMaskTexId = GLHelper.initTex(
GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE2,
GLES20.GL_LINEAR, GLES20.GL_LINEAR, GLES20.GL_CLAMP_TO_EDGE);
mMaskTexture = new SurfaceTexture(mMaskTexId);
mMaskTexture.setDefaultBufferSize(width(), height());
mMaskSurface = new Surface(mMaskTexture);
GLES20.glActiveTexture(GLES20.GL_TEXTURE2);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mMaskTexId);
GLES20.glUniform1i(uTex3, 2);
}
/**
* internalOnStartの下請け、GLES3用
*/
@SuppressLint("NewApi")
@WorkerThread
private void internalOnStartES3() {
if (DEBUG) Log.v(TAG, String.format("internalOnStartES3:init mix texture(%dx%d)",
width(), height()));
mDrawer.updateShader(MY_FRAGMENT_SHADER_EXT_ES3);
final int uTex1 = mDrawer.glGetUniformLocation("sTexture");
GLES30.glUniform1i(uTex1, 0);
// アルファブレンド用テクスチャ/SurfaceTexture/Surfaceを生成
final int uTex2 = mDrawer.glGetUniformLocation("sTexture2");
mTexId2 = GLHelper.initTex(
GL_TEXTURE_EXTERNAL_OES, GLES30.GL_TEXTURE1,
GLES30.GL_LINEAR, GLES30.GL_LINEAR, GLES30.GL_CLAMP_TO_EDGE);
mMasterTexture2 = new SurfaceTexture(mTexId2);
mMasterTexture2.setDefaultBufferSize(width(), height());
mMasterSurface2 = new Surface(mMasterTexture2);
if (BuildCheck.isAndroid5()) {
mMasterTexture2.setOnFrameAvailableListener(
mOnFrameAvailableListener, mAsyncHandler);
} else {
mMasterTexture2.setOnFrameAvailableListener(
mOnFrameAvailableListener);
}
GLES30.glActiveTexture(GLES30.GL_TEXTURE1);
GLES30.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexId2);
GLES30.glUniform1i(uTex2, 1);
// マスク用テクスチャ/SurfaceTexture/Surfaceを生成
final int uTex3 = mDrawer.glGetUniformLocation("sTexture3");
mMaskTexId = GLHelper.initTex(
GL_TEXTURE_EXTERNAL_OES, GLES30.GL_TEXTURE2,
GLES30.GL_LINEAR, GLES30.GL_LINEAR, GLES30.GL_CLAMP_TO_EDGE);
mMaskTexture = new SurfaceTexture(mMaskTexId);
mMaskTexture.setDefaultBufferSize(width(), height());
mMaskSurface = new Surface(mMaskTexture);
GLES30.glActiveTexture(GLES30.GL_TEXTURE2);
GLES30.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mMaskTexId);
GLES30.glUniform1i(uTex3, 2);
}