码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 音视频入门基础:H.264专题(12)——FFmpeg源码中通过SPS属性计算视频分辨率的实现


    =================================================================

    音视频入门基础:H.264专题系列文章:

    音视频入门基础:H.264专题(1)——H.264官方文档下载

    音视频入门基础:H.264专题(2)——使用FFmpeg命令生成H.264裸流文件

    音视频入门基础:H.264专题(3)——EBSP, RBSP和SODB

    音视频入门基础:H.264专题(4)——NALU Header:forbidden_zero_bit、nal_ref_idc、nal_unit_type简介

    音视频入门基础:H.264专题(5)——FFmpeg源码中 解析NALU Header的函数分析

    音视频入门基础:H.264专题(6)——FFmpeg源码:从H.264码流中提取NALU Header、EBSP、RBSP和SODB

    音视频入门基础:H.264专题(7)——FFmpeg源码中 指数哥伦布编码的解码实现

    音视频入门基础:H.264专题(8)——H.264官方文档的描述符

    音视频入门基础:H.264专题(9)——SPS简介

    音视频入门基础:H.264专题(10)——FFmpeg源码中,存放SPS属性的结构体和解码SPS的函数分析

    音视频入门基础:H.264专题(11)——计算视频分辨率的公式

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

    音视频入门基础:H.264专题(13)——FFmpeg源码中通过SPS属性获取视频色彩格式的实现

    音视频入门基础:H.264专题(14)——计算视频帧率的公式

    音视频入门基础:H.264专题(15)——FFmpeg源码中通过SPS属性获取视频帧率的实现

    音视频入门基础:H.264专题(16)——FFmpeg源码中,判断某文件是否为H.264裸流文件的实现

    音视频入门基础:H.264专题(17)——FFmpeg源码获取H.264裸流文件信息(视频压缩编码格式、色彩格式、视频分辨率、帧率)的总流程

    =================================================================

    一、引言

    在上一节《音视频入门基础: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函数中有如下代码,通过下面的这部分代码拿到计算视频分辨率所需的属性:

    1. int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
    2. H264ParamSets *ps, int ignore_truncation)
    3. {
    4. //...
    5. sps->gaps_in_frame_num_allowed_flag = get_bits1(gb);
    6. sps->mb_width = get_ue_golomb(gb) + 1;
    7. sps->mb_height = get_ue_golomb(gb) + 1;
    8. sps->frame_mbs_only_flag = get_bits1(gb);
    9. if (sps->mb_height >= INT_MAX / 2U) {
    10. av_log(avctx, AV_LOG_ERROR, "height overflow\n");
    11. goto fail;
    12. }
    13. sps->mb_height *= 2 - sps->frame_mbs_only_flag;
    14. //...
    15. sps->crop = get_bits1(gb);
    16. if (sps->crop) {
    17. unsigned int crop_left = get_ue_golomb(gb);
    18. unsigned int crop_right = get_ue_golomb(gb);
    19. unsigned int crop_top = get_ue_golomb(gb);
    20. unsigned int crop_bottom = get_ue_golomb(gb);
    21. int width = 16 * sps->mb_width;
    22. int height = 16 * sps->mb_height;
    23. if (avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) {
    24. av_log(avctx, AV_LOG_DEBUG, "discarding sps cropping, original "
    25. "values are l:%d r:%d t:%d b:%d\n",
    26. crop_left, crop_right, crop_top, crop_bottom);
    27. sps->crop_left =
    28. sps->crop_right =
    29. sps->crop_top =
    30. sps->crop_bottom = 0;
    31. } else {
    32. int vsub = (sps->chroma_format_idc == 1) ? 1 : 0;
    33. int hsub = (sps->chroma_format_idc == 1 ||
    34. sps->chroma_format_idc == 2) ? 1 : 0;
    35. int step_x = 1 << hsub;
    36. int step_y = (2 - sps->frame_mbs_only_flag) << vsub;
    37. if (crop_left > (unsigned)INT_MAX / 4 / step_x ||
    38. crop_right > (unsigned)INT_MAX / 4 / step_x ||
    39. crop_top > (unsigned)INT_MAX / 4 / step_y ||
    40. crop_bottom> (unsigned)INT_MAX / 4 / step_y ||
    41. (crop_left + crop_right ) * step_x >= width ||
    42. (crop_top + crop_bottom) * step_y >= height
    43. ) {
    44. av_log(avctx, AV_LOG_ERROR, "crop values invalid %d %d %d %d / %d %d\n",
    45. crop_left, crop_right, crop_top, crop_bottom, width, height);
    46. goto fail;
    47. }
    48. sps->crop_left = crop_left * step_x;
    49. sps->crop_right = crop_right * step_x;
    50. sps->crop_top = crop_top * step_y;
    51. sps->crop_bottom = crop_bottom * step_y;
    52. }
    53. } else {
    54. sps->crop_left =
    55. sps->crop_right =
    56. sps->crop_top =
    57. sps->crop_bottom =
    58. sps->crop = 0;
    59. }
    60. //...
    61. }

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

    1. static inline int parse_nal_units(AVCodecParserContext *s,
    2. AVCodecContext *avctx,
    3. const uint8_t * const buf, int buf_size)
    4. {
    5. //...
    6. for (;;) {
    7. switch (nal.type) {
    8. case H264_NAL_SPS:
    9. ff_h264_decode_seq_parameter_set(&nal.gb, avctx, &p->ps, 0);
    10. break;
    11. //...
    12. case H264_NAL_IDR_SLICE:
    13. //...
    14. s->coded_width = 16 * sps->mb_width;
    15. s->coded_height = 16 * sps->mb_height;
    16. s->width = s->coded_width - (sps->crop_right + sps->crop_left);
    17. s->height = s->coded_height - (sps->crop_top + sps->crop_bottom);
    18. if (s->width <= 0 || s->height <= 0) {
    19. s->width = s->coded_width;
    20. s->height = s->coded_height;
    21. }
    22. //...
    23. }
    24. //...
    25. }
    26. }

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

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

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

  • 相关阅读:
    【python】教你如何下载弹幕、评论、视频一体软件在伙伴面前狠狠装一波~
    Chapter7.4:线性离散系统的分析与校正考研参考题
    MySQL:日期函数整理
    Git常用命令
    算法通过村第七关-树(递归/二叉树遍历)黄金笔记|迭代遍历
    状态管理 Pinia
    微软开发新模型;YouTube 推出新AI功能;可折叠iPhone 或发布?
    英国央行已经完成加息周期,大幅下调英镑预期
    快速使用 Kafka
    low power-upf-vcsnlp(五)
  • 原文地址:https://blog.csdn.net/u014552102/article/details/140344076
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号