[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 从字面上 ...
随机推荐
- dubbo(一)
1. Introduction 参考链接:https://www.baeldung.com/dubbo Dubbo is an open-source RPC and microservice fra ...
- Java Web基础 --- Servlet 综述(理论篇)
摘要: Web 技术成为当今主流的互联网 Web 应用技术之一,而 Servlet 是 Java Web 技术的核心基础.本文首先从请求/响应架构应用的大背景谈起 Servlet 的由来,明确 Ser ...
- 微信小程序学习笔记二 数据绑定 + 事件绑定
微信小程序学习笔记二 1. 小程序特点概述 没有DOM 组件化开发: 具备特定功能效果的代码集合 体积小, 单个压缩包体积不能大于2M, 否则无法上线 小程序的四个重要的文件 *js *.wxml - ...
- MongoDB学习笔记一(MongoDB介绍 + 基本指令 + 查询语句)
什么是MongoDB MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统. 在高负载的情况下,添加更多的节点,可以保证服务器性能. MongoDB 旨在为WEB应用提供可扩 ...
- ES读写数据的工作原理
es写入数据的工作原理是什么啊?es查询数据的工作原理是什么?底层的lucence介绍一下呗?倒排索引了解吗? 一.es写数据过程 1.客户端选择一个node发送请求过去,这个node就是coordi ...
- Linkerd 2.10(Step by Step)—配置重试
Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ...
- openresty(nginx) 配置 http与https使用同一个端口,禁止 IP 直接访问
准备好工作目录 mkdir work cd work mkdir conf logs 准备好 conf/nginx.conf 配置文件, 把 your.domain 换成你自己的域名 user abc ...
- redis 主从复制详解
引言 我们之前操作 Redis 都是单机版,但是实际应用中没人使用单机版,都是搭建集群的方式.这篇文章要介绍的主从复制,是指将一台 Redis 服务器的数据,复制到其他 Redis 服务器,我们将前者 ...
- 硕盟 TYPE C转HDMI+VGA+USB3.0+PD3.0四口扩展坞
硕盟SM-T54是一款USB-C 四合一多功能扩展坞,支持四口同时使用,您可以将含有USB 3.1协议的电脑主机,通过此产品连接到具有HDMI或VGA的显示器.电视机或其他显示设备.产品可以接入硬盘. ...
- 最全Windows版本jemalloc库(5.2.1)及其使用:包含动态库和静态库、x86版本和x64版本、debug版本和release版本
编写服务器程序时,需要频繁的申请和释放内存,长时间运行会产生大量的内存碎片,这就导致即使当前系统中的闲置内存还足够多,但也无法申请到大的连续可用的内存块,因为此时的物理内存已经千疮百孔像个马蜂窝.此外 ...