深入浅出,camera v4l2理解

八、V4L2 ioctl 控制接口 调用流程 V4L2 ioctl 控制接口 调用流程 当 使用v4l2打开配置好video节点后,还可能需要对设备进行参数 sensor 或者ISP的参数配置,例如自动对焦、自动曝光、亮度、对比度、锐度、色度、白平衡、测试图案等等 V4L2_CID_BRIGHTNESS 我们举例 设置亮度 static void set_sensor_brightness(int videofd, int brightness) { struct v4l2_control ctrl; ctrl.id = V4L2_C 阅读详情

 

深入浅出,camera v4l2理解(1)v4l2准备使用的参数 1,probe


2,读id,id读完了并且成功才能注册v4l2
 
3,注册v4l2,
v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,s_ctrl->sensor_v4l2_subdev_ops);
这里v4l2的注册需要几个参数
s_ctrl->sensor_v4l2_subdev
这个参数主要是v4l2的名字,这个name是从驱动中去读的,如下
snprintf(s_ctrl->sensor_v4l2_subdev.name,sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);


client
这个参数是i2c的client,从驱动中获取,读id的时候使用的那个


s_ctrl->sensor_v4l2_subdev_ops
这个参数是驱动中的imx111_subdev_ops
static struct v4l2_subdev_core_ops imx111_subdev_core_ops = {
  .ioctl                     = msm_sensor_subdev_ioctl,   //各种效果等控制参数的传递
  .s_power                   = msm_sensor_power,          //power
};


static struct v4l2_subdev_video_ops imx111_subdev_video_ops = {
  .enum_mbus_fmt             = msm_sensor_v4l2_enum_fmt,
};


static struct v4l2_subdev_ops imx111_subdev_ops = {
  .core                      = &imx111_subdev_core_ops,   //见上面
  .video                     = &imx111_subdev_video_ops,  //见上面
};


int32_t msm_sensor_v4l2_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
                        enum v4l2_mbus_pixelcode *code)
{
       struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);   //这边不用说,还是驱动那个s_ctrl


       if ((unsigned int)index >= s_ctrl->sensor_v4l2_subdev_info_size) //这里就是看你准备了多少种code,看看是不是超出了所定义的 
              return -EINVAL;


       *code = s_ctrl->sensor_v4l2_subdev_info[index].code;   //调用驱动中的code
       return 0;
}
static struct v4l2_subdev_info imx111_subdev_info[] = {       //这个在驱动里面,就是上面的那个info
  {
    .code                    = V4L2_MBUS_FMT_SRGGB10_1X10,
    .colorspace              = V4L2_COLORSPACE_JPEG,
    .fmt                     = 1,
    .order                   = 0,
  },
};
深入浅出,camera v4l2理解(2)v4l2注册
2013-06-04 16:36 290人阅读 评论(0) 收藏 举报
正式步入v4l2_i2c_subdev_init
这个是什么呢,看代码:
这个是在v4l2-common里面:
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
                const struct v4l2_subdev_ops *ops)
{
        v4l2_subdev_init(sd, ops);    //这个地方属于初始化,也就是申请相关空间
        sd->flags |= V4L2_SUBDEV_FL_IS_I2C;  //说明这个是个i2c的
        /* the owner is the same as the i2c_client's driver owner */
        sd->owner = client->driver->driver.owner;
        /* i2c_client and v4l2_subdev point to one another */
        v4l2_set_subdevdata(sd, client);   //相互保存数据
        i2c_set_clientdata(client, sd);    //相互保存数据
        /* initialize name */
        snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",  //在这个地方这个name改变了,这里也就是注册mipi的时候用到的名字,每个mipi的每个线都要和这个名字对应,分别是name-所在的i2c总线-i2c的地址
                client->driver->driver.name, i2c_adapter_id(client->adapter),
                client->addr);
}
EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);


这个函数主要起到保存参数的总用,后续调用更加的方便。


在这个函数后,真正对v4l2配置的在下面这个函数:


/* register a msm sensor into the msm device, which will probe the
 * sensor HW. if the HW exist then create a video device (/dev/videoX/)
 * to represent this sensor */


