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

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

音视频入门基础: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官方文档的描述符

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

一、引言

由于视频的传输和存贮是十分在乎体积的,对于每一个比特(bit)都要格外珍惜,所以H.264中用到了多种熵编码来对原本的数据进行压缩。

比如Sequence Paramater Set(sps / 序列参数集)中,seq_parameter_set_id这个属性用到了无符号指数哥伦布编码ue(v):

offset_for_non_ref_pic这个属性用到了有符号指数哥伦布编码se(v):

要拿到sps中的上述属性,需要对H.264码流对应的位置进行指数哥伦布编码的解码。

二、指数哥伦布编码简介

哥伦布编码(又译作格伦布编码,英语:Golomb coding)是一种无失真资料压缩方法,由数学家所罗门·格伦布在1960年代提出。其优点为易于编码与解码,目前广泛用于无损影像压缩。它是一种变长编码。

其具体原理可以参考《百度百科:指数哥伦布码》

《维基百科:格伦布编码》

《Golomb Codes》

三、FFmpeg源码中 无符号指数哥伦布编码的解码实现

FFmpeg源码中通过get_ue_golomb、get_ue_golomb_long、get_ue_golomb_31等函数实现 对无符号指数哥伦布编码的解码。下面以get_ue_golomb_31函数为例,进行讲解。

get_ue_golomb_31函数定义在FFmpeg源码(本文演示用的FFmpeg源码版本为5.0.3)的头文件libavcodec/golomb.h中:

/**
 * read unsigned exp golomb code, constraint to a max of 31.
 * If the value encountered is not in 0..31, the return value
 * is outside the range 0..30.
 */
static inline int get_ue_golomb_31(GetBitContext *gb)
{
    unsigned int buf;

#if CACHED_BITSTREAM_READER
    buf = show_bits_long(gb, 32);

    buf >>= 32 - 9;
    skip_bits_long(gb, ff_golomb_vlc_len[buf]);
#else

    OPEN_READER(re, gb);
    UPDATE_CACHE(re, gb);
    buf = GET_CACHE(re, gb);

    buf >>= 32 - 9;
    LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
    CLOSE_READER(re, gb);
#endif

    return ff_ue_golomb_vlc_code[buf];
}

形参gb:既是输入型参数也是输出型参数。指向已经被初始化的GetBitContext类型的变量。执行get_ue_golomb_31函数之前必须确保已经使用init_get_bits函数进行初始化。(关于GetBitContext结构体可以参考《FFmpeg中位操作相关的源码:GetBitContext结构体,init_get_bits函数、get_bits1函数和get_bits函数分析》)

如果是使用get_ue_golomb_31函数对某个NALU(比如sps)中的属性进行读取。

执行get_ue_golomb_31函数之前:

gb->buffer需指向存放该NALU的“NALU Header + RBSP 的缓冲区”。

gb->buffer_end需指向上述缓冲区的末尾,也就是RBSP的最后一个字节。

gb->index的值需等于:当前读取到该缓冲区的第几位了(单位为bit)。要对以该位为起始的数据进行无符号指数哥伦布编码的解码。

gb->size_in_bit 的值需等于NALU Header + SODB的位数,单位为bit。

gb->size_in_bits_plus8的值需等于 s->size_in_bit 的值 加 8。

执行get_ue_golomb_31函数后:

gb->index的值会加上 “读取到的无符号指数哥伦布编码后的位数”。gb的其它成员的值不变。

get_ue_golomb_31函数返回值为:对gb->index的位置 进行无符号指数哥伦布解码后得到的数据。

注意:get_ue_golomb_31函数有读取范围的限制!!!只能读取0到31的数据,所以如果get_ue_golomb_31函数的返回值大于31表示出错了。

所以FFmpeg源码中(源文件libavcodec/h264_ps.c)对sps进行解码的函数ff_h264_decode_seq_parameter_set中有这样的一段逻辑:

#define MAX_SPS_COUNT          32

int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,

                                     H264ParamSets *ps, int ignore_truncation)

{//...

    sps_id    = get_ue_golomb_31(gb);

    if (sps_id >= MAX_SPS_COUNT) {
        av_log(avctx, AV_LOG_ERROR, "sps_id %u out of range\n", sps_id);
        goto fail;
    }

//...
}

如果读取到的sps_id值不小于32,表示out of range了。

如果想要更大的读取范围可以用get_ue_golomb函数和get_ue_golomb_long函数。它们的用法跟get_ue_golomb_31函数一样,只是读取范围更大而已。

四、FFmpeg源码中 有符号指数哥伦布编码的解码实现

FFmpeg源码中通过get_se_golomb和get_se_golomb_long等函数实现对 有符号指数哥伦布编码的解码。它们都定义在libavcodec/golomb.h中。

其形参跟get_ue_golomb_31函数相同,不同的地方为返回值是:对gb->index的位置 进行有符号指数哥伦布解码后得到的数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/771600.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【SpringCloud】Ribbon源码解析

ribbon是一个负载均衡组件,它可以将请求分散到多个服务提供者实例中,提高系统的性能和可用性。本章分析ribbon是如何实现负载均衡的 1、LoadBalanced 消费者在引入ribbon组件后,给http客户端添加LoadBalanced注解就可以启用负载均衡功能。Lo…

MATLAB贝叶斯线性回归模型案例

采用辛烷值数据集“spectra_data.mat”(任意数据集均可),介绍贝叶斯线性回归模型的构建和使用流程。 运行结果如下: 训练集预测精度指标如下: 训练集数据的R2为: 1 训练集数据的MAE为: 0.00067884 训练集数据的RMSE为: 0.00088939 测试集预测精度指标如下: 测试集数据的R2…

Python学习之小游戏--坦克大作战

今天跟视频学习了Python实现坦克大作战小游戏,挺有意思的,一起来玩吧~ 按空格发射子弹,上下左右键实现移动,ESC键无限复活。 import pygame,time,random from pygame.sprite import Sprite SCREEN_WIDTH800 SCREEN_HEIGHT500 BG…

如何改善提示词,让 GPT-4 更高效准确地把视频内容整体转换成文章?

(注:本文为小报童精选文章。已订阅小报童或加入知识星球「玉树芝兰」用户请勿重复付费) 让我们来讨论一下大语言模型应用中的一个重要原则 ——「欲速则不达」。 作为一个自认为懒惰的人,我一直有一个愿望:完成视频制作…

typescript2-类的类型

/* 输出 吃饭 游泳 */ []( )继承与多态------------------------------------------------------------------------1. 子类继承父类特征子类 extends 父类2. 当需要父类参数传递时,用子类也可以,这就是多态/* 继承:子类继承父类 多态…

集团型企业组织架构复杂,业务线多,如何进行高效费用管控?

企业管理中流行这样一句话:“企业转型,财务先行”。对集团型企业而言,当今的发展形势下,通过财务战略全面转型、最终撬动企业价值提升,是一件难而正确的事情。 集团企业具有经营规模大、产业链多、分支机构多、地域跨度…

容器部署rabbitmq集群迁移

1、场景: 因业务需要,要求把rabbitmq-A集群上的数据迁移到rabbitmq-B集群上,rabbitmq的数据包括元数据(RabbitMQ用户、vhost、队列、交换和绑定)和消息数据,而消息数据存储在单独的消息存储库中。 2、迁移要…

中国算力网络市场发展分析

中国算力网络市场发展现状 算力涵盖计算、内存、存储等全方位能力,广泛分布于网络边缘、云计算中心、联网设备及转发节点。随着数字化技术革新,算力与网络正深度融合,推动“算网一体化”的演进。这一新型基础设施日渐凸显其重要性&#xff0c…

番外篇 | YOLOv8改进之即插即用全维度动态卷积ODConv + 更换Neck网络为GFPN

前言:Hello大家好,我是小哥谈。本文所做出的改进是在YOLOv8中引入即插即用全维度动态卷积ODConv和更换Neck网络为GFPN,希望大家学习之后能够有所收获~!🌈 目录 🚀1.基础概念 🚀2.网络结构 🚀3.添加步骤 🚀4.改进方法 🍀🍀步骤1:block.py文件修改…

Kamailio-Web管理页面Siremis的安装与部署

siremis 是针对于 Kamailio 的web管理接口,使用PHP书写,更新至2020年,相对不是太新但是是官方友链的 以下就采用 Ubuntu 22.04Siremis 5.8.0apache http server 2.4php7.0 如有疑问请参看官方指南 以下开始介绍操作步骤 安装apache2.4 we…

一文读懂什么是“GPU算力”

在数字化转型的浪潮中,各行业对算力的需求日益激增,GPU(图形处理单元)算力作为推动科技进步的重要力量,正逐步从传统的图形渲染领域扩展到人工智能、大数据分析、高性能计算等多个前沿领域。通过本文,深入剖…

亮相2024世界人工智能大会,扫描全能王AIGC“黑科技”助力敦煌遗书数字化修复

7月4日,2024年世界人工智能大会(简称“大会”)在上海举行。这次这场科技与创新的盛会上,一张古朴、典雅的卷轴吸引了众人的目光。这张被修复的卷轴脱胎于敦煌遗书系列古籍,在被机器拍摄扫描后,卷轴上脏污、…

Airflow: 大数据调度工具详解

欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: 欢迎关注微信公众号:野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&a…

SalesForce集成案例-获取联系人信息

SalesForce本身比较复杂,涉及的东西比较多,下面以使用REST API接口为例,介绍与SalesForce集成的过程,集成案例:获取联系人信息。 首先需要注册一个免费的开发者帐号,具有完全操作SalesForce的权限。 1、注…

Echarts中的热力图和漏斗图(在Vue中使用热力图和漏斗图)

热力图 (Heatmap) Echarts的热力图用于展示两个维度数据矩阵中的值分布情况。它通过在平面上划分成多个矩形区域,并用不同的颜色填充这些区域来表示数据的大小或强度。颜色渐变从浅到深通常映射着数值从小到大,从而直观展示数据的集中程度和分布模式。热…

STM32工业自动化控制系统教程

目录 引言环境准备工业自动化控制系统基础代码实现:实现工业自动化控制系统 4.1 数据采集模块 4.2 数据处理与分析 4.3 控制系统实现 4.4 用户界面与数据可视化应用场景:工业自动化与优化问题解决方案与优化收尾与总结 1. 引言 工业自动化控制系统利用…

INFINI Console 使用介绍

上次在《INFINI Easysearch尝鲜Hands on》中我们部署了两个节点的Easysearch,并且也设置了Console对集群进行监控。那么今天我们再来介绍下INFINI Console的使用。 INFINI Console 仪表盘功能介绍 INFINI Console 是一个功能强大的数据管理和分析平台,…

JBoss JMXInvokerServlet 反序列化漏洞

漏洞原理: 这是经典的JBoss反序列化漏洞,JBoss在/invoker/JMXInvokerServlet请求中读取了用户传入的对象,然后我们利用Apache Commons Collections中的Gadget执行任意代码。 影响版本: JBoss Enterprise Application Platform 6…

实时数仓Hologres OLAP场景核心能力介绍

作者:赵红梅 Hologres PD OLAP典型应用场景与痛点 首先介绍典型的OLAP场景以及在这些场景上的核心痛点,OLAP典型应用场景很多,总结有四类:第一类是BI报表分析类,例如BI报表,实时大屏,数据中台等…

Java项目:基于SSM框架实现的班主任助理管理系统【ssm+B/S架构+源码+数据库+开题报告+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的班主任助理管理系统 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse或者idea 确保可以运行! 该系统功能完善、界面美观、操作简单、功…