一文带你了解V4L2

1、什么是v4l2

V4L2(Video4Linux的缩写)是Linux下关于视频采集相关设备的驱动框架,为驱动和应用程序提供了一套统一的接口规范。

V4L2支持的设备十分广泛,但是其中只有很少一部分在本质上是真正的视频设备:

•Video capture device :从摄像头等设备上获取视频数据。对很多人来讲,video capture是V4L2的基本应用。设备名称为/dev/video,主设备号81,子设备号0~63•Video output device :将视频数据编码为模拟信号输出。与video capture设备名相同。•Video overlay device :将同步锁相视频数据(如TV)转换为VGA信号,或者将抓取的视频数据直接存放到视频卡的显存中。•Video output overlay device :也被称为OSD(On-Screen Display)•VBI device :提供对VBI(Vertical Blanking Interval)数据的控制,发送VBI数据或抓取VBI数据。设备名/dev/vbi0~vbi31,主设备号81,子设备号224~255•Radio device :FM/AM发送和接收设备。设备名 /dev/radio0~radio63,主设备号81,子设备号64~127

V4L2在Linux系统中的结构图如下:

2、从应用层看V4L2

从V4L2简单框图可以看出,V4L2是一个字符设备,而V4L2的大部分功能都是通过设备文件的ioctl导出的。

可以将这些ioctl分类如下:

•Query Capability:查询设备支持的功能,只有VIDIOC_QUERY_CAP一个。•优先级相关:包括VIDIOC_G_PRIORITY,VIDIOC_S_PRIORITY,设置优先级。•capture相关:视频捕获相关Ioctl。

capture ioctl list ID 描述

VIDIOC_ENUM_FMT    枚举设备所支持的所有数据格式
VIDIOC_S_FMT    设置数据格式
VIDIOC_G_FMT    获取数据格式
VIDIOC_TRY_FMT    与VIDIOC_S_FMT一样,但不会改变设备的状态
VIDIOC_REQBUFS    向设备请求视频缓冲区,即初始化视频缓冲区
VIDIOC_QUERYBUF    查询缓冲区的状态
VIDIOC_QBUF    从设备获取一帧视频数据
VIDIOC_DQBUF    将视频缓冲区归回给设备,
VIDIOC_OVERLAY    开始或者停止overlay
VIDIOC_G_FBUF    获取video overlay设备或OSD设备的framebuffer参数
VIDIOC_S_FBUF    设置framebuffer参数
VIDIOC_STREAMON    开始流I/O操作,capture or output device
VIDIOC_STREAMOFF    关闭流I/O操作

•TV视频标准:

TV Standard ID 描述 VIDIOC_ENUMSTD 枚举设备支持的所有标准 VIDIOC_G_STD 获取当前正在使用的标准 VIDIOC_S_STD 设置视频标准 VIDIOC_QUERYSTD 有的设备支持自动侦测输入源的视频标准,此时使用此ioctl查询侦测到的视频标准

•input/output:

Input / Output ID 描述

VIDIOC_ENUMINPUT    枚举所有input端口
VIDIOC_G_INPUT    获取当前正在使用的input端口
VIDIOC_S_INPUT    设置将要使用的input端口
VIDIOC_ENUMOUTPUT    枚举所有output端口
VIDIOC_G_OUTPUT    获取当前正在使用的output端口
VIDIOC_S_OUTPUT    设置将要使用的output端口
VIDIOC_ENUMAUDIO    枚举所有audio input端口
VIDIOC_G_AUDIO    获取当前正在使用的audio input端口
VIDIOC_S_AUDIO    设置将要使用的audio input端口
VIDIOC_ENUMAUDOUT    枚举所有audio output端口
VIDIOC_G_AUDOUT    获取当前正在使用的audio output端口
VIDIOC_S_AUDOUT    设置将要使用的audio output端口

•controls:设备特定的控制,例如设置对比度,亮度•controls ID 描述*

VIDIOC_QUERYCTRL    查询指定control的详细信息
VIDIOC_G_CTRL    获取指定control的值
VIDIOC_S_CTRL    设置指定control的值
VIDIOC_G_EXT_CTRLS    获取多个control的值
VIDIOC_S_EXT_CTRLS    设置多个control的值
VIDIOC_TRY_EXT_CTRLS    与VIDIOC_S_EXT_CTRLS相同,但是不改变设备状态
VIDIOC_QUERYMENU    查询menu