一个v4l2的接口在/dev/videoX/每一个videoX对应一个v4l2的设备节点,从这个开始才是v4l2的重点:


int msm_sensor_register(struct v4l2_subdev *sensor_sd)
{
       int rc = -EINVAL;
       struct msm_camera_sensor_info *sdata;
       struct msm_cam_v4l2_device *pcam;
       struct msm_sensor_ctrl_t *s_ctrl;


       D("%s for %s\n", __func__, sensor_sd->name);


       /* allocate the memory for the camera device first */
       pcam = kzalloc(sizeof(*pcam), GFP_KERNEL);
       if (!pcam) {
              pr_err("%s: could not allocate mem for msm_cam_v4l2_device\n",
                     __func__);
              return -ENOMEM;
       }


       pcam->sensor_sdev = sensor_sd;   //这个sensor_sd,就是一个v4l2的name而已,里面的成员只做了赋值为0的初始化动作,后面会看到它的羽翼逐渐丰满。
       s_ctrl = get_sctrl(sensor_sd);
       sdata = (struct msm_camera_sensor_info *) s_ctrl->sensordata;//这个很眼熟,不就是那个board中的msm_camera_sensor_info嘛!它包含了对sensor的很多信息,power啊reset啊 是否是有yuv的还是raw的,有没有对焦啊,什么都有!


       pcam->act_sdev = msm_actuator_probe(sdata->actuator_info);//这个地方看了对马达的probe了没,马达的i2c的probe就是从这个地方开始的
       pcam->eeprom_sdev = msm_eeprom_probe(sdata->eeprom_info); //这个地方对应board中的eeprom_info


       D("%s: pcam =0x%p\n", __func__, pcam);


       pcam->sdata = sdata;   //msm_camera_sensor_info进去了


       /* init the user count and lock*/
       pcam->use_count = 0;
       mutex_init(&pcam->vid_lock);
       mutex_init(&pcam->mctl_node.dev_lock);


       /* Initialize the formats supported */
       rc  = msm_mctl_init_user_formats(pcam);

 


/**************************************************************************************************/


这个函数主要是对camera输出的格式定义,这样v4l2才可以接受
int msm_mctl_init_user_formats(struct msm_cam_v4l2_device *pcam)
{
       struct v4l2_subdev *sd = pcam->sensor_sdev;
       enum v4l2_mbus_pixelcode pxlcode;
       int numfmt_sensor = 0;
       int numfmt = 0;
       int rc = 0;
       int i, j;


       D("%s\n", __func__);
       while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, numfmt_sensor,    //别看了这个是用来判断是否存在pxlcode空指针的,用这个来判断你个v4l2支持多个格式
                                                        &pxlcode))
              numfmt_sensor++;       //格式的数量加加~


       D("%s, numfmt_sensor = %d\n", __func__, numfmt_sensor);
       if (!numfmt_sensor)
              return -ENXIO;


       pcam->usr_fmts = vmalloc(numfmt_sensor * ARRAY_SIZE(msm_isp_formats) * //知不知道v4l2对sensor输出格式的接受是有
                            sizeof(struct msm_isp_color_fmt));  //明确的定义的?这个函数的意思是在所有的可以接受的格式先保存下来,很多十多组吧。
       if (!pcam->usr_fmts)
              return -ENOMEM;


       /* from sensor to ISP.. fill the data structure */
       for (i = 0; i < numfmt_sensor; i++) {                                  //这里对每一个v4l2选择他对应的输出格式,有一个,配一个,可配置多个,也就是说一个sensor可能支持多个格式的输出嘛~
              rc = v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &pxlcode);   //循环取pxlcode空指针的,空了推出
              D("rc is  %d\n", rc);
              if (rc < 0) {
                     vfree(pcam->usr_fmts);
                     return rc;
              }


              for (j = 0; j < ARRAY_SIZE(msm_isp_formats); j++) {             //找一找pxlcode是否能匹配,不能换下一个pxlcode,一个sensor能提供多个pxlcode
                     /* find the corresponding format */
                     if (pxlcode == msm_isp_formats[j].pxlcode) {
                            pcam->usr_fmts[numfmt] = msm_isp_formats[j];
                            D("pcam->usr_fmts=0x%x\n", (u32)pcam->usr_fmts);
                            D("format pxlcode 0x%x (0x%x) found\n",
                                     pcam->usr_fmts[numfmt].pxlcode,//如果你配置的参数在列表中有,恭喜你匹配成功,记录在pcam->usr_fmts[numfmt].pxlcode
                                     pcam->usr_fmts[numfmt].fourcc);////如果你配置的参数在列表中有,恭喜你匹配成功,记录在pcam->usr_fmts[numfmt].pxlcode
                            numfmt++;
                     }
              }
       }


       pcam->num_fmts = numfmt;   //你有多少个支持的格式啊?


       if (numfmt == 0) {      //老子没有!
              pr_err("%s: No supported formats.\n", __func__);
              vfree(pcam->usr_fmts);
              return -EINVAL;  //滚粗!
       }


       D("Found %d supported formats.\n", pcam->num_fmts);
       /* set the default pxlcode, in any case, it will be set through
        * setfmt */
       return 0;
}


