首页 > 其他分享 >FFmpeg开发笔记(二十二)FFmpeg中SAR与DAR的显示宽高比

FFmpeg开发笔记(二十二)FFmpeg中SAR与DAR的显示宽高比

时间:2024-05-19 12:29:23浏览次数:24  
标签:ratio FFmpeg den height width aspect DAR 宽高比

​《FFmpeg开发实战:从零基础到短视频上线》一书提到:通常情况下,在视频流解析之后,从AVCodecContext结构得到的宽高就是视频画面的宽高。然而有的视频文件并非如此,如果按照AVCodecContext设定的宽高展示视频,会发现画面被压扁或者拉长了。比如该书第10章源码playsync.c在播放meg.vob时的视频画面如下图所示:

可见按照现有方式展示的话,视频画面被拉长了。这是因为视频尺寸有三种宽高概念,说明如下:

1、采样宽高比,指的是摄像头在采集画面时,方格内部的宽度与高度的采样点数量比例。采样宽高比的英文叫做“Sample Aspect Ratio”,简称SAR。
2、像素宽高比,指的是视频画面保存到文件时,宽度和高度各占据多少像素。像素宽高比的英文叫做“Pixel Aspect Ratio”,简称PAR。
3、显示宽高比,指的是视频画面渲染到屏幕时,显示出来的宽度与高度比例。显示宽高比的英文叫做“Display Aspect Ratio”,简称DAR。
采样宽高比对应AVCodecParameters结构的sample_aspect_ratio字段,该字段为分数类型AVRational。
像素宽高比对应AVCodecContext结构的width与height两个字段,比例值等于width/height。
显示宽高比对应最终要显示的画面尺寸,该值需要额外计算。多数时候sample_aspect_ratio的num与den均为1,表示宽高两个方向的采样点比例为1:1,此时像素宽高比等于显示宽高比。
由此可见,当sample_aspect_ratio的num与den均为1时,表示像素点是个正方形,此时AVCodecContext结构的宽高就是视频的宽高,无需另外处理。只有sample_aspect_ratio的num不等于den时,表示像素点是个长方形,才需要另外计算显示宽高比,并根据视频高度计算视频的实际宽度。
已知三个宽高比的转换式子如下:

DAR = PAR x SAR

令DAR=实际宽度/实际高度,则代入具体的字段,可得详细的转换式子如下:

实际宽度   width    sample_aspect_ratio.num
——————— = —————— X —————————————————————————
实际高度   height   sample_aspect_ratio.den

当实际高度为height时,表示保持原画面尺寸,则实际的画面宽度计算式子如下。

             sample_aspect_ratio.num
实际宽度 = width X —————————————————————————
             sample_aspect_ratio.den

假如​已经求得DAR值并保存在变量display_aspect_ratio中,那么实际宽度 = 实际高度 * PAR = 实际高度 * display_aspect_ratio.num / display_aspect_ratio.den。

根据上述所列的几个计算式子,编写如下的宽高比以及实际宽度的求解代码如下所示。

int origin_width = video_decode_ctx->width;
int origin_height = video_decode_ctx->height;
AVRational aspect_ratio = src_video->codecpar->sample_aspect_ratio;
AVRational display_aspect_ratio;
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
          origin_width  * aspect_ratio.num,
          origin_height * aspect_ratio.den,
          1024 * 1024);
av_log(NULL, AV_LOG_INFO, "origin size is %dx%d, SAR %d:%d, DAR %d:%d\n",
       origin_width, origin_height,
       aspect_ratio.num, aspect_ratio.den,
       display_aspect_ratio.num, display_aspect_ratio.den);
int real_width = origin_width;
// 第一种方式:根据SAR的采样宽高比,由原始的宽度算出实际的宽度
if (aspect_ratio.num!=0 && aspect_ratio.den!=0 && aspect_ratio.num!=aspect_ratio.den) {
    real_width = origin_width * aspect_ratio.num / aspect_ratio.den;
}
int target_height = 270;
int target_width = target_height*origin_width/origin_height;
// 第二种方式:根据DAR的显示宽高比,由目标的高度算出目标的宽度
if (aspect_ratio.num!=0 && aspect_ratio.den!=0 && aspect_ratio.num!=aspect_ratio.den) {
    target_width = target_height * display_aspect_ratio.num / display_aspect_ratio.den;
}
av_log(NULL, AV_LOG_INFO, "real size is %dx%d, target_width=%d, target_height=%d\n",
    real_width, origin_height, target_width, target_height);

上述修改后的代码已经附在了《FFmpeg开发实战:从零基础到短视频上线》一书第10章的源码chapter10/playsync2.c中,这个c代码是playsync.c的改进版,能够根据sample_aspect_ratio的宽高比例调整目标视频的画面尺寸。
接着执行下面的编译命令。