•其他杂项:•controls ID 描述*

VIDIOC_G_MODULATOR     
VIDIOC_S_MODULATOR     
VIDIOC_G_CROP     
VIDIOC_S_CROP     
VIDIOC_G_SELECTION     
VIDIOC_S_SELECTION     
VIDIOC_CROPCAP     
VIDIOC_G_ENC_INDEX     
VIDIOC_ENCODER_CMD     
VIDIOC_TRY_ENCODER_CMD     
VIDIOC_DECODER_CMD     
VIDIOC_TRY_DECODER_CMD     
VIDIOC_G_PARM     
VIDIOC_S_PARM     
VIDIOC_G_TUNER     
VIDIOC_S_TUNER     
VIDIOC_G_FREQUENCY     
VIDIOC_S_FREQUENCY     
VIDIOC_G_SLICED_VBI_CAP     
VIDIOC_LOG_STATUS     
VIDIOC_DBG_G_CHIP_IDENT     
VIDIOC_S_HW_FREQ_SEEK     
VIDIOC_ENUM_FRAMESIZES     
VIDIOC_ENUM_FRAMEINTERVALS     
VIDIOC_ENUM_DV_PRESETS     
VIDIOC_S_DV_PRESET     
VIDIOC_G_DV_PRESET     
VIDIOC_QUERY_DV_PRESET     
VIDIOC_S_DV_TIMINGS     
VIDIOC_G_DV_TIMINGS     
VIDIOC_DQEVENT     
VIDIOC_SUBSCRIBE_EVENT     
VIDIOC_UNSUBSCRIBE_EVENT     
VIDIOC_CREATE_BUFS     
VIDIOC_PREPARE_BUF

v4l2设备的基本操作流程如下

1、打开设备,例如 fd = open("/dev/video0",0)

2、查询设备能力. 例如:

struct capability cap;
ioctl(fd,VIDIOC_QUERYCAP,&cap)
3、设置优先级(可选)

4、配置设备。

包括:

•视频输入源的视频标准,VIDIOC_*_STD•视频数据的格式 , VIDIOC_*_FMT•视频输入端口, VIDIOC_*_INPUT•视频输出端口,VIDIOC_*_OUTPUT

5、启动设备开始I/O操作。V4L2支持一下三种I/O方式:

•Read/Write:通过调用设备节点文件的Read/Write函数,与设备交互数据。打开设备后,默认使用的是此方法。•Stream I/O:流操作,只传递数据缓冲区指针,不拷贝数据。使用此方法,需要调用VIDIOC_REQBUFS ioctl来通知设备。流操作I/O有两种方式memory map和user buffer。(具体区别后面章节介绍)•overlay :也可以理解为memory to memory 传输。将数据从内存拷贝到显存中。overlay设备独有的。

对于Capture device可以以如下方式启动设备:

•调用VIDIOC_REQBUFS ioctl来分配缓冲区队列;•调用VIDIOC_STREAMON ioctl通知设备开始stream IO•调用VIDIOC_QBUF ioctl从设备获取一帧视频数据;•使用完数据后,调用VIDIOC_DQBUF将缓冲区还给设备,以便设备填充下一帧数据。

6、释放资源并关闭设备。

1.3、从驱动层看V4L2

在驱动层,V4L2为驱动编写者做了很多工作。只需要实现硬件相关的代码,并且注册相关设备即可。

硬件相关代码的编写,除了编写具体硬件的控制代码外,最主要的就是将代码与V4L2框架绑定。绑定主要分为以下两个部分:

•关系绑定:也就是要将我们自己的结构体,与V4L2框架中相关连的结构体绑定在一起。•iocontrol等函数绑定:将V4L2所定义的空的函数指针,与自己的函数绑定在一起。

3.1 关系绑定

提到关系绑定,就必须介绍下V4L2几个重要结构体。

•struct video_device:主要的任务就是负责向内核注册字符设备•struct v4l2_device:一个硬件设备可能包含多个子设备,比如一个电视卡除了有capture设备,可能还有VBI设备或者FM tunner。而v4l2_device就是所有这些设备的根节点,负责管理所有的子设备。•struct v4l2_subdev:子设备,负责实现具体的功能。

v4l2_device,v4l2_subdev可以看作所有设备和子设备的基类。我们在编写自己的驱动时,往往需要继承这些设备基类,添加一些自己的数据成员。例如第三章要讲到的soc_camera_host结构体,就是继承v4l2_device,并添加了互斥锁、子设备列表等成员变量。

绑定的基本流程

根据需要”重载”v4l2_device或v4l2_subdev结构体,添加需要的结构体成员。例如 :

•linux/include/media/soc_camera.h文件中soc_camera_host重载了v4l2_device:

struct soc_camera_host {
struct v4l2_device v4l2_dev;
struct list_head list;
struct mutex host_lock;         /* Protect during probing */
unsigned char nr;               /* Host number */
void *priv;
const char *drv_name;
struct soc_camera_host_ops *ops;
};

•linux/drivers/media/video/Ml86v7667.c中ml86v7667_priv结构体”重载”了v4l2_subdev:

struct ml86v7667_priv {struct v4l2_subdev                sd;struct v4l2_ctrl_handler  hdl;v4l2_std_id                       std;
};
v4l2_device与V4L2框架的绑定:通过调用v4l2_device_register函数实现。例如,上面提到的soc_camera_host的绑定:
int soc_camera_host_register(struct soc_camera_host *ici)
{struct soc_camera_host *ix;int ret;if (!ici || !ici->ops ||!ici->ops->try_fmt ||!ici->ops->set_fmt ||!ici->ops->set_bus_param ||!ici->ops->querycap ||((!ici->ops->init_videobuf ||!ici->ops->reqbufs) &&!ici->ops->init_videobuf2) ||!ici->ops->add ||!ici->ops->remove ||!ici->ops->poll ||!ici->v4l2_dev.dev)return -EINVAL;if (!ici->ops->set_crop)ici->ops->set_crop = default_s_crop;if (!ici->ops->get_crop)ici->ops->get_crop = default_g_crop;if (!ici->ops->cropcap)ici->ops->cropcap = default_cropcap;if (!ici->ops->set_parm)ici->ops->set_parm = default_s_parm;if (!ici->ops->get_parm)ici->ops->get_parm = default_g_parm;if (!ici->ops->enum_fsizes)ici->ops->enum_fsizes = default_enum_fsizes;mutex_lock(&list_lock);list_for_each_entry(ix, &hosts, list) {if (ix->nr == ici->nr) {ret = -EBUSY;goto edevreg;}}ret = v4l2_device_register(ici->v4l2_dev.dev, &ici->v4l2_dev);if (ret < 0)goto edevreg;list_add_tail(&ici->list, &hosts);mutex_unlock(&list_lock);mutex_init(&ici->host_lock);scan_add_host(ici);return 0;edevreg:mutex_unlock(&list_lock);return ret;}

v4l2_subdev与v4l2_device的绑定:通过v4l2_device_register_subdev函数,将subdev注册到根节点上。例如:

static int soc_camera_platform_probe(struct platform_device *pdev)
{struct soc_camera_host *ici;struct soc_camera_platform_priv *priv;struct soc_camera_platform_info *p = pdev->dev.platform_data;struct soc_camera_device *icd;int ret;if (!p)return -EINVAL;if (!p->icd) {dev_err(&pdev->dev,"Platform has not set soc_camera_device pointer!\n");return -EINVAL;}priv = kzalloc(sizeof(*priv), GFP_KERNEL);if (!priv)return -ENOMEM;icd = p->icd;/* soc-camera convention: control's drvdata points to the subdev */platform_set_drvdata(pdev, &priv->subdev);/* Set the control device reference */icd->control = &pdev->dev;ici = to_soc_camera_host(icd->parent);v4l2_subdev_init(&priv->subdev, &platform_subdev_ops);v4l2_set_subdevdata(&priv->subdev, p);strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE);ret = v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev);if (ret)goto evdrs;return ret;evdrs:platform_set_drvdata(pdev, NULL);kfree(priv);return ret;
}

video_device与v4l2_device的绑定:将v4l2_device的地址赋值给video_device的v4l2_dev即可。

3.2 函数绑定

在v4l2 framework 简略版图中,绿色的方框都是需要我们绑定并实现的。

其中v4l2_file_operations和v4l2_ioctl_ops是必须实现的。而v4l2_subdev_ops下的八类ops中,v4l2_subdev_core_ops是必须实现的,其余需要根据设备类型选择实现的。比如video capture类设备需要实现v4l2_subdev_core_ops, v4l2_subdev_video_ops。

•v4l2_file_operations:实现文件类操作,比如open,close,read,write,mmap等。但是ioctl是不需要实现的,一般都是用video_ioctl2代替。例如linux/drivers/media/video/soc_camera.c文件中soc_camera_fops的实现:

static struct v4l2_file_operations soc_camera_fops = {.owner          = THIS_MODULE,.open           = soc_camera_open,.release        = soc_camera_close,.unlocked_ioctl = video_ioctl2,.read           = soc_camera_read,.mmap           = soc_camera_mmap,.poll           = soc_camera_poll,
};

•v4l2_ioctl_ops:V4L2导出给应用层使用的所有ioctl都是在这个地方实现的。但不必全部实现,只实现自己相关的ioctl即可。例如linux/drivers/media/video/soc_camera.c中soc_camera_ioctl_ops的实现:

static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {.vidioc_querycap         = soc_camera_querycap,.vidioc_try_fmt_vid_cap  = soc_camera_try_fmt_vid_cap,.vidioc_g_fmt_vid_cap    = soc_camera_g_fmt_vid_cap,.vidioc_s_fmt_vid_cap    = soc_camera_s_fmt_vid_cap,.vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,.vidioc_enum_input       = soc_camera_enum_input,.vidioc_g_input          = soc_camera_g_input,.vidioc_s_input          = soc_camera_s_input,.vidioc_s_std            = soc_camera_s_std,.vidioc_g_std            = soc_camera_g_std,.vidioc_enum_framesizes  = soc_camera_enum_fsizes,.vidioc_reqbufs          = soc_camera_reqbufs,.vidioc_querybuf         = soc_camera_querybuf,.vidioc_qbuf             = soc_camera_qbuf,.vidioc_dqbuf            = soc_camera_dqbuf,.vidioc_create_bufs      = soc_camera_create_bufs,.vidioc_prepare_buf      = soc_camera_prepare_buf,.vidioc_streamon         = soc_camera_streamon,.vidioc_streamoff        = soc_camera_streamoff,.vidioc_cropcap          = soc_camera_cropcap,.vidioc_g_crop           = soc_camera_g_crop,.vidioc_s_crop           = soc_camera_s_crop,.vidioc_g_parm           = soc_camera_g_parm,.vidioc_s_parm           = soc_camera_s_parm,.vidioc_g_chip_ident     = soc_camera_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG.vidioc_g_register       = soc_camera_g_register,.vidioc_s_register       = soc_camera_s_register,
#endif
};

•v4l2_subdev_ops:v4l2_subdev有可能需要实现的ops的总合。分为8类,core,audio,video,vbi,tuner......等。例如, linuxdriversmediavideosoc_camera_platform.c中platform_subdev_ops的实现

static struct v4l2_subdev_video_ops platform_subdev_video_ops = {.s_stream       = soc_camera_platform_s_stream,.enum_mbus_fmt  = soc_camera_platform_enum_fmt,.cropcap        = soc_camera_platform_cropcap,.g_crop         = soc_camera_platform_g_crop,.try_mbus_fmt   = soc_camera_platform_fill_fmt,.g_mbus_fmt     = soc_camera_platform_fill_fmt,.s_mbus_fmt     = soc_camera_platform_fill_fmt,.g_mbus_config  = soc_camera_platform_g_mbus_config,
};static struct v4l2_subdev_ops platform_subdev_ops = {.core   = &platform_subdev_core_ops,.video  = &platform_subdev_video_ops,
};

函数绑定只是将驱动所实现的函数赋值给相关的变量即可。


扫码或长按关注

回复「 加群 」进入技术群聊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/468119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

笨方法学python(本文为阅读时从此书摘录的笔记) 第五天

26. 27. and 与or 或not 非 28. 29. 30. if的下一行语句必须有缩进( 四个空格) if ... : elif ...: else: 转载于:https://www.cnblogs.com/iamjuruo/p/7470921.html

流水灯c语言实验报告心得,嵌入式流水灯实验心得体会.docx

嵌入式流水灯实验心得体会嵌入式流水灯实验心得体会篇一&#xff1a;嵌入式流水灯实验   实验三 GPIO输出控制实验   一、 实验目的   熟悉LPCXX系列ARM7微控制器的GPIO输入控制。   二、实验设备   ? 硬件&#xff1a;PC机 一台   LPC2131教学实验开发平台 一套 …

Linux 僵尸进程可以被杀死吗?

在 Unix 进程模型中&#xff0c;父进程和其所产生的子进程是异步运行的&#xff0c;所以如果子进程在结束后&#xff0c;会留下一些信息需要父进程使用 wait / waitpid 来接收。而如果父进程太忙了&#xff0c;没有调用 wait / waitpid 的话&#xff0c;子进程就会变成…

jstl 获取 javascript 定义的变量_前端开发大牛完整总结出了JavaScript 难点 +最新web前端开发教程...

1. 立即执行函数立即执行函数&#xff0c;即Immediately Invoked Function Expression (IIFE)&#xff0c;正如它的名字&#xff0c;就是创建函数的同时立即执行。它没有绑定任何事件&#xff0c;也无需等待任何异步操作&#xff1a;立即执行函数function(){…}是一个匿名函数&…

MySQL 5.6.20-enterprise-commercial的参数文件位置问题

今天在折腾MySQL的参数文件时&#xff0c;突然发现MySQL 5.6.20-enterprise-commercial-advanced-log这个版本数据库的参数文件my.cnf的位置有点奇怪&#xff0c;如下所示&#xff1a; [rootDB-Server ~]# mysql --help | grep my.cnforder of preference, my.cnf, $MYSQL_TCP_…

最害怕的是,不知道想要什么

生活在现在的时代&#xff0c;你要是出去吹牛说你与世无争&#xff0c;你看破红尘&#xff0c;你就想开心上班啥也不图&#xff0c;别人要不以为你是一个傻子&#xff0c;要不就以为你是一个家财万贯的主&#xff0c;特别是现在&#xff0c;从2015年开始&#xff0c;房价像吃了…

c语言gcc汇编文件,[汇编]gcc生成汇编.s文件 $ gcc -Og -S sum.c /$ gcc -Og -S -masm=intel sum.c 与 反汇编 objdump...

目录- C语言源码文件&#xff1a;sum.c- gcc 生成的汇编语言文件 sum.sx86-64 AT&T 语法格式x86-64 Intel格式- 反汇编 objdump3.1 输出 AT&T格式 objdump -d sum3.2 输出 Intel格式 objdump -M intel -d sumC语言源码文件&#xff1a;sum.c加法&#xff1a;c a b#in…

diff算法_详解 React 16 的 Diff 策略

这是我 Deep In React 系列的第二篇文章&#xff0c;如果还没有读过的强烈建议你先读前一篇&#xff1a;详谈 React Fiber 架构(1)。前言我相信在看这篇文章的读者一般都已经了解过 React 16 以前的 Diff 算法了&#xff0c;这个算法也算是 React 跨时代或者说最有影响力的一点…

BotVS开发基础—2.1 账户、行情、K线、深度

代码 import json def main():Log("账号信息&#xff1a;", exchange.GetAccount()); #Log("K 线数据&#xff1a;", exchange.GetRecords()); # 获取K线数据&#xff0c;已成交的记录Log("行情数据&#xff1a;", exchange.GetTicker()); # 返…

实力剖析一个经典笔试题

昨天群里有个同学发了这样一个题目过来&#xff0c;这个题目应该是嵌入式笔试经典题目了&#xff0c;如果是校招的话&#xff0c;笔试不考这个题目&#xff0c;都觉得有点说不过去。#include <stdio.h>int main() {int a[5] {1,2,3,4,5};int *ptr1 (int *)(&a 1);i…