/**************************************************************************************************/


       if (rc < 0)
              goto failure;


       rc  = msm_cam_dev_init(pcam);
       if (rc < 0)
              goto failure;


/*************************************************************************************************


static int msm_cam_dev_init(struct msm_cam_v4l2_device *pcam)
{
       int rc = -ENOMEM;
       struct video_device *pvdev = NULL;
       struct i2c_client *client =v4l2_get_subdevdata(pcam->sensor_sdev);  //之前保存的现在拿出来用了
       D("%s\n", __func__);


       /* first register the v4l2 device */
       pcam->v4l2_dev.dev = &client->dev;
       rc = v4l2_device_register(pcam->v4l2_dev.dev, &pcam->v4l2_dev);    //初始化参数用


       if (rc < 0)
              return -EINVAL;
          /*********************************************
             int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
           {
               if (v4l2_dev == NULL)
                 return -EINVAL;


              INIT_LIST_HEAD(&v4l2_dev->subdevs);
              spin_lock_init(&v4l2_dev->lock);
              mutex_init(&v4l2_dev->ioctl_lock);
              v4l2_prio_init(&v4l2_dev->prio);
              kref_init(&v4l2_dev->ref);
              get_device(dev);
              v4l2_dev->dev = dev;
              if (dev == NULL) {
                 /* If dev == NULL, then name must be filled in by the caller */
                  WARN_ON(!v4l2_dev->name[0]);
                 return 0;
           }


       /* Set name to driver name + device name if it is empty. */
       if (!v4l2_dev->name[0])
              snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
                     dev->driver->name, dev_name(dev));
       if (!dev_get_drvdata(dev))
              dev_set_drvdata(dev, v4l2_dev);
       return 0;
}
EXPORT_SYMBOL_GPL(v4l2_device_register);
/**********************************************


       else
              pcam->v4l2_dev.notify = msm_cam_v4l2_subdev_notify;

 


       /* now setup video device */
       pvdev = video_device_alloc();                  //申请一个video
       if (pvdev == NULL) {
              pr_err("%s: video_device_alloc failed\n", __func__);
              return rc;
       }


       strlcpy(pcam->media_dev.model, QCAMERA_NAME,
                     sizeof(pcam->media_dev.model));
       pcam->media_dev.dev = &client->dev;           
       rc = media_device_register(&pcam->media_dev);   //注册一个media
       pvdev->v4l2_dev = &pcam->v4l2_dev;
       pcam->v4l2_dev.mdev = &pcam->media_dev;      //注意这个v4l2_dev,包含了很多,很重要


       /* init video device's driver interface */   //接口和操作
       D("sensor name = %s, sizeof(pvdev->name)=%d\n",
              pcam->sensor_sdev->name, sizeof(pvdev->name));


       /* device info - strlcpy is safer than strncpy but
          only if architecture supports*/
       strlcpy(pvdev->name, pcam->sensor_sdev->name, sizeof(pvdev->name));


       pvdev->release   = video_device_release;
       pvdev->fops     = &g_msm_fops;
       pvdev->ioctl_ops = &g_msm_ioctl_ops;
       pvdev->minor   = -1;
       pvdev->vfl_type  = 1;


       media_entity_init(&pvdev->entity, 0, NULL, 0);
       pvdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
       pvdev->entity.group_id = QCAMERA_VNODE_GROUP_ID;


       /* register v4l2 video device to kernel as /dev/videoXX */
       D("video_register_device\n");
       rc = video_register_device(pvdev,
                                   VFL_TYPE_GRABBER,
                                   msm_camera_v4l2_nr);
       if (rc) {
              pr_err("%s: video_register_device failed\n", __func__);
              goto reg_fail;
       }
       pvdev->entity.name = video_device_node_name(pvdev);
       D("%s: video device registered as /dev/video%d\n",
              __func__, pvdev->num);


       /* connect pcam and video dev to each other */
       pcam->pvdev   = pvdev;
       video_set_drvdata(pcam->pvdev, pcam);


       /* If isp HW registeration is successful,
        * then create event queue to
        * receievent event froms HW
       */
       /* yyan: no global - each sensor will
        * create a new vidoe node! */
       /* g_pmsm_camera_v4l2_dev = pmsm_camera_v4l2_dev; */
       /* g_pmsm_camera_v4l2_dev->pvdev = pvdev; */


       return rc ;


