当前位置: 首页 > news >正文

音视频入门基础:H.264专题(12)——FFmpeg源码中通过SPS属性计算视频分辨率的实现

一、引言

在上一节《音视频入门基础:H.264专题(11)——计算视频分辨率的公式》中,讲述了通过SPS中的属性计算H.264编码的视频的分辨率的公式。本文讲解FFmpeg源码中计算视频分辨率的实现。

二、FFmpeg源码中计算视频分辨率的实现

从文章《音视频入门基础:H.264专题(10)——FFmpeg源码中,存放SPS属性的结构体和解码SPS的函数分析》中,我们可以知道,FFmpeg源码中通过ff_h264_decode_seq_parameter_set函数解码SPS,从而拿到SPS中的属性。

在ff_h264_decode_seq_parameter_set函数中有如下代码,通过下面的这部分代码拿到计算视频分辨率所需的属性:

int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,H264ParamSets *ps, int ignore_truncation)
{//...sps->gaps_in_frame_num_allowed_flag = get_bits1(gb);sps->mb_width                       = get_ue_golomb(gb) + 1;sps->mb_height                      = get_ue_golomb(gb) + 1;sps->frame_mbs_only_flag = get_bits1(gb);if (sps->mb_height >= INT_MAX / 2U) {av_log(avctx, AV_LOG_ERROR, "height overflow\n");goto fail;}sps->mb_height *= 2 - sps->frame_mbs_only_flag;//...sps->crop = get_bits1(gb);if (sps->crop) {unsigned int crop_left   = get_ue_golomb(gb);unsigned int crop_right  = get_ue_golomb(gb);unsigned int crop_top    = get_ue_golomb(gb);unsigned int crop_bottom = get_ue_golomb(gb);int width  = 16 * sps->mb_width;int height = 16 * sps->mb_height;if (avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) {av_log(avctx, AV_LOG_DEBUG, "discarding sps cropping, original ""values are l:%d r:%d t:%d b:%d\n",crop_left, crop_right, crop_top, crop_bottom);sps->crop_left   =sps->crop_right  =sps->crop_top    =sps->crop_bottom = 0;} else {int vsub   = (sps->chroma_format_idc == 1) ? 1 : 0;int hsub   = (sps->chroma_format_idc == 1 ||sps->chroma_format_idc == 2) ? 1 : 0;int step_x = 1 << hsub;int step_y = (2 - sps->frame_mbs_only_flag) << vsub;if (crop_left  > (unsigned)INT_MAX / 4 / step_x ||crop_right > (unsigned)INT_MAX / 4 / step_x ||crop_top   > (unsigned)INT_MAX / 4 / step_y ||crop_bottom> (unsigned)INT_MAX / 4 / step_y ||(crop_left + crop_right ) * step_x >= width ||(crop_top  + crop_bottom) * step_y >= height) {av_log(avctx, AV_LOG_ERROR, "crop values invalid %d %d %d %d / %d %d\n",     crop_left, crop_right, crop_top, crop_bottom, width, height);goto fail;}sps->crop_left   = crop_left   * step_x;sps->crop_right  = crop_right  * step_x;sps->crop_top    = crop_top    * step_y;sps->crop_bottom = crop_bottom * step_y;}} else {sps->crop_left   =sps->crop_right  =sps->crop_top    =sps->crop_bottom =sps->crop        = 0;}//...
}

然后在FFmpeg源码的源文件libavcodec/h264_parser.c的parse_nal_units函数中,有如下代码:

static inline int parse_nal_units(AVCodecParserContext *s,AVCodecContext *avctx,const uint8_t * const buf, int buf_size)
{//...for (;;) {switch (nal.type) {case H264_NAL_SPS:ff_h264_decode_seq_parameter_set(&nal.gb, avctx, &p->ps, 0);break;//...case H264_NAL_IDR_SLICE://...s->coded_width  = 16 * sps->mb_width;s->coded_height = 16 * sps->mb_height;s->width        = s->coded_width  - (sps->crop_right + sps->crop_left);s->height       = s->coded_height - (sps->crop_top   + sps->crop_bottom);if (s->width <= 0 || s->height <= 0) {s->width  = s->coded_width;s->height = s->coded_height;}//... }//...}
}

可以看到parse_nal_units函数中最终是通过下面的语句拿到视频分辨率的:

s->width = s->coded_width - (sps->crop_right + sps->crop_left);
s->height = s->coded_height - (sps->crop_top + sps->crop_bottom);

可以看到FFmpeg源码中计算视频分辨率的实现跟文章《音视频入门基础:H.264专题(11)——计算视频分辨率的公式》中描述的公式是一致的。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • WPF设置全局样式
  • 学Java JVM:全面解析Java虚拟机
  • 人工智能算法工程师(中级)课程2-Opencv视觉处理之高级操作与代码详解
  • 基于STM32设计的药品柜温湿度监测系统(华为云IOT)(184)
  • Linux 命令集
  • 【ai】决策树
  • 关于魔兽世界服务器负载的资料、计算和思考
  • 修改ES索引名称
  • vue3中谷歌地图+外网申请-原生-实现地址输入搜索+点击地图获取地址回显 +获取国外的geoJson实现省市区级联选择
  • 什么是软件定义安全SDSec
  • Archery 之SQL审核系统部署
  • MT6825磁编码IC在智能双旋机器人中的应用
  • 端到端拥塞控制的本质
  • CSS实现table表格:隔行换色的效果
  • 使用F1C200S从零制作掌机之debian文件系统完善NES
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • 78. Subsets
  • canvas 绘制双线技巧
  • DataBase in Android
  • EventListener原理
  • HomeBrew常规使用教程
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • java8-模拟hadoop
  • JavaScript 奇技淫巧
  • Linux后台研发超实用命令总结
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • Shadow DOM 内部构造及如何构建独立组件
  • Wamp集成环境 添加PHP的新版本
  • 从重复到重用
  • 技术发展面试
  • 精彩代码 vue.js
  • 批量截取pdf文件
  • 全栈开发——Linux
  • 无服务器化是企业 IT 架构的未来吗?
  • 一些关于Rust在2019年的思考
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • ‌移动管家手机智能控制汽车系统
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • $.ajax,axios,fetch三种ajax请求的区别
  • (11)MSP430F5529 定时器B
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (pytorch进阶之路)扩散概率模型
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (精确度,召回率,真阳性,假阳性)ACC、敏感性、特异性等 ROC指标
  • (九)One-Wire总线-DS18B20
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (万字长文)Spring的核心知识尽揽其中
  • (原創) 物件導向與老子思想 (OO)
  • (转)Oracle存储过程编写经验和优化措施
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET Core WebAPI中封装Swagger配置