c语言计算多个整数加减,求用C编个大数加减法运算程序

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼只写过加法的&#xff0c;杭电的A B Problem (II)(AC)&#xff1a;#include #include #include #define N 3000int main(void){int n, i, j, k, p, q, a, b, t, up;char s[N];scanf("%d ", &n);for (i 0; i < n…

点击开启此虚拟机时,出现“该虚拟机似乎正在使用中”问题

VMware是常用的虚拟机工具&#xff0c;受到广大群众的喜爱&#xff0c;有用户在意外断电或非正常关机&#xff08;直接关掉进程&#xff09;出现VMware虚拟机无法启动的情况&#xff0c;接下来让我们看看如何解决这一问题。 1.点击我的计算机的windows 10*64后弹出对话框&#…

get请求可以传body吗_都9102年了,GET和POST的区别掌握了没有?

1 前言最近看了一些同学的面经&#xff0c;发现无论什么技术岗位&#xff0c;还是会问到 get 和 post 的区别&#xff0c;而搜索出来的答案并不能让我们装得一手好逼&#xff0c;那就让我们从 HTTP 报文的角度来撸一波&#xff0c;从而搞明白他们的区别。2 标准答案在开撸之前吗…

玩转 Rockchip 的开发板,这些信息你要知道

RK 的处理器Rockchip 在江湖中简称 RK&#xff0c;是一家总部坐落于福建福州的 SOC 设计公司。RK 基于 Arm cortex-A 内核设计的一系列 SOC &#xff0c;宛如苍穹中一颗颗明星&#xff0c;在国内外的产业界和极客手中闪闪发光&#xff0c;其受欢迎程度超过了很多人的想象。登录…

android sdk 封装html5,Android平台以WebView方式集成HTML5+SDK方法

HTML5 SDK 可以按照“独立应用”和“单页面”两种种方式进行集成&#xff0c;两种集成方式各有优点。独立应用集成方式&#xff1a;即Widget集成方式&#xff0c;开发者在集成后可在需要时启动HTML5 SDK&#xff0c;显示指定目录下的5 WebAPP单页面集成方式&#xff1a;即Webvi…

htmlcss实例小项目_小程序websocket心跳库——websocket-heartbeat-miniprogram

前言在16年的时候因为项目接触到websocket&#xff0c;而后对心跳重连做了一次总结&#xff0c;写了篇博客&#xff0c;而后18年对之前github上的demo代码进行了再次开发和开源&#xff0c;最终封装成库。如下&#xff1a;博客&#xff1a;https://www.cnblogs.com/1wen/p/5808…

C# 索引器简介

索引器是一种特殊的类成员&#xff0c;它能够让对象以类似数组的方式来存取&#xff0c;是程序看起来更为直观&#xff0c;更容易编写。 1、索引器的定义 C#中的类成员可以是任意类型&#xff0c;包括数组和集合。当一个类包含了数组和集合成员时&#xff0c;索引器将大大简化对…

C语言,画吃豆人剖析

接上一篇文章&#xff0c;很多人还是搞不清楚ptr1[-1]是怎么回事&#xff0c;可以看看这篇文章&#xff0c;看完的同学还是多转发的&#xff0c;让更多的人看到。一道90%都会做错的指针题偶然的一次机会在知乎上看到这个代码&#xff0c;里面涉及的C语言点我觉得很酷&#xff0…

android 教学白板功能,Android集成互动白板

Android集成互动白板注意&#xff1a;SDK版本3.6.5之后开始支持白板功能.使用白板功能首先需要登录环信&#xff0c;登录成功之后才可以去调用api创建白板房间&#xff0c;创建成功之后会直接加入房间&#xff0c;不需要再去调用加入的api。其他人可以通过房间名称或者通过创建…

mit数据集_DriveSeg:动态驾驶场景分割数据集

【导读】麻省理工学院和丰田发布DriveSeg数据集以加速自动驾驶研究&#xff0c;DriveSeg包含许多常见道路对象的精确像素级表示&#xff0c;并通过连续视频驾驶场景的镜头。我们如何训练自动驾驶模型&#xff0c;以加深对周围世界的认识&#xff1f;计算机能否从过去的经验中学…