gcc playsync2.c -o playsync2 -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib -I/usr/local/sdl2/include -L/usr/local/sdl2/lib -lsdl2 -lavformat -lavdevice -lavfilter -lavcodec -lavutil -lswscale -lswresample -lpostproc -lm

编译完成后执行以下命令启动测试程序,期望播放视频文件meg.vob。

./playsync2 ../meg.vob

程序运行完毕,发现控制台输出以下的日志信息。

Success open input_file ../meg.vob.
origin size is 720x576, SAR 64:45, DAR 16:9
real size is 1024x576, target_width=480, target_height=270
……

同时弹出SDL窗口播放视频画面,如下图所示:

可见画面尺寸符合该视频的实际宽高比例,表示上述代码正确实现了调整视频尺寸的功能。

标签:ratio,FFmpeg,den,height,width,aspect,DAR,宽高比
From: https://www.cnblogs.com/aqi00/p/18161912

相关文章

  • Ubuntu下darknet yolo4的编译
    Ubuntu下darknetyolo4的编译首次编辑:24/5/17/23:16最后编辑:24/5/18/12:47参考链接YOLOv4-darknetinstallationandusageonyoursystem(Windows&Linux)InstallingandBuildingDarknet官网0说明此博客只记录darknetyolo4+opencv的编译安装,不涉及cuda和cuDNN......
  • FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器
    ​AVS3是中国AVS工作组制定的第三代音视频编解码技术标准,也是全球首个已推出的面向8K及5G产业应用的视频编码标准。AVS工作组于2019年3月9日完成第三代AVS视频标准(AVS3)基准档次的制订工作,参考软件的测试表明,AVS3基准档次的性能比上一代标准AVS2和HEVC提升了约30%。libuavs3d是AV......
  • FFmpeg
    命令格式:ffmpeg{通用参数}{输入音频参数}{输出音频参数}使用文档:https://cloud.baidu.com/doc/SPEECH/s/7k38lxpwf(百度)https://www.quarkbook.com/wp-content/uploads/2019/10/ffmpeg%E7%BF%BB%E8%AF%91%E6%96%87%E6%A1%A3.pdf(中文翻译) 1、音频格式转换//pcm转为wav注......
  • QStandardItemModel遍历查找搜索关键字
    (1)findItems查找内容筛选项,只能查找显示的文字中是否包含该文字,但是QList<QStandardItem*>findItems(constQString&text,Qt::MatchFlagsflags=Qt::MatchExactly,intcolumn=0)const;(2)mat......
  • Lazarus使用FFMpeg解码视频文件
    一、下载ffmpeg-delphi-pascal-headers下载地址Headers|FFVCL–DelphiFFmpegVCLComponents(VideoEncoderandVideoPlayer)下载 Releases·BtbN/FFmpeg-Builds·GitHub 下载与上面版本对应的DLL库二、引用单元libavformat,libavcodec_codec,libavcodec,FFUtils......
  • QStandardItemModel 遍历勾选的项
    QStandardItemModel遍历勾选的项rowCount()不能传入 m_model->index(0,0)根节点,无法获取行数;不传,或者传入一个空QModelIndex对象,可以获取到第一级节点的数量;QMap<QString,QVariantMap>mapSelectVideo;introotRowCount=m_model->rowCount();for(inti=0;i<ro......
  • standard quorum intersection
    在区块链和分布式共识算法领域,单词"standardquorumintersection"的中文释义可以解释为:标准法定交集。以下是对该术语的进一步解释:标准:指的是符合某种事先确定的规则或标准。法定:在分布式系统中,通常指的是合法的投票群体或节点集合。法定的数量一般是指足够多的节点,以形成......
  • ROS学习日记:(报错)terminate called after throwing an instance of 'rclcpp::excepti
    论坛里的一个老哥给出答案https://discourse.ros.org/t/how-to-shutdown-and-reinitialize-a-publisher-node-in-ros-2/4090就是我在初始化环境前先初始化了节点autonode=std::make_shared<Static_tf_broadcaster>(argv);rclcpp::init(argc,argv);rclcpp::spin(nod......
  • the request was rejected because no multipart boundary was found
    报错:Failedtoparsemultipartservletrequest;nestedexceptionisjava.io.IOException:org.apache.tomcat.util.http.fileupload.FileUploadException:therequestwasrejectedbecausenomultipartboundarywasfound本地一个模块,在多种环境下测试过都OK,但是在一个......
  • FFmpeg 命令:从入门到精通 | ffmpeg 命令图片和视频转换
    FFmpeg命令:从入门到精通|ffmpeg命令图片和视频转换截取一张图片转换视频为图片(每帧一张图)图片转换为视频从视频中生成GIF图片将GIF转化为视频FFmpeg命令:从入门到精通|ffmpeg命令图片和视频转换本节主要介绍了ffmpeg命令图片和视频转换的方法,并列举了一些例......