现象:
在使用Camera Preview时;热插拔摄像头会导致设备节点由/dev/video0变为/dev/video1,或者插入多个video设备时,会变为/dev/video1、/dev/video2......。
一、首先看设备节点的创建
drivers/media/video/uvc/uvc_driver.c
static int uvc_probe(struct usb_interface *intf,
const struct usb_device_id *id){
if (v4l2_device_register(&intf->dev, &dev->vdev) < 0)
goto error;
}
drivers/media/video/v4l2-devices.c
int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
{
err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1, sd->owner);
}
drivers/media/video/v4l2-dev.c
int __video_register_device(struct video_device *vdev, int type, int nr,
int warn_if_nr_in_use, struct module *owner){
int nr = -1; int minor_cnt = 64;
nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt); //设备节点名,即“/dev/video*”
vdev->num = nr;
devnode_set(vdev); //该vdev->numd对应的符号被置为1
/*
devnode_set(vdev); //该vdev->numd对应的符号被置为1
devnode_clear(vdev); //该vdev->numd对应的符号被置为0
*/
name_base = "video";
dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
ret = device_register(&vdev->dev);
vdev->dev.release = v4l2_device_release; //该接口会调用devnode_clear(vdev)
}
二、问题解决
最终修改,问题解决:
drivers/media/video/uvc/uvc_driver.c
static void uvc_disconnect(struct usb_interface *intf){
uvc_unregister_video(dev);
}
static void uvc_unregister_video(struct uvc_device *dev){
video_unregister_device(stream->vdev); //修改该接口函数
if (atomic_dec_and_test(&dev->nstreams)){ //这里也有些问题,但不是根本原因
uvc_delete(dev);
}
}
我的修改:
drivers/media/video/v4l2-dev.c
void video_unregister_device(struct video_device *vdev){
devnode_clear(vdev);//add by tankai
device_unregister(&vdev->dev); //该接口本身会调用v4l2_device_release,但却没有
}
三、其他解决办法
1.这是一个网友在HAL层的解决办法
http://blog.csdn.net/rachel_rq/article/details/7545332
2.我们在HAL的解决办法
hardware/amlogic/camera/AppCallbackNotifier.cpp
//All sub-components of Camera HAL call this whenever any error happens
void AppCallbackNotifier::errorNotify(int error)
{
LOG_FUNCTION_NAME;
CAMHAL_LOGEB("AppCallbackNotifier received error %d", error);
// If it is a fatal error abort here!
if((error == CAMERA_ERROR_FATAL) || (error == CAMERA_ERROR_HARD)) {
//We kill media server if we encounter these errors as there is
//no point continuing and apps also don't handle errors other
//than media server death always.
abort();
return;
}
if ( ( NULL != mCameraHal ) &&
( NULL != mNotifyCb ) &&
( mCameraHal->msgTypeEnabled(CAMERA_MSG_ERROR) ) )
{
CAMHAL_LOGEB("AppCallbackNotifier mNotifyCb %d", error);
mNotifyCb(CAMERA_MSG_ERROR, CAMERA_ERROR_UNKNOWN, 0, mCallbackCookie);
mCameraHal->release(); //add by tankai
}
LOG_FUNCTION_NAME_EXIT;
}