reg_fail:
       video_device_release(pvdev);
       v4l2_device_unregister(&pcam->v4l2_dev);
       pcam->v4l2_dev.dev = NULL;
       return rc;
}


/************************************************************************************************

 

 

 

 

 

 

 

       rc = msm_setup_mctl_node(pcam);
       if (rc < 0) {
              pr_err("%s:failed to create mctl device: %d\n",
                      __func__, rc);
              goto failure;
       }


       g_server_dev.camera_info.video_dev_name
       [g_server_dev.camera_info.num_cameras]
       = video_device_node_name(pcam->pvdev);
       D("%s Connected video device %s\n", __func__,
              g_server_dev.camera_info.video_dev_name
              [g_server_dev.camera_info.num_cameras]);


       g_server_dev.camera_info.s_mount_angle
       [g_server_dev.camera_info.num_cameras]
       = sdata->sensor_platform_info->mount_angle;


       g_server_dev.camera_info.is_internal_cam
       [g_server_dev.camera_info.num_cameras]
       = sdata->camera_type;


       g_server_dev.mctl_node_info.mctl_node_name
       [g_server_dev.mctl_node_info.num_mctl_nodes]
       = video_device_node_name(pcam->mctl_node.pvdev);


       pr_info("%s mctl_node_name[%d] = %s\n", __func__,
              g_server_dev.mctl_node_info.num_mctl_nodes,
              g_server_dev.mctl_node_info.mctl_node_name
              [g_server_dev.mctl_node_info.num_mctl_nodes]);


       /*Temporary solution to store info in media device structure
         until we can expand media device structure to support more
         device info*/
       snprintf(pcam->media_dev.serial,
                     sizeof(pcam->media_dev.serial),
                     "%s-%d-%d", QCAMERA_NAME,
                     sdata->sensor_platform_info->mount_angle,
                     sdata->camera_type);


       g_server_dev.camera_info.num_cameras++;
       g_server_dev.mctl_node_info.num_mctl_nodes++;


       D("%s done, rc = %d\n", __func__, rc);
       D("%s number of sensors connected is %d\n", __func__,
              g_server_dev.camera_info.num_cameras);


       /* register the subdevice, must be done for callbacks */
       rc = msm_cam_register_subdev_node(sensor_sd, SENSOR_DEV, vnode_count);
       if (rc < 0) {
              D("%s sensor sub device register failed\n",
                     __func__);
              goto failure;
       }


       if (pcam->act_sdev) {
              rc = v4l2_device_register_subdev(&pcam->v4l2_dev,
                            pcam->act_sdev);
              if (rc < 0) {
                     D("%s actuator sub device register failed\n",
                       __func__);
                     goto failure;
              }
       }


       if (pcam->eeprom_sdev) {
              rc = v4l2_device_register_subdev(&pcam->v4l2_dev,
                     pcam->eeprom_sdev);
              if (rc < 0) {
                     D("%s eeprom sub device register failed\n", __func__);
                     goto failure;
              }
       }


       pcam->vnode_id = vnode_count++;
       return rc;


failure:
       kzfree(pcam);
       return rc;
}


EXPORT_SYMBOL(msm_sensor_register);

深入浅出,camera v4l2理解(2)v4l2注册 正式步入v4l2_i2c_subdev_init 这个是什么呢,看代码: 这个是在v4l2-common里面: void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,                 const struct v4l2_subdev_ops *ops) { 阅读详情

相关推荐

深入浅出,camera v4l2理解(1)v4l2准备使用的参数

1,probe 2,读id,id读完了并且成功才能注册v4l2   3,注册v4l2, v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,s_ctrl->sensor_v4l2_subdev_ops); 这里v4l2的注册需要几个参数 s_ctrl->sensor_v4l2_subdev 这个参数主要是v

u010641000的专栏 1842

Best Free Apps to Stream Videos from PC to Android Phone

Original: http://www.androidauthority.com/best-free-apps-to-stream-videos-from-pc-to-android-phone-46394/ by Carl Parker on Jan 26, 2012 with 6 CommentsAAA Tweet There may be to

sdafrma4的专栏 343万+

深入浅出:图解Rockchip Camera驱动框架与OV426传感器集成原理

本文深入解析Rockchip Camera驱动框架与OV426传感器集成原理,通过架构图解和数据流分析,详细介绍了硬件接口层、驱动抽象层和数据处理层的设计理念。重点探讨了OV426传感器的DVP接口配置要点和V4L2驱动模型实现,帮助开发者提升驱动调试效率与问题解决能力。

weixin_30896825的博客 152

video使用

<video class="video_box" width="100%" height="100%" webkit-playsinline="webkit-playsinline" x5-playsinline="x5-playsinline" x5-video-player-type="h5" x5-video-player-fullscreen="" playsinline="playsinline" preload="auto" poster="https://xxx/poster.png"

一只快乐的小猴子的博客 2万+

从手机拍照到Linux驱动:深入浅出图解V4L2 Camera子设备(CSI/ISP/MIPI)数据流

本文深入解析了Linux内核中V4L2框架如何管理Camera子设备(CSI/ISP/MIPI)的数据流,从手机拍照的硬件协作到驱动开发实践。通过图解和代码示例,详细介绍了V4L2的核心数据结构、子设备操作以及数据流动过程,为开发者提供Camera驱动调试的实用技巧和工具集。

weixin_42531128的博客 229

第1讲 Camera KMD ISP子系统课程介绍

课程会帮助大家理解高通camera kmd驱动,包括一些优秀的设计思想。重点讲解cpas, crm, isp, camsync, cdm, smmu等模块. 随着高通camx驱动代码更新,本课程也就持续出视频同步新的

qq_42194101的博客 1523

C++ OpenCV工业级工程实战:VS2022配置与cv::Mat内存管理

OpenCV是计算机视觉领域最广泛使用的开源图像处理库,其C++接口因高性能和可控性成为嵌入式、工控及边缘AI部署的首选。理解cv::Mat的内存视图机制与videoio后端原理,是规避空帧、LNK2019链接错误、Release崩溃等高频问题的关键。OpenCV并非即插即用的黑盒,而是一套需精确管理模块依赖(core→imgproc→videoio→highgui)、运行时库(/MD统一)、平台工具链(v143)的精密系统。在车牌识别、工业缺陷检测、实时视频分析等场景中,正确的工程架构(接口层/实现层/适

weixin_34242331的博客 347

第1讲 Camera Sensor Driver课程简介

课程主要帮助大家理解camera sensor基本概念及原理知识,理解高通camera sensor驱动框架,通过学习完本视频课程后,可以掌握高通平台上的sensor bringup以及解决部分工作中可能会遇到的sensor相关的问题。

qq_42194101的博客 1223

Building a 3D Game in XNA From Scratch - Free Video Tutorial Series Now Available!

 After far too many hours of learning, teaching, recording, testing, video editing, and other glorious activities, I am ready to make available my massive collection of video tutorials for creatin

0.5 Degree 26万+

camera驱动分析

1. 内核的 camera 控制器驱动 和 sensor 驱动是基于 v4l2 驱动架构编写的,应用程序可以使用 cimutils 进行测试   CIM 控制器驱动,基于 V4L2 架构,并采用 videobuf2。便于上层开发 drivers/media/platform/soc_camera/ingenic/x2000/ingenic_camera.c static int __in...

sinat_37817094的博客 1743

深入浅出V4L2:手把手教你写一个camera_client采集程序

V4L2(Video4Linux2)是Linux平台下标准视频采集接口,负责连接摄像头驱动与用户态应用。通过open、ioctl、mmap、poll等系统调用,开发者可完成从设备查询、格式协商到缓冲管理的完整流程。理解V4L2的采集机制,不仅是编写USB摄像头、CSI摄像头及采集卡驱动的基础,也为嵌入式多媒体开发中的性能优化提供关键支撑。在实际工程中,合理设计缓冲队列、处理设备热插拔、利用mmap零拷贝等手段,能显著提升采集稳定性。本文从V4L2核心原理出发,系统讲解camera_client项目的骨架、常

weixin_29159127的博客 249

Uninstall Ulead VideoStudio with UninstallGeek.Com Uninstall Guides

Uninstalling the full Ulead VideoStudio out of PC might always a headache for a lot of computer users when it expired or there is certainly something wrong with the current version. If you still have

DellaDavis的专栏 2万+

Xilisoft HD Video Converter5.XX KEY.txt

Xilisoft HD Video Converter5.XX KEY.txt

麒麟操作系统/Linux 摄像头采集录制

Linux系统上采集摄像头,可以使用V4L2相关接口,linux上的摄像头设备对应的文件是/dev/videoxx, 采集和控制摄像头只要调用open("/dev/videoxx", flag) 打开文件,然后对文件进行读写等控制操作即可. 最近在Linux推送SDK也增加了摄像头采集和预览功能,集成调用非常简单,几行C++代码就可以完成. class CameraInfo { public: std::string name_; std::string id_; std:...

lsheevyfg的专栏 4813

避免踩坑!杰理AC63蓝牙名修改常见问题及解决方案(含BLE后缀处理)

本文详细解析了杰理AC63蓝牙设备名称修改的全过程,包括基础操作、BLE后缀处理及高级调试技巧。针对蓝牙名修改中的常见问题,提供了实用的解决方案和代码示例,帮助开发者避免踩坑并实现高效定制。

q6r7s8t9的博客 410

信号完整性入门:为什么工程师总爱用dB来描述衰减?

本文深入探讨了信号完整性分析中工程师偏爱使用dB(分贝)单位描述衰减的原因。dB通过对数转换,将大动态范围的乘除关系简化为加减运算,极大地方便了多级系统分析和链路预算计算。文章重点解释了-3dB点的核心意义,即功率衰减一半的临界状态,并阐述了其在评估信道带宽、插入损耗与回波损耗等关键参数中的实际应用,是高效工程思维和沟通的重要工具。

weixin_29263201的博客 384

MIME类型大全

MIME类型大全  格式前面为后辍名,后面为对应的MIME型(例如:rar application/x-rar-compressed 表示.RAR对应的是application/x-rar-compressed )  application/vnd.lotus-1-2-3  3gp video/3gpp  aab application/x-authoware-bin  aam

tanwen1234的专栏 1358

【HAL库-STM】智能温控按键小风扇【胎教级教学】

硬件设备:DHT11,0.96寸oled屏,二/三/四线风扇(不挑),面包板 、f10的精英板等等。当人在的风扇面前时可以自行控制风扇,不在面前时又想开风扇就让他温控自行开启,(在这里有一个想法就是加上蓝牙和wifi控制的功能能够远程遥控,这个如果做的再全一点就要自主研发是一个多功能app,这里没有做。针对这个dht11,我一开始是卡在了这个check函数里面,一直是我给完dht11低电平和高电平后,dht11不回复我低电平和高电平,这个不是我的问题,当时代码是没毛病的,这个点一直卡着我。吐血五天实现小成品

weixin_52451652的博客 1738

android xvideo app,xvideo downloader and player

xvideo downloader and player 介绍xvideo downloader and playerWith X-Video Player app, you can maduras enjoy high quality top video files on your device. And most other video format MP4, AVI and so on....

weixin_30070663的博客 8万+

win10任务栏文件夹设置成竖形列表样式

win10任务栏文件夹设置成竖形列表样式

ftzchina的博客 7075

大数据架构中的数据血缘追踪技术解析

数据血缘(Data Lineage)是指数据从源头到目标的完整流转路径,它记录了数据在整个生命周期中的变化过程。在大数据架构中,数据血缘追踪技术已经成为数据治理的核心组成部分。本文旨在全面解析数据血缘追踪的技术原理、实现方法和应用实践,帮助读者深入理解这一关键技术。本文将从基础概念入手,逐步深入到技术实现细节,最后探讨实际应用和未来趋势。数据血缘的核心概念和技术原理数据血缘的数学模型和算法实现实际项目案例和代码解析主流工具和解决方案比较未来发展方向和技术挑战。

架构师的AI之路,分享AI应用开发架构的学习与实践。 687

android VideoView的使用例程

<br />一、 xxxvideo.java<br /> <br /><br />public class RemoteVideo extends Activity {<br />private String path = "";<br />private String textUrl = "";<br />private VideoView mVideoView;<br />private static int i = 0;<br />private int width;<br />private int

不以己悲的博客 4万+

R语言机器学习算法实战系列(十三)随机森林生存分析构建预后模型 (Random Survival Forest)

本教程运用随机森林生存分析筛选与患者生存状态显著相关特征。该方法借随机森林这一强大机器学习算法,构建多棵决策树并集成结果,以提高生存分析准确性,识别关键生物标志物。接着,利用选定特征构建风险得分,将多个特征转化为单一数值,量化患者风险水平。之后,依据风险得分将患者分为高、低风险亚型,为临床治疗提供个性化指导。最后,通过分析时间依赖的 ROC 曲线评估模型长期预测能力。此曲线计算不同阈值下的真正例率与假正例率,在多个时间点评估,全面展现模型长期稳定性与准确性。

专注生信领域 2017

100 Best Ubuntu Apps

100 Best Applications for Ubuntu 2018 Earlier this year we have published the list of 20 Best Ubuntu Applications for 2018 which can be very useful to many users. Now we are almost in the second half ...

Tedlin1122的博客 1万+

最佳RANSAC算法拟合矩形的实现(基于PCL库)

最佳RANSAC算法是一种常用的参数估计方法,用于从数据集中拟合出最佳的模型。在计算机视觉和图像处理领域,最佳RANSAC算法常用于拟合几何形状,如矩形。本文将详细介绍如何使用点云库(PCL)中的最佳RANSAC算法来拟合矩形,并提供相应的源代码。

JbPatch的博客 1540

乐企归集能力说明文档V2.0006

纳税人销售货物、提供服务开具的增值税发票及购进货物、接受服务取得的增值税发票、海关缴款书(含出口转内销证明)、代扣代缴完税凭证,可以通过本能力进行归集。纳税人可将本能力中的各类规则和接口嵌入本单位信息化系统中(如:销售、报销、财务等),实现发票自动化归集,便于纳税人完成发票入账、抵扣、退税以及代办退税等操作,有效提升涉税业务办理效率。

记录点滴 573
上一篇: Linux内核中的V4L2核心框架分析(V4L2 framework,video for linux 2,linux视频子系统) .
下一篇: Qualcomm 8X camera daemon进程浅析 .
TopicDev
博客等级 码龄14年 128粉丝 111原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值