BT.656 协议介绍

预备知识 场的概念 在视频传输协议中,“场”(field)是指构成一帧完整图像的两个半幅图像之一。在传统的隔行扫描视频系统中,一帧完整的图像由两个场组成:上场(top field)和下场(bottom field)。这种扫描方式主要用于模拟电视信号中,以减少带宽需求并提高图像质量。 场的基本概念: 隔行扫描:在隔行扫描中,屏幕上的像素不是一次性全部刷新,而是分成两个阶段来完成。首先刷新所有偶数行(上场),然后刷新所有奇数行(下场),这样就完成了一帧图像的显示。 上场与下场:上场包含所有偶数行,下场包含所有奇数行。这两个场结合在一起组成一帧完整的图像。 帧与场: 在隔行扫描中,每两场构成一帧。帧是完整的图像,而场则是帧的一半。因此,在模拟电视系统中,每秒显示的场数通常是帧数的两倍。 隔行扫描与逐行扫描的区别: 隔行扫描:每一帧图像分成两个场显示,每个场包含一半的扫描线。这种方式减少了带宽需求,但也可能导致运动图像出现闪烁或交错现象(interlacing effect)。 逐行扫描:每一帧图像的所有扫描线一次性显示完毕。这种方式可以提供更平滑的图像,但需要更大的带宽。 应用场景: 模拟电视系统:在 PAL 和 NTSC 等模拟电视标准中,使用隔行扫描技术来传输视频信号。例如,NTSC 系统的帧率为每秒 30 帧,但实际上是以每秒 60 场的速度传输。 PAL,NTSC,SECAM 三者都是模拟电视信号标准。 NTSC: 全称为 National Television Standards Committee。视频格式为一张 NTSC 的图片包含 525 个交错行(interlaced lines), 每秒 29.97 帧。 PAL: 全称为 Phase Alternate Line。视频格式为一张 PAL 图片 625 个交错行,每秒 25 帧。 SECAM: 全称为 Sequential Color and Memory。视频格式和 PAL 一样,一张 SECAM 图片 625 个交错行,每秒 25 帧。但是 SECAM 处理颜色信息的方式和 PAL 不同。...

2024-08-22 · 2 min

Framebuffer

Kconfig 配置 Capemgr 配置 linux-menuconfig: CONFIG_CAPE_REALTEK CONFIG_OF_OVERLAY CONFIG_FW_LOADER echo lcd_tianma_tm050rdh03 > sys/devices/platform/rts_capemgr/slots LCD 配置 menuconfig: CONFIG_BR2_PACKAGE_LCD 在BR2_PACKAGE_LCD_LIST即Supported lcd display list中加入 lcd 屏的名称tianma_tm050rdh03。(这里看graphic/lcd/CMakeList.txt,会寻找我们加入的屏名称,编译对应的 dts 到/lib/firmware) linux-menuconfig: CONFIG_FB_RTS

2024-08-21 · 1 min

Framebuffer Driver

概念 真彩,伪彩 真彩色:图像中的每个像素值都分成 R、G、B 三个基色分量。比如 RGB888,每种颜色各占 8bit, 最多有 256256256=16.7M 种色彩。 伪彩色:每个像素的颜色不是由每个基色分量的数值直接决定,而是把像素值当作彩色查找表(color look-up table CLUT)的入口地址,去查找对应的 RGB 值。 直接色:与伪彩色系统相比,相同之处是都采用查找表,不同之处是直接色对 R,G,B 分量分别进行变换,伪彩色是把整个像素当作查找表的索引值进行彩色变换。 Color Key color key: Colorkey 技术是作用在两个图像叠加混合的时候,对特殊色做特殊过滤,符合条件的区域叫 match 区,在 match 区就全部使用另外一个图层的颜色值。 图像数据在内存中的排列方式 主要介绍三种, 以 RGB888 数据例子: Packed Pixel: pixel 接 pixel,紧凑排列。RGB 按顺序排列。R1 G1 B1 R2 G2 B2 R3 G3 B3。 Planes: 将 pixel 不同部分分成多个 planes, 比如 RGB 格式可以分为 3 个 planes 保存,R1 R2 R3 G1 G2 G3 B1 B2 B3。 Interleaved planes: planes 之间可以交错,通过 fix 参数中的type_aux来表示两个 planes 开头的 offset。...

2024-08-21 · 3 min

DRM Subsystem 3 -- Hardware Driver

