Created
July 2, 2018 03:20
-
-
Save lyokato/6cb6a6c23eeeb16f49e90ec1b2326439 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.lyokato.rtc360; | |
import android.content.Context; | |
import android.util.Log; | |
import android.view.Surface; | |
import com.serenegiant.usb.Size; | |
import com.serenegiant.usb.UVCCamera; | |
import org.webrtc.SurfaceTextureHelper; | |
import org.webrtc.ThreadUtils; | |
import org.webrtc.VideoCapturer; | |
import java.util.List; | |
public class UVCCameraCapturer implements VideoCapturer, | |
SurfaceTextureHelper.OnTextureFrameAvailableListener { | |
private static final String TAG = UVCCameraCapturer.class.getSimpleName(); | |
private SurfaceTextureHelper surfaceTextureHelper; | |
private VideoCapturer.CapturerObserver capturerObserver; | |
private boolean isDisposed; | |
private int width; | |
private int height; | |
private UVCCamera camera; | |
public UVCCameraCapturer(UVCCamera camera) { | |
this.camera = camera; | |
this.isDisposed = false; | |
} | |
private void checkNotDisposed() { | |
if (isDisposed) { | |
throw new RuntimeException("capturer is disposed."); | |
} | |
} | |
@Override | |
public void onTextureFrameAvailable(int oesTextureId, | |
float[] transformMatrix, | |
long timestampNs) { | |
capturerObserver.onTextureFrameCaptured( | |
width, height, oesTextureId, transformMatrix, 0 /* rotation */, timestampNs); | |
} | |
@Override | |
public void initialize(final SurfaceTextureHelper surfaceTextureHelper, | |
final Context context, | |
final VideoCapturer.CapturerObserver capturerObserver) { | |
Log.d(TAG, "initialize"); | |
checkNotDisposed(); | |
if (surfaceTextureHelper == null) { | |
throw new RuntimeException("surfaceTextureHelper not set."); | |
} | |
this.surfaceTextureHelper = surfaceTextureHelper; | |
if (capturerObserver == null) { | |
throw new RuntimeException("capturerObserver not set."); | |
} | |
this.capturerObserver = capturerObserver; | |
} | |
@Override | |
public void startCapture(final int width, | |
final int height, | |
final int ignoredFrameRate) { | |
Log.d(TAG, "startCapture"); | |
checkNotDisposed(); | |
if (setupCameraTexture(width, height)) { | |
capturerObserver.onCapturerStarted(true); | |
surfaceTextureHelper.startListening(UVCCameraCapturer.this); | |
} | |
} | |
private Size getNearestSize(List<Size> sizeList, int preferredWidth, int preferredHeight) { | |
Size selected = null; | |
int lastDiff = 10000; | |
for (Size s : sizeList) { | |
Log.d(TAG, "SIZE: " + String.valueOf(s.width) + ":" + String.valueOf(s.height)); | |
int diff = Math.abs(s.width - preferredWidth); | |
if (diff < lastDiff) { | |
selected = s; | |
} | |
} | |
return selected; | |
} | |
private boolean setupCameraTexture(final int width, final int height) { | |
Log.d(TAG, "setupCameraTexture"); | |
List<Size> sizeList = camera.getSupportedSizeList(); | |
if (sizeList.size() == 0) { | |
Log.d(TAG, "failed to obtain supported size list"); | |
camera.destroy(); | |
return false; | |
} | |
Size size = getNearestSize(sizeList, width, height); | |
this.width = size.width; | |
this.height = size.height; | |
try { | |
camera.setPreviewSize(this.width, this.height, UVCCamera.FRAME_FORMAT_MJPEG); | |
} catch (IllegalArgumentException e1) { | |
Log.d(TAG, "failed to set preview size: " + e1.getStackTrace().toString()); | |
try { | |
camera.setPreviewSize(this.width, this.height, UVCCamera.DEFAULT_PREVIEW_MODE); | |
} catch (IllegalArgumentException e2) { | |
Log.d(TAG, "failed to set preview size YUV: " + e2.getStackTrace().toString()); | |
camera.destroy(); | |
return false; | |
} | |
} | |
surfaceTextureHelper.getSurfaceTexture().setDefaultBufferSize(this.width, this.height); | |
Surface surface = new Surface(surfaceTextureHelper.getSurfaceTexture()); | |
camera.setPreviewDisplay(surface); | |
camera.startPreview(); | |
return true; | |
} | |
@Override | |
public void stopCapture() throws InterruptedException { | |
Log.d(TAG, "stopCapture"); | |
checkNotDisposed(); | |
ThreadUtils.invokeAtFrontUninterruptibly(surfaceTextureHelper.getHandler(), new Runnable() { | |
@Override | |
public void run() { | |
camera.stopPreview(); | |
surfaceTextureHelper.stopListening(); | |
capturerObserver.onCapturerStopped(); | |
} | |
}); | |
} | |
@Override | |
public void changeCaptureFormat(final int width, | |
final int height, | |
final int ignoredFrameRate) { | |
Log.d(TAG, "changeCaptureFormat"); | |
checkNotDisposed(); | |
ThreadUtils.invokeAtFrontUninterruptibly(surfaceTextureHelper.getHandler(), new Runnable() { | |
@Override | |
public void run() { | |
camera.stopPreview(); | |
setupCameraTexture(width, height); | |
surfaceTextureHelper.stopListening(); | |
capturerObserver.onCapturerStopped(); | |
} | |
}); | |
} | |
@Override | |
public void dispose() { | |
Log.d(TAG, "dispose"); | |
isDisposed = true; | |
if (camera != null) { | |
camera.destroy(); | |
camera = null; | |
} | |
} | |
@Override | |
public boolean isScreencast() { | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment