首页
技术博客
PHP教程
数据库技术
前端开发
HTML5
Nginx
php论坛
新用户注册
|
会员登录
PHP教程
技术博客
编程问答
PNG素材
编程语言
前端技术
Android
PHP教程
HTML5教程
数据库
Linux技术
Nginx技术
PHP安全
WebSerer
职场攻略
JavaScript
开放平台
业界资讯
大话程序猿
登录
极速注册
取消
热门标签 | HotTags
copy
golang
bitmap
instance
subset
byte
int
php8
hook
search
heap
perl
import
timestamp
hash
node.js
python3
frameworks
cmd
random
export
yaml
typescript
expression
join
c语言
vbscript
less
tags
buffer
list
javascript
cookie
js
foreach
emoji
sum
char
rsa
header
match
cpython
const
audio
python2
actionscrip
hashtable
regex
triggers
php
default
format
web3
jsp
timezone
function
install
window
md5
future
select
require
range
split
uri
web
loops
shell
bytecode
email
include
testing
eval
flutter
solr
iostream
substring
object
metadata
当前位置:
开发笔记
>
编程语言
> 正文
格式
作者:mySi2502876237 | 来源:互联网 | 2023-06-17 16:45
版本 v1.0,存在内存问题 在 void v4l2_process_image(struct buffer buf)中对 v4l2 采集来的一帧进行处理,存在 struct buffer bu f
版本 v1.0,存在内存问题
在 void v4l2_process_image(struct buffer buf)中对 v4l2 采集来的一帧进行处理,存在 struct buffer bu
f 中
buffer 结构定义为:
struct buffer {
void * start;
size_t length;
};
buffer.start 为 YUV422 格式数据的起始地址。
有关 YUV 格式:
YUV 格式通常有两大类:打包(packed)格式和平面(planar)格式。前者将 YUV 分量存放在同一个数组中,
通常是几个相邻的像素组成一个宏像素(macro-pixel);而后者使用三个数组分开存放 YUV 三个分量,就像
是一个三维平面一样。
对于 YUV422(YUV2,V4L2_PIX_FMT_YUYV)格式,属于打包格式,存储顺序为:
Byte Order. Each cell is one byte.
start + 0: Y'00 Cb00 Y'01 Cr00 Y'02 Cb01 Y'03 Cr01
start + 8: Y'10 Cb10 Y'11 Cr10 Y'12 Cb11 Y'13 Cr11
start + 16: Y'20 Cb20 Y'21 Cr20 Y'22 Cb21 Y'23 Cr21
start + 24: Y'30 Cb30 Y'31 Cr30 Y'32 Cb31 Y'33 Cr31
参见: http://www.linuxtv.org/downloads/v4l-dvb-apis/re09.html#id2765148 (2010.7.12)
对于 YUV420(YUV2,V4L2_PIX_FMT_YVU420)格式,属于平面格式,存储顺序为:
Byte Order. Each cell is one byte.
start + 0: Y'00 Y'01 Y'02 Y'03
start + 4: Y'10 Y'11 Y'12 Y'13
start + 8: Y'20 Y'21 Y'22 Y'23
start + 12: Y'30 Y'31 Y'32 Y'33
start + 16: Cr00 Cr01
start + 18: Cr10 Cr11
start + 20: Cb00 Cb01
start + 22: Cb10 Cb11
参见: http://www.linuxtv.org/downloads/v4l-dvb-apis/re14.html#id2770792 (2010.7.12)
v4l2 抓取的帧为 YUV422,但 ffmpeg 中 mpeg4 编码的输入帧格式为 YUV420,在 ffmpeg 编码中输入的帧结构
为 AVFrame ,其数据结构中有关帧数据的部分为:
{
uint8_t *data[4];
int linesize[4]; // number of bytes per line
其它信息(是否是 key_frame,已编码图像书 coded_picture_number、
是否作为参考帧 reference、宏块类型 *mb_type 等等,目前未用到);
}
另外要提到的一种数据结构 AVPicture :
typedef struct AVPicture {
uint8_t *data[4];
int linesize[4]; //number of bytes per line
} AVPicture;
AVPicture 的存在有以下原因,AVPicture 将 Picture 的概念从 Frame 中提取出来,就只
由 Picture(图片)本身的信息,亮度、色度和行大小。而 Frame 还有如是否是 key_frame 之类的信息。
所以要从 v4l2 采集到的帧(v4l2_process_image 中 buf.start)转换为 YUV420 格式给编码器,需要两个 A
VFrame(其实 AVPicture 已经足够了):
AVFrame *srcbuf ; //源格式 YUV422
AVFrame *dstbuf ; //目标 YUV420
对于 YUV422 格式只用到了 srcbuf->data[0]存放 YUV 数据(打包格式),和 srcbuf->linesize[0]这是一
帧每行所站的 bytes 数(YUV422 为 width *2)。
对于 YUV420 格式(平面格式),则 data[0]、data[1]、data[2]对应 YUV 三个平面。
data[0]:Y 起始 addr,size 个 y 数据。 (size=width *height)
data[1] = data[0] + size; // U 起始 addr ,size/4 个 U
data[2] = data[1] + size / 4; // V 起始 addr,size/4 个 V
从 YUV422 转换为 YUV420 格式可以利用 ffmpeg 下 libavcodec/imgconvert.c 中的
void yuyv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
int width, int height) 函数,
但要设置好 srcbuf , dstbuf,(强制类型转换)并为分配好内存,刚开始就是在这方面出现问题,后面
再提。
总结,现在有了 buffer buf 结构的帧数据(在 buf.start 中以 YUV422 存储),先要将其放到 AVFrame *
srcbuf 中(仍为 YUV422 格式),再用 yuyv422_to_yuv420p 转换为 YUV420 格式并存在 AVFrame *dstb
uf ,dstbuf 交给编码器 mpeg4 编码。
在版本 v1.0,为初次遇到的内存错误:
●
dstbuf = avcodec_alloc_frame();
只是这样就以为为 srcbuf , dstbuf 分配好了内存。
srcbuf->data[0] = (uint8_t*)buf.start;srcbuf->data[0]指向 buf.start 就开始 yuyv422_to_yuv42
0p 转换了。(见 main.c v4l2_process_image 函数)
运行时错误信息: 段错误
调试信息:
Breakpoint 1, v4l2_process_image (buf=...) at main.c:29
29 srcbuf = avcodec_alloc_frame();
(gdb) s
30 dstbuf = avcodec_alloc_frame();
(gdb) s
31 srcbuf->data[0] = (uint8_t*)buf.start;
(gdb) s
32 srcbuf->linesize[0] = V4L2_WIDTH*2;
(gdb) p srcbuf->data[0]
$1 = (uint8_t *) 0xb7bf6000
(gdb) p srcbuf->data[0][0]@10
Cannot access memory at address 0xb7bf6000
(gdb) p buf.start[0]@10
Attempt to dereference a generic pointer.
(gdb) p dstbuf->data[0]
$2 = (uint8_t *) 0x0
(gdb) p dstbuf->data[0][0]@5
Cannot access memory at address 0x0
srcbuf->data[0]已指向 buf.start,但是无法访问数组的数据,可能是指针为 void*的原因,(uint8_t
*)强制转换也没用。
dstbuf->data[0]的值为 (uint8_t *) 0x0,并没有指向可用的内存。所以 srcbuf = avcodec_alloc_fr
ame()并没有分配内存,可能只是声明了 srcbuf 为 AVFrame。还需要用 malloc()分配内存。
在版本 v1.1,针对以上问题的处理为:
●
uint8_t *picture_bufdst,*picture_bufsrc;
AVFrame *srcbuf = NULL; //源 YUV422
AVFrame *dstbuf = NULL; //目标 YUV420
srcbuf = avcodec_alloc_frame();
dstbuf = avcodec_alloc_frame();
picture_bufsrc = malloc(640 * 480 *2);
srcbuf->data[0] = picture_bufsrc;
memcpy(srcbuf->data[0], buf.start, 640 * 480 * 2);
srcbuf->linesize[0] = V4L2_WIDTH*2; //每行 bytes 数
picture_bufdst = malloc((640 * 480 * 3) / 2); /* size for YUV 420 */
dstbuf->data[0] = picture_bufdst; //Y 起始 addr,size 个 Y
dstbuf->data[1] = dstbuf->data[0] + 640*480; // U 起始 addr ,size/4 个 U
dstbuf->data[2] = dstbuf->data[1] + 640*480/4; // V 起始 addr,size/4 个 V
dstbuf->linesize[0] = c->width;
dstbuf->linesize[1] = c->width / 2;
dstbuf->linesize[2] = c->width / 2;
可见,不但要分配内存,还要使 data[0]等指针指向正确的位置。即对 AVFrame 的初始化(其实也就是内
存分配)。
以下为调试信息:
(gdb) p srcbuf->data[0][0]@10
$2 = "\213r\214t\214t\213u\212r"
(gdb) p buf.start[0]@10
Attempt to dereference a generic pointer.
(gdb) p dstbuf->data[0][0]@5
$3 = "\000\000\000\000"
buf.start[0]仍无法访问, srcbuf , dstbuf 已可用.
在版本 v1.2 改进:
●
encod_init() 为编码的初始化相关的函数。
Srcbuf 直接指向 buf.start ,省略了 memcpy()。
在版本 v1.3 改进:
●
AVCodecContext *c,c->pix_fmt = PIX_FMT_YUYV422 可设置 Pixel forma,将其设为 YUV422 格式,
出错:only YUV420 and YUV422 are supported ,原来是设错了,但知道了支持的格式了。
改为 c->pix_fmt = PIX_FMT_YUV422P ,这样省去了到 YUV420 的转换。
首先 srcbuf 直接指向 buf.start ,出现了段错误,
(gdb) p srcbuf->data[0][0]@10
Cannot access memory at address 0xb7bf5000
(gdb) s
73 out_size = avcodec_encode_video(c, outbuf, OUTBUF_SIZE, srcbuf);
(gdb) s
Program received signal SIGSEGV, Segmentation fault.
0x00b76fc6 in ?? () from /lib/tls/i686/cmov/libc.so.6
(gdb) q
再用 memcpy(srcbuf->data[0], buf.start, 640 * 480 * 2);
(gdb) p srcbuf->data[0][0]@10
$1 = "Bk@|>l>{Bm"
77 out_size = avcodec_encode_video(c, outbuf, OUTBUF_SIZE, srcbuf);
(gdb) p out_size
$1 = 0
(gdb) s
Program received signal SIGSEGV, Segmentation fault.
0x00b76fc6 in ?? () from /lib/tls/i686/cmov/libc.so.6
srcbuf->data[0]有数据,但仍然在 avcodec_encode_video 中出现段错误。
原因呢?
在 ffmpeg 中对各种格式的解释为:
PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
引自:file:///usr/share/doc/ffmpeg-doc/html/pixfmt_8h.html#a60883d4958a60b91661e97027a85072a
在 V4L2 下的解释:
V4L2_PIX_FMT_YUV422P 4 × 4 pixel image
Byte Order. Each cell is one byte.
start + 0: Y'00 Y'01 Y'02 Y'03
start + 4: Y'10 Y'11 Y'12 Y'13
start + 8: Y'20 Y'21 Y'22 Y'23
start + 12: Y'30 Y'31 Y'32 Y'33
start + 16: Cb00 Cb01
start + 18: Cb10 Cb11
start + 20: Cb20 Cb21
start + 22: Cb30 Cb31
start + 24: Cr00 Cr01
start + 26: Cr10 Cr11
start + 28: Cr20 Cr21
start + 30: Cr30 Cr31
引自:http://www.linuxtv.org/downloads/v4l-dvb-apis/re16.html#id3090524
其 YUV422 是指 PIX_FMT_YUV422P ,仍为平面格式(planar),而 video4linux 输入的应该是 PIX_FMT
_YUYV422 打包格式,所以始终还是要进行转换。
所以本文涉及的 YUV 三中格式总结为:
YUYV422:v4l 输出格式,打包格式
YUV420P,YUV422P:平面格式,ffmpeg 编码器支持的输入格式。(带 P 的为 planar?)
process
struct
buffer
数组
byte
http
linux
vb
api
写下你的评论吧 !
吐个槽吧,看都看了
会员登录
|
用户注册
推荐阅读
int
javascript分页类支持页码格式
前端时间因为项目需要,要对一个产品下所有的附属图片进行分页显示,没考虑ajax一张张请求,所以干脆一次性全部把图片out,然 ...
[详细]
蜡笔小新 2024-11-12 14:58:57
int
IOS Run loop详解
为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ...
[详细]
蜡笔小新 2024-11-13 12:14:35
int
开机自启动的几种方式
0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ...
[详细]
蜡笔小新 2024-11-12 11:16:30
int
技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ...
[详细]
蜡笔小新 2024-11-11 15:24:24
import
如何在Nginx服务器上轻松配置CertBot以实现SSL证书自动化管理
为了确保iOS应用能够安全地访问网站数据,本文介绍了如何在Nginx服务器上轻松配置CertBot以实现SSL证书的自动化管理。通过这一过程,可以确保应用始终使用HTTPS协议,从而提升数据传输的安全性和可靠性。文章详细阐述了配置步骤和常见问题的解决方法,帮助读者快速上手并成功部署SSL证书。 ...
[详细]
蜡笔小新 2024-11-10 08:42:08
hash
浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ...
[详细]
蜡笔小新 2024-11-13 16:43:07
int
JUC(三):深入解析AQS
本文详细介绍了Java并发工具包中的核心类AQS(AbstractQueuedSynchronizer),包括其基本概念、数据结构、源码分析及核心方法的实现。 ...
[详细]
蜡笔小新 2024-11-13 15:40:34
int
使用ArcGIS for Java和Flex浏览自定义ArcGIS Server 9.3地图
本文介绍了如何在Flex应用程序中实现浏览自定义ArcGIS Server 9.3发布的地图。这是一个基本的入门示例,适用于初学者。 ...
[详细]
蜡笔小新 2024-11-13 14:40:13
import
Spring – Bean Life Cycle
Spring – Bean Life Cycle ...
[详细]
蜡笔小新 2024-11-13 13:24:40
hash
图像相似度对比的多种方法
本文介绍了几种常用的图像相似度对比方法,包括直方图方法、图像模板匹配、PSNR峰值信噪比、SSIM结构相似性和感知哈希算法。每种方法都有其优缺点,适用于不同的应用场景。 ...
[详细]
蜡笔小新 2024-11-13 11:04:56
hash
解决Only fullscreen opaque activities can request orientation错误的方法
本文介绍了在使用PictureSelectorLight第三方框架时遇到的Only fullscreen opaque activities can request orientation错误,并提供了一种有效的解决方案。 ...
[详细]
蜡笔小新 2024-11-13 09:46:25
c语言
C语言检测
字符串学习时间:1.5W(“W”周,下同)知识点checkliststrlen()函数的返回值是什么类型的?字 ...
[详细]
蜡笔小新 2024-11-12 19:23:53
import
Go语言中的命令设计模式详解
命令模式是一种行为设计模式,它将请求封装成一个独立的对象,从而允许你参数化不同的请求、队列请求或者记录请求日志。本文将详细介绍命令模式的基本概念、组件及其在实际场景中的应用。 ...
[详细]
蜡笔小新 2024-11-12 09:26:59
int
深入解析:Synchronized 关键字在 Java 中对 int 和 Integer 对象的作用与影响
深入探讨了 `Synchronized` 关键字在 Java 中对 `int` 和 `Integer` 对象的影响。尽管初看此题似乎简单,但其实质在于理解对象的概念。根据《Java编程思想》第二章的观点,一切皆为对象。本文详细分析了 `Synchronized` 关键字在不同数据类型上的作用机制,特别是对基本数据类型 `int` 和包装类 `Integer` 的区别处理,帮助读者深入理解 Java 中的同步机制及其在多线程环境中的应用。 ...
[详细]
蜡笔小新 2024-11-11 13:13:17
int
如何在Linux中通过编程手段禁用硬件预取功能?
本文探讨了如何通过编程手段在Linux系统中禁用硬件预取功能。基于Intel® Core™微架构的应用性能优化需求,文章详细介绍了相关配置方法和代码实现,旨在帮助开发人员有效控制硬件预取行为,提升应用程序的运行效率。 ...
[详细]
蜡笔小新 2024-11-10 14:02:38
mySi2502876237
这个家伙很懒,什么也没留下!
Tags | 热门标签
copy
golang
bitmap
instance
subset
byte
int
php8
hook
search
heap
perl
import
timestamp
hash
node.js
python3
frameworks
cmd
random
export
yaml
typescript
expression
join
c语言
vbscript
less
tags
buffer
RankList | 热门文章
1
解决mysql启动时出现系统错误2的方法
2
Oracle 完整数据库副本
3
word文档查重_论文查重应该提交什么格式?
4
拷贝HttpRequestBase对象
5
软件工程—个人作业(5)
6
服务器监控系统大概多少钱,服务器监控系统 报价
7
JavaScript字符串包含
8
kubernetes二进宫系列——k8s整体架构与核心组件详解2
9
精准创业实战第13章 不要堆积功能
10
微软云平台 Azure简介 (四)Windows Azure 存储之Blob
11
Word批量打印软件/工具
12
C语言解题——指针解析(牛客网题目)
13
查漏补缺_半夜思考之查漏补缺 , Spring 中 Bean 之间的依赖问题
14
说说如何写分析类文章
15
H3C/锐捷 路由、交换 网御防火墙 一些配置要点
PHP1.CN | 中国最专业的PHP中文社区 |
DevBox开发工具箱
|
json解析格式化
|
PHP资讯
|
PHP教程
|
数据库技术
|
服务器技术
|
前端开发技术
|
PHP框架
|
开发工具
|
在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved |
京公网安备 11010802041100号
|
京ICP备19059560号-4
| PHP1.CN 第一PHP社区 版权所有