[FFMpeg] 非标准分辨率视频Dump YUV注意事项
背景
做视频编解码相关开发的过程中我们经常会遇到要把视频原始YUV数据保存下来查看的情况。
使用FFMpeg
对视频解码之后原始图片数据都是保存在AVFrame
这一结构中,很多时候我们都按照图像的长宽来对数据进行保存,这在绝大部分标准分辨率中都是可行的,因为图像的宽度在内存中能刚好满足CPU的字节对齐。
而对于非标准分辨率的视频来说,应该注意AVFrame
的linesize
可能比实际的图像宽度要大。
如我在解码一个858x360分辨率的视频成YUV420P的时候,其解码出来的帧的linesize
分别为{896,448,448}
,可以看到linesize[0]
大于858,相关解释可以见AVFrame
结构体定义的备注:
/**
* For video, size in bytes of each picture line.
* For audio, size in bytes of each plane.
*
* For audio, only linesize[0] may be set. For planar audio, each channel
* plane must be the same size.
*
* For video the linesizes should be multiples of the CPUs alignment
* preference, this is 16 or 32 for modern desktop CPUs. // <-- Suiyek: Ref Here
* Some code requires such alignment other code can be slower without
* correct alignment, for yet other it makes no difference.
*
* @note The linesize may be larger than the size of usable data -- there
* may be extra padding present for performance reasons.
*/
int linesize[AV_NUM_DATA_POINTERS];
不难看出,AVFrame.data
的数据存放格式是这样的:
data[i]:
[ (width >> component-shift) data | padding data ]
|<- - linesize[i] - ->|
所以我们在dump YUV的时候不能仅仅使用宽高来计算数据大小,应该去掉linesize
的对齐长度(以YUV420P为例):
void DumpYUV420P(const AVFrame* frame, const char* name) {
if (!frame->width || !frame->height)
return;
int ws, hs;
// 取得当前像素格式的U/V分量(若有)的右移系数(其实就是除以多少..)
av_pix_fmt_get_chroma_sub_sample(static_cast<AVPixelFormat>(frame->format), &ws, &hs);
int offset = 0;
std::ofstream ofs(name, std::ios::binary | std::ios::app);
for (int i = 0; i < frame->height; i++)
{
ofs.write((char*)(frame->data[0] + offset), frame->width);
offset += frame->linesize[0];
}
offset = 0;
for (int i = 0; i < frame->height >> hs; i++)
{
ofs.write((char*)(frame->data[1] + offset), frame->width >> ws);
offset += frame->linesize[1];
}
offset = 0;
for (int i = 0; i < frame->height >> hs; i++)
{
ofs.write((char*)(frame->data[2] + offset), frame->width >> ws);
offset += frame->linesize[2];
}
ofs.close();
}
参考
FFMpeg在很多地方都有做数据字节对齐的优化,字节对齐是很常见的计算机软件优化手段,可以参考:Data structure alignment
[FFMpeg] 非标准分辨率视频Dump YUV注意事项的更多相关文章
- Linux BSP非标准HDMI分辨率
Linux BSP非标准HDMI分辨率 Intrinsyc公司发布了它的一个新的Linux BSP软件的发布 打开-Q820 开发套件基于Linux内核版本.支持的软件功能包括HDMI输出,可以支持标 ...
- 【FFMPEG】各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式
目录(?)[-] 编解码学习笔记二codec类型 编解码学习笔记三Mpeg系列Mpeg 1和Mpeg 2 编解码学习笔记四Mpeg系列Mpeg 4 编解码学习笔记五Mpeg系列AAC音频 编解码学习笔 ...
- 最简单的基于FFmpeg的libswscale的示例(YUV转RGB)
===================================================== 最简单的基于FFmpeg的libswscale的示例系列文章列表: 最简单的基于FFmpeg ...
- 最简单的基于FFmpeg的视频编码器-更新版(YUV编码为HEVC(H.265))
===================================================== 最简单的基于FFmpeg的视频编码器文章列表: 最简单的基于FFMPEG的视频编码器(YUV ...
- ffmpeg在asp.net 视频转换
ffmpeg是一个源于Linux的工具软件,是FLV视频转换器,可以轻易地实现FLV向其它格式avi.asf. mpeg的转换或者将其它格式转换为flv.在视频播客中,我们通常使用它把我们上传的视频转 ...
- 利用FFmpeg玩转Android视频录制与压缩(二)<转>
转载出处:http://blog.csdn.net/mabeijianxi/article/details/72983362 预热 时光荏苒,光阴如梭,离上一次吹牛逼已经过去了两三个月,身边很多人的女 ...
- 交叉编译多平台 FFmpeg 库并提取视频帧
原文地址: 交叉编译多平台 FFmpeg 库并提取视频帧 交叉编译多平台 FFmpeg 库并提取视频帧 本文档适用于 x86 平台编译 armeabi.armeabi-v7a.arm64-v8a.x8 ...
- 交叉编译多平台 FFmpeg 库并提取视频帧(转)
交叉编译多平台 FFmpeg 库并提取视频帧 转 https://www.cnblogs.com/leviatan/p/11142579.html 本文档适用于 x86 平台编译 armeabi.a ...
- ffmpeg最简单的解码保存YUV数据 <转>
video的raw data一般都是YUV420p的格式,简单的记录下这个格式的细节,如有不对希望大家能指出. YUV图像通常有两种格式,一种是packet 还有一种是planar 从字面上 ...
随机推荐
- 今天突发奇想写了一个小工具,CSDN文章目录生成器
Why 文章被遗忘 文章检索不好用 方便总结个人知识 What 根据文章分类生成文章目录 莫逸风文章目录 项目地址 gitee(地址)
- 输入npm install 报错node-sass@4.13.0 postinstall:`node scripts/build.js` Failed at the node-sass@4.13.0
这个是因为sass安装时获取源的问题,先修改sass安装的源,再运行npm install就成功了 npm config set sass_binary_site=https://npm.taobao ...
- EL表达式学习(二)
1.从特定域中获取值: 2.从请求页面的input标签中,获取值:(同servlet中的getParameter和getParameterValues): 3.获取请求头(同servlet中的getH ...
- 痞子衡嵌入式:MCUXpresso IDE下SDK工程在Build配置上与IAR,MDK差异
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE下SDK工程在Build配置上与IAR,MDK差异. 恩智浦 SW 团队每个季度都会公布 SDK.Tool ...
- 关于IDEA无法加载main方法的bug
问题现象 main方法没有run按钮 问题解决 发现args显示灰色未调用,原来是之前莫名其妙调用了sun包下的String 删除调用问题解决!
- (六)羽夏看C语言——函数
写在前面 由于此系列是本人一个字一个字码出来的,包括示例和实验截图.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇 ...
- 性能测试工具JMeter 基础(二)—— 主界面介绍
主界面介绍 JMeter的主界面主要分为菜单导航栏.工具栏.计划树标签栏.内容栏 菜单导航栏:全部的功能的都包含在菜单栏中 工具栏:相当于菜单栏常用功能的快捷按钮 计划树标签栏:显示测试用例(计划)相 ...
- WEB漏洞——XSS
跨站脚本( Cross-site Scripting,简称为XSS或跨站脚本或跨站脚本攻击)是一种针对网站应用程序的安全漏洞攻击技术,是代码注入的一种. XSS攻击可以分为三种:反射型.存储型和DOM ...
- Sentry Web 性能监控 - Metrics
系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...
- java 多线程Thread和Runnable的区别
如果一个类继承Thread,则不适合资源共享.但是如果实现了Runable接口的话,则很容易的实现资源共享 实现Runnable接口比继承Thread类所具有的优势:1. 适合多个相同的程序代码的线程 ...