解决Android UVCCamera stopPreview 报错 崩溃 闪退 问题

在使用libuvccamera库的UVCCamera时,经常在调用stopPreview关闭预览的时候,app直接崩溃闪退了,经过综合各种修改源码的方案,已解决这个问题,以下请参考:

  1. 首先找到android_usbfs.c,linux_usbfs.c两个文件,在两个文件中都可以找到这段代码,按如下示例修改:

修改前:

for (i = 0; i < num_urbs; i++) {
	if (urb == tpriv->iso_urbs[i]) {
		urb_idx = i + 1;
		break;
	}
}

修改后:

for (i = 0; i < num_urbs; i++) {
    if (tpriv->iso_urbs == NULL){
        break;
    }
	if (urb == tpriv->iso_urbs[i]) {
		urb_idx = i + 1;
		break;
	}
}
  1. 找到UVCPreview.h文件,在volatile bool mIsCapturing;这一行下添加一行,如下:
	volatile bool mIsCapturing;
    volatile bool mHasCaptureThread;
  1. 找到UVCPreview.cpp文件,按如下修改:

修改前:

        pthread_cond_signal(&preview_sync);
        pthread_cond_signal(&capture_sync);
        if (pthread_join(capture_thread, NULL) != EXIT_SUCCESS) {
            LOGW("UVCPreview::terminate capture thread: pthread_join failed");
        }

修改后:

		pthread_cond_signal(&preview_sync);
        if (mHasCaptureThread) {
            pthread_cond_signal(&capture_sync);
            if (pthread_join(capture_thread, NULL) != EXIT_SUCCESS) {
                LOGW("UVCPreview::terminate capture thread: pthread_join failed");
            }
        }

然后同个文件中再找到do_preview函数,按如下修改:
修改前:

void UVCPreview::do_preview(uvc_stream_ctrl_t *ctrl) {
    ...

    if (LIKELY(!result)) {
        clearPreviewFrame();
        pthread_create(&capture_thread, NULL, capture_thread_func, (void *)this);

修改后:

void UVCPreview::do_preview(uvc_stream_ctrl_t *ctrl) {
    ...

    mHasCaptureThread = false;
    if (LIKELY(!result)) {
        clearPreviewFrame();
        if (pthread_create(&capture_thread, NULL, capture_thread_func, (void *)this) == 0) {
            mHasCaptureThread = true;
        }

最后,找到do_capture_callback函数,按如下修改就完成了:
修改前:

env->CallVoidMethod(mFrameCallbackObj, iframecallback_fields.onFrame, buf);

修改后:

if (iframecallback_fields.onFrame) {
    env->CallVoidMethod(mFrameCallbackObj, iframecallback_fields.onFrame, buf);
}

至此,修改完毕,重新编译运行吧!希望能够帮到你~

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
以下是一个简单的 Android UVCCamera 实现视频防抖动的示例代码: ```java public class UvcCameraPreview implements SurfaceHolder.Callback, Camera.PreviewCallback { private static final String TAG = "UvcCameraPreview"; private SurfaceHolder mHolder; private Camera mCamera; private ByteBuffer mPreviewBuffer; private byte[] mPreviewFrame; private int mPreviewWidth; private int mPreviewHeight; private int mFrameSize; private boolean mIsPreviewing = false; private Handler mHandler = new Handler(); private Runnable mStabilizationRunnable = new Runnable() { @Override public void run() { stabilizeFrame(); } }; public UvcCameraPreview(SurfaceView surfaceView) { mHolder = surfaceView.getHolder(); mHolder.addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { mCamera = Camera.open(); mCamera.setPreviewCallbackWithBuffer(this); Camera.Parameters params = mCamera.getParameters(); List<Camera.Size> sizes = params.getSupportedPreviewSizes(); Camera.Size size = sizes.get(0); params.setPreviewSize(size.width, size.height); mCamera.setParameters(params); try { mCamera.setPreviewDisplay(holder); } catch (IOException e) { e.printStackTrace(); } mPreviewWidth = size.width; mPreviewHeight = size.height; mFrameSize = mPreviewWidth * mPreviewHeight * ImageFormat.getBitsPerPixel(params.getPreviewFormat()) / 8; mPreviewBuffer = ByteBuffer.allocate(mFrameSize); mCamera.addCallbackBuffer(mPreviewBuffer.array()); mCamera.startPreview(); mIsPreviewing = true; } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { mIsPreviewing = false; mCamera.stopPreview(); mCamera.setPreviewCallback(null); mCamera.release(); mCamera = null; } @Override public void onPreviewFrame(byte[] data, Camera camera) { mPreviewFrame = data; mHandler.post(mStabilizationRunnable); if (mCamera != null && mIsPreviewing) { mCamera.addCallbackBuffer(mPreviewBuffer.array()); } } private void stabilizeFrame() { // 实现视频防抖动的代码 // 将 mPreviewFrame 中的数据进行防抖动处理 // 处理后的数据可以进行显示或者存储 // 处理完成后,可以继续进行下一帧的处理 mHandler.post(mStabilizationRunnable); } } ``` 在这个示例中,我们使用了 `SurfaceView` 来显示预览画面,并通过 `SurfaceHolder.Callback` 监听 `SurfaceView` 的生命周期。在 `surfaceCreated` 方法中,我们打开了相机,设置了预览的参数和大小,并将预览的数据回调设置为 `this`,即当前类。我们还创建了一个 `ByteBuffer` 来存储预览数据,并将其添加到相机的回调缓冲区中。 在 `onPreviewFrame` 方法中,我们将相机返回的预览数据存储到 `mPreviewFrame` 数组中,并通过 `Handler` 在另一个线程中调用 `stabilizeFrame` 方法对预览数据进行防抖动处理。在 `stabilizeFrame` 中,我们可以对 `mPreviewFrame` 数组中的数据进行防抖动处理,并将处理后的数据显示或者保存。最后,我们通过 `Handler` 的方式在处理完成后继续对下一帧数据进行处理,从而实现视频防抖动的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值