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

ffmpeg 怎样分析ts 流中的 sdt 表

---------------------------------------------------------
author:hjjdebug
date: 2024年 07月 24日 星期三 10:34:08 CST
descriptor: ffmpeg 怎样分析ts 流中的 sdt 表
---------------------------------------------------------
1. sdt 的概念
   sdt 就是服务描述表,就是这个表包含一个或多个服务.
   一个服务对应一个节目,所以服务就是节目的服务.
   上面听起来就是挺虎人的,
   那服务是什么呢? 
   服务就是每个频道对应的频道名称和频道供应商等信息.
   可以简单理解为就是2个字符串!!


2. ffmpeg 怎样保存sdt 表中的字符串
   由于字符串的长度并不固定,所以需要动态分配内存来保存.

    switch (desc_tag) {
    case 0x48: //0x48描述符
        service_type = get8(&p, p_end);
        if (service_type < 0) // 服务类型,0x1为数字电视业务
            break;
// getstr8 会返回动态分配的内存, 该内存的容量往往比字符串长度要大.
// 另getstr8 还会调用icon_open()函数, 该函数有动态内存分配,需调用icon_close()释放动态内存
// 这是我向下跟踪得到的.这里就不展开了.
        provider_name = getstr8(&p, p_end); 
        if (!provider_name)
            break;
        name = getstr8(&p, p_end); // 此处也是动态指针
        if (name) {
//ts->stream 是avformatContext, 先找有没有sid这个节目, 有的话直接返回program
//没有再分配节目, 有动态内存分配,要等释放AVFormatContext 时才会释放program
            AVProgram *program = av_new_program(ts->stream, sid); 
            if (program) {
            //sdt 信息保存在节目的metadata 中, program->metadata是一个字典dictionary
            //添加字典项会有内存再分配
            //而字典项key和value根据flags 可能会被复制,就是说可能有内存分配,
            //只所以要进行字符串复制是因为这里用strdup,会根据字符长度重新分配一次内存,呈紧凑字符串形式
            //它们的内存释放要等到program 被释放的时候
            //关于字典的操作还有很多细节,例如key-value已经有值了怎么办等, 可由flags控制.
                av_dict_set(&program->metadata, "service_name", name, 0);
                av_dict_set(&program->metadata, "service_provider", provider_name, 0);
            }
        }
        av_free(name);  // 释放动态内存, 保持内存平衡,因为这里的字符串存储空间往往比字符串长度大.
        av_free(provider_name);
        break;
    default:
        break;
    }

3. 这些为字符串分配的内存何时释放
   参考第2步的代码注释!
   简单说,临时用的就立即释放了,对象用的要等到对象释放时才释放,
   对象的属性也可能是不断变化的.但对sdt来讲,虽然有很多sdt表,但内容是不变的.

小结: 本博着重从内存分配的角度来描述一下sdt表的存储,是我查内存泄漏的一个小收获!
 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 昇思25天学习打卡营第22天|Pix2Pix实现图像转换
  • el-table列的显示与隐藏
  • axios请求大全
  • vue3 antdv3 检测Modal的尺寸是否改变,全屏的时候获取Modal的width与height,然后我们就可以动态设置表格高度了。
  • 网络安全-华为华三交换机防火墙日志解析示例
  • Spring, Spring Boot 和Spring MVC的关系以及区别
  • C语言学习笔记
  • 耳机、音响UWB传输数据模组,飞睿智能低延迟、高速率超宽带uwb模块技术音频应用
  • Golang高效合并(拼接)多个gzip压缩文件
  • MongoDB教程(二十一):MongoDB大文件存储GridFS
  • 安全产品在防御勒索病毒中的作用
  • windows使用ssh-agent管理私钥
  • 23.jdk源码阅读之Thread(下)
  • Scala学习笔记20: Future 和Promise
  • 【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第三十八章 驱动模块编译进内核
  • Google 是如何开发 Web 框架的
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • Angular Elements 及其运作原理
  • Angular 响应式表单之下拉框
  • Object.assign方法不能实现深复制
  • Objective-C 中关联引用的概念
  • php的插入排序,通过双层for循环
  • storm drpc实例
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 深入浅出webpack学习(1)--核心概念
  • 说说动画卡顿的解决方案
  • 物联网链路协议
  • 小程序01:wepy框架整合iview webapp UI
  • 在electron中实现跨域请求,无需更改服务器端设置
  • #162 (Div. 2)
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (arch)linux 转换文件编码格式
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (备份) esp32 GPIO
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (转)母版页和相对路径
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .NET MVC第五章、模型绑定获取表单数据
  • .net 连接达梦数据库开发环境部署
  • .NET 通过系统影子账户实现权限维持
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项
  • .net经典笔试题
  • .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • /bin/bash^M: bad interpreter: No such file or directory
  • @GetMapping和@RequestMapping的区别
  • [ vulhub漏洞复现篇 ] Grafana任意文件读取漏洞CVE-2021-43798