中间层 struct drm_driver 底层 driver xxx_drv.c 首先初始化一个struct drm_driver DEFINE_DRM_GEM_DMA_FOPS(fops); static const struct drm_driver mxsfb_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS, .fops = &fops, .name = "mxsfb-drm", .desc = "MXSFB Controller DRM", .date = "20160824", .major = 1, .minor = 0, }; 其中.driver_feature支持的属性有: enum drm_driver_feature { DRIVER_GEM = BIT(0), // GEM 内存管理,一般都需要选上 DRIVER_MODESET = BIT(1), // KMS, kernel mode setting DRIVER_RENDER = BIT(3), // dedicated render node DRIVER_ATOMIC = BIT(4), // 支持所有modesetting userspace API。 DRIVER_SYNCOBJ = BIT(5), // 支持&drm_syncobj,用来主动同步 DRIVER_SYNCOBJ_TIMELINE = BIT(6), DRIVER_COMPUTE_ACCEL = BIT(7), // 支持compute acceleration。和DRIVER_RENDER,DRIVER_MODESET选项互斥,如果同时支持modeset和compute_accel那么就需要实现两个driver。 DRIVER_GEM_GPUVA = BIT(8), // 支持user定义的GPU VA bindings for GEM objects DRIVER_CURSOR_HOTSPOT = BIT(9), // 支持cursor hotspot information // 下面这些都是legacy driver的属性 DRIVER_USE_AGP = BIT(25), // AGP support, 不清楚作用,已不使用 DRIVER_LEGACY = BIT(26), // 使用shadow attach的legacy driver,已淘汰 DRIVER_PCI_DMA = BIT(27), // Legacy PCI DMA supprot, 已不使用 DRIVER_SG = BIT(28), // Legacy scatter/gather DMA support, 已不使用 DRIVER_HAVE_DMA = BIT(29), // Legacy DMA support, 已不使用 DRIVER_HAVE_IRQ = BIT(30), // Legacy irq support, 已不使用 }; 在 driver probe 函数中调用devm_drm_dev_alloc()函数分配struct drm_device空间,drm_dev_alloc()中又会调用drm_dev_init()来进行一系列初始化struct drm_device。...

2024-08-20 · 2 min

DRM Subsystem 2 -- Userspace Application

参考 https://github.com/dvdhrm/docs/tree/master/drm-howto 中的 modeset-atomic.c Modeset prepare 首先 open drm 设备节点: fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC); 设置 client 的 capability: drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1); 第一行设置 drm file_priv->universal_planes=1。 第二行设置 file_priv->atomic=1, file_priv->universal_planes=1, file_priv->aspect_ratio_allowed = 1。 获取 client 的 capability: drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &cap); drmGetCap(fd, DRM_CAP_CRTC_IN_VBLANK_EVENT, &cap); 第一行,如果 drm_driver 提供了 dumb_create 回调,则返回 1,一般都会提供。 第二行,必定返回 1,现在 driver 都会支持 Vblank 事件。 获取 resources: drmModeGetResources(); drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res); 得到 fbs/crtcs/connectors/encoders 的数量,以及每个对应的 id,还有显示支持的最大最小长宽,填充结构体: typedef struct _drmModeRes { int count_fbs; uint32_t *fbs; int count_crtcs; uint32_t *crtcs; int count_connectors; uint32_t *connectors; int count_encoders; uint32_t *encoders; uint32_t min_width, max_width; uint32_t min_height, max_height; } drmModeRes, *drmModeResPtr; 获取 connector:...

2024-08-20 · 2 min

DRM Subsystem 1 -- Graphic Introduction

Reference https://docs.kernel.org/gpu/index.html introduction 中提供了一些关于 DRM 的讲座和 slides 材料。 https://bootlin.com/doc/training/graphics/graphics-slides.pdf Basic Theory and Concepts About Graphics YUV 数据格式 采样 YUV 格式,由一个 Y 的亮度分量(Luma)和 U(蓝色投影 Cb)和 V(红色投影 Cr)的色度分量(Chroma)表示。 4:4:4 表示不降低色度(UV)通道的采样率。每个 Y 分量对应一组 UV 分量。 4:2:2 表示 2:1 水平下采样,没有垂直下采样。每两个 Y 分量共享一组 UV 分量。 4:2:0 表示 2:1 水平下采样,同时 2:1 垂直下采样。每四个 Y 分量共享一组 UV 分量。 4:1:1 表示 4:1 水平下采样,没有垂直下采样。每四个 Y 分量共享一组 UV 分量。 BT.601 中规定的 YUV 和 RGB 的转换公式: \(R=Y+1.140*V-0.7\) \(G=Y-0.343*U-0.711*V+0.526\) \(B=Y+1.765*U-0.883\) \(Y=0.299*R+0.587*G+0.114*B\) \(U=-0.169*R-0.331*G+0.500*B\) \(V=0.500*R-0.439*G-0.081\*B\)...

2024-08-20 · 1 min

MIPI DPI 协议介绍

Reference MIPI Alliance Standard for Display Pixel Interface (DPI-2) Overview MIPI DPI(Display Pixel Interface)协议。分辨率最大支持到 800*480。 Parallel RGB 屏遵从的就是 MIPI DPI 协议。 4 Display Architectures and Interface Constructions 显示设备一般有 4 种结构: Type1: includes a display device, display driver IC, full-frame memory, registers, timing controller, non-volatile memory and control interface. Type2: includes a display device, display driver IC, partial-frame memory, registers, timing controller, non-volatile memory, control interface and video stream interface. Type3: includes a display device, display driver IC, partial-frame memory, registers, timing controller, non-volatile memory, control interface and video stream interface...

2024-08-19 · 2 min

Cmake笔记

最简单的,只有一个源文件的 CMakeList.txt: cmake_minimum_required (VERSION 2.8) project (learn_cmake) add_executable(hello hello.cpp) $ mkdir build $ cd build/ $ cmake .. $ make 定义变量 set(SRC_LIST 1.c 2.c 3.c) add_executable(app ${SRC_LIST}) 通过EXECUTABLE_PUTPUT_PATH可以指定输出路径: set(HOME /home/xyc) set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin) 搜索文件 方式 1:aux_source_directory 方式 2:file file(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型) file(GLOB app_sources src/*.c) target_sources(app PRIVATE ${app_sources}) GLOB: 将指定目录下搜索到的满足条件的所有文件名生成一个列表,并将其存储到变量中。 GLOB_RECURSE:递归搜索指定目录,将搜索到的满足条件的文件名生成一个列表,并将其存储到变量中。 包含头文件 include_directories(path) 动态库/静态库 制作静态库 add_library(库名称 STATIC 源文件1 [源文件2] ...) # 指定静态库输出路径 set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) 制作动态库 add_library(库名称 SHARED 源文件1 [源文件2] ...) # 指定动态库输出路径 set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) # 动态库默认是有执行权限的,可以通过这种方式。 链接静态库 # 指明库路径 link_directories(${PROJECT_SOURCE_DIR}/lib) # 链接库 link_libraries(calc) # 可以是全名libxxx....

2024-08-12 · 1 min

CSAPP - Chapter7 链接

7.2 静态链接 为了构造可执行文件,链接器必须完成两个主要任务: 符号解析。将每个符号引用和一个符号定义连接起来。 重定位。编译器和汇编器生成从 0 地址开始的代码和数据节。连接器通过把每个符号定义与一个内存位置关联起来,从而重定位这些节。然后修改所有对这些符号的引用,使得他们指向这个内存位置。 7.3 目标文件 可重定位目标文件 .o, .a(.a 就是一堆打包的.o) 可执行目标文件 elf 共享目标文件 .so 7.4 可重定位目标文件 .text 代码段 .rodata 只读数据段,保存字符串,const 数据等。 .data 数据段。全局和静态变量。 .bss 未初始化和初始化为 0 的全局和静态变量。不占空间。 .symtab 符号表,存放程序中定义和引用的函数和全局变量信息。 .rel.text .text 节中需要重定位的代码段。 .rel.data .data 节中需要重定位的数据段,被模块引用或定义的所有全局变量。 .debug 调试符号表。包含程序中定义的局部变量和类型定义,定义和引用的全局变量,原始的 C 源文件。 .line 原始 C 文件中的行号和.text 节中机器指令的映射。 .strtab 字符串表。 7.5 符号和符号表 由当前模块定义并能被其他模块引用的全局符号 其他模块定义并被当前模块引用的全局符号,称为外部符号 只被当前模块定义和引用的的局部符号 下面两个局部静态变量: int f() { static int x = 1; return x; } int g() { static int x = 2; return x; } 两个 x 分别在各自的函数中可见,这两个 x 都会保存到....

2024-08-07 · 5 min

CSAPP - Cache Lab

实验说明 在 cache lab 实验中,包含两个部分: 第一部分要求我们写一个 C program 来模拟 cache memory。 第二部分要求我们通过减少 cache miss 来优化一个矩阵转置函数。 对应的文件分别为csim.c, trans.c 可通过make和make clean来编译和删除编译文件。 PartA Writing a Cache Simulator 准备工作 我们利用valgrind生成的 trace files 作为我们 cache simulator 的 input。 格式为[space]operation address, size: I 0400d7d4,8 M 0421c7f0,4 L 04f6b868,8 S 7ff0005c8,8 I 加载指令 L 加载数据 S 存储数据 M 内存数据修改(先加载数据,再存储数据) I 前面不跟空格,L/S/M 前面需要加一个空格。 csim-ref是一个参考的 cache simulator 实现。使用LRU替换算法。 用法: Usage: ./csim-ref [-hv] -s <s> -E <E> -b <b> -t <tracefile>...

2024-08-05 · 3 min