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

FFMPEG C++封装(二)

4 详细设计

这章是FFMPEG C++封装库的详细设计。

4.1 Init

该模块初始化FFMPEG库。

4.1.1 Init定义

namespace media
{
namespace sdk
{
void  MEDIASDK_EXPORT Init();
}
}

函数说明:

  • Init 初始化FFMPEG库,该函数可调用多次。

4.1.2 Init实现

namespace media
{
namespace sdk
{
void Init()
{static bool isInit = false;if(isInit)return;isInit = true;avcodec_register_all();avfilter_register_all();av_register_all();avformat_network_init();Report(false);
}
}
}

函数流程:

  • 注册支持的全部编码器(codec)。
  • 注册支持的全部过滤器(filter)。
  • 注册支持的全部封包格式(format)。
  • 初始化支持的网络。
  • 默认关闭打印输出。

4.2 Utils

该模块提供FFMPEG库的工具函数。

4.2.1 Utils定义

namespace media
{
namespace sdk
{
void MEDIASDK_EXPORT Report(bool on);void MEDIASDK_EXPORT Formats();
void MEDIASDK_EXPORT Codecs(bool encoder);
void MEDIASDK_EXPORT Bsfs();
void MEDIASDK_EXPORT Protocols();
void MEDIASDK_EXPORT Filters();
void MEDIASDK_EXPORT PixFmts();
void MEDIASDK_EXPORT SampleFmts();int64_t MEDIASDK_EXPORT Time();
int64_t MEDIASDK_EXPORT NoPtsValue();
int64_t MEDIASDK_EXPORT ToTime(int64_t const& pts, Rational const& timebase);std::vector<std::string> MEDIASDK_EXPORT DisplayCardNames();
}
}

4.2.2 Utils实现

4.2.2.1 Report
void Report(bool on)
{if(on)av_log_set_callback(log_callback_help);		elseav_log_set_callback(log_callback_null);
}

函数说明:

  • 如果需要打印,设置一个可打印新的callback.
  • 如果不要打印,设置一个不可打印的callback.
4.2.2.2 Formats
void Formats()
{AVInputFormat *ifmt  = NULL;AVOutputFormat *ofmt = NULL;const char *last_name;printf("File formats:\n"" D. = Demuxing supported\n"" .E = Muxing supported\n"" --\n");last_name = "000";for (;;) {int decode = 0;int encode = 0;const char *name      = NULL;const char *long_name = NULL;while ((ofmt = (AVOutputFormat *)av_oformat_next(ofmt))) {if ((name == NULL || strcmp(ofmt->name, name) < 0) &&strcmp(ofmt->name, last_name) > 0) {name      = ofmt->name;long_name = ofmt->long_name;encode    = 1;}}while ((ifmt = (AVInputFormat *)av_iformat_next(ifmt))) {if ((name == NULL || strcmp(ifmt->name, name) < 0) &&strcmp(ifmt->name, last_name) > 0) {name      = ifmt->name;long_name = ifmt->long_name;encode    = 0;}if (name && strcmp(ifmt->name, name) == 0)decode = 1;}if (name == NULL)break;last_name = name;printf(" %s%s %-15s %s\n",decode ? "D" : " ",encode ? "E" : " ",name,long_name ? long_name:" ");}
}

函数流程:

  • 遍历输出格式和输入格式
  • 打印名字和长名字
  • 输入格式作为解复用(Demux)打印
  • 输出格式作为复用(Mux)打印
4.2.2.3 Codecs
void Codecs(bool encoder)
{const AVCodecDescriptor **codecs;unsigned i, nb_codecs = get_codecs_sorted(&codecs);printf("%s:\n"" V..... = Video\n"" A..... = Audio\n"" S..... = Subtitle\n"" .F.... = Frame-level multithreading\n"" ..S... = Slice-level multithreading\n"" ...X.. = Codec is experimental\n"" ....B. = Supports draw_horiz_band\n"" .....D = Supports direct rendering method 1\n"" ------\n",encoder ? "Encoders" : "Decoders");for (i = 0; i < nb_codecs; i++) {const AVCodecDescriptor *desc = codecs[i];const AVCodec *codec = NULL;while ((codec = next_codec_for_id(desc->id, codec, encoder))) {printf(" %c", get_media_type_char(desc->type));printf((codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : ".");printf((codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : ".");printf((codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL)  ? "X" : ".");printf((codec->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)?"B" : ".");printf((codec->capabilities & AV_CODEC_CAP_DR1)           ? "D" : ".");printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");if (strcmp(codec->name, desc->name))printf(" (codec %s)", desc->name);printf("\n");}}av_free(codecs);
}

函数流程:

  • 遍历支持的编解码器
  • 按照视频,音频,字幕,帧级多线程,切片级多线程,实验性,支持画横条,支持直接渲染等格式打印
4.2.2.4 Bsfs
void Bsfs()
{const AVBitStreamFilter *bsf = 0;void *opaque = NULL;printf("Bitstream filters:\n");while ((bsf = av_bsf_iterate(&opaque)))printf("%s\n", bsf->name);printf("\n");
}

函数流程:

  • 遍历支持的Bitstream过滤器
  • 打印过滤器名称
4.2.2.5 Protocols
void Protocols()
{void *opaque = NULL;const char *name;printf("Supported file protocols:\n""Input:\n");while ((name = avio_enum_protocols(&opaque, 0)))printf("%s\n", name);printf("Output:\n");while ((name = avio_enum_protocols(&opaque, 1)))printf("%s\n", name);
}

函数流程:

  • 遍历支持的输入/输出协议
  • 打印协议名称
4.2.2.6 Filters
void Filters()
{const AVFilter *filter = NULL;char descr[64], *descr_cur;void *opaque = NULL;int i, j;const AVFilterPad *pad;printf("Filters:\n""  T.. = Timeline support\n""  .S. = Slice threading\n""  ..C = Command support\n""  A = Audio input/output\n""  V = Video input/output\n""  N = Dynamic number and/or type of input/output\n""  | = Source or sink filter\n");while ((filter = av_filter_iterate(&opaque))) {descr_cur = descr;for (i = 0; i < 2; i++) {if (i) {*(descr_cur++) = '-';*(descr_cur++) = '>';}pad = i ? filter->outputs : filter->inputs;for (j = 0; pad && avfilter_pad_get_name(pad, j); j++) {if (descr_cur >= descr + sizeof(descr) - 4)break;*(descr_cur++) = get_media_type_char(avfilter_pad_get_type(pad, j));}if (!j)*(descr_cur++) = ((!i && (filter->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)) ||( i && (filter->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS))) ? 'N' : '|';}*descr_cur = 0;printf(" %c%c%c %-17s %-10s %s\n",filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE ? 'T' : '.',filter->flags & AVFILTER_FLAG_SLICE_THREADS    ? 'S' : '.',filter->process_command                        ? 'C' : '.',filter->name, descr, filter->description);}
}

函数流程:

  • 遍历支持的过滤器
  • 按照时间线,切片线程,命令支持,音频输入/输出,视频输入/输出和源/显示类型打印。
4.2.2.7 PixFmts
void PixFmts()
{const AVPixFmtDescriptor *pix_desc = NULL;printf("Pixel formats:\n""I.... = Supported Input  format for conversion\n"".O... = Supported Output format for conversion\n""..H.. = Hardware accelerated format\n""...P. = Paletted format\n""....B = Bitstream format\n""FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL\n""-----\n");#if !CONFIG_SWSCALE
#   define sws_isSupportedInput(x)  0
#   define sws_isSupportedOutput(x) 0
#endifwhile ((pix_desc = av_pix_fmt_desc_next(pix_desc))) {enum AVPixelFormat av_unused pix_fmt = av_pix_fmt_desc_get_id(pix_desc);printf("%c%c%c%c%c %-16s       %d            %2d\n",sws_isSupportedInput (pix_fmt)              ? 'I' : '.',sws_isSupportedOutput(pix_fmt)              ? 'O' : '.',pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL   ? 'H' : '.',pix_desc->flags & AV_PIX_FMT_FLAG_PAL       ? 'P' : '.',pix_desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ? 'B' : '.',pix_desc->name,pix_desc->nb_components,av_get_bits_per_pixel(pix_desc));}
}

函数流程:

  • 遍历支持的像素格式
  • 按照输入,输出,硬件支持,调色板和位流类型打印。
4.2.2.8 SampleFmts
void SampleFmts()
{int i;char fmt_str[128];for (i = -1; i < AV_SAMPLE_FMT_NB; i++)printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), (enum AVSampleFormat)i));
}

函数流程:

  • 遍历支持的音频采样格式
  • 打印音频采样格式
4.2.2.9 Time
int64_t Time()
{return av_gettime();
}
4.2.2.10 NoPtsValue
int64_t NoPtsValue()
{return AV_NOPTS_VALUE;
}

函数说明:

  • 返回无效时间戳
4.2.2.11 ToTime
int64_t ToTime(int64_t const& pts, Rational const& timebase)
{AVRational tb1 = {timebase.num, timebase.den};AVRational tb2 = {1, AV_TIME_BASE};return av_rescale_q(pts, tb1, tb2);
}

函数说明:

  • 将以1/AV_TIME_BASE秒为单位的时间戳转换位以timebase为单位的时间戳
  • AV_TIME_BASE值为1000000
4.2.2.12 DisplayCardNames
std::vector<std::string> DisplayCardNames()
{std::vector<std::string> displayNames;IDXGIFactory * pFactory;HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory));if(FAILED(hr))return displayNames;IDXGIAdapter * pAdapter;int iAdapterNum = 0;while(pFactory->EnumAdapters(iAdapterNum, &pAdapter) != DXGI_ERROR_NOT_FOUND){DXGI_ADAPTER_DESC desc;pAdapter->GetDesc(&desc);std::wstring aa(desc.Description);displayNames.push_back(WStringToString(aa));++iAdapterNum;}return displayNames;
}

函数流程:

  • 遍历系统中显卡名称
  • 将显卡名称放入数组并返回

示例

namespace mediasdk = media::sdk;
int main(int argc, char* argv[])
{mediasdk::Init();mediasdk::Formats();//打印支持的文件格式(封包格式).mediasdk::Codecs(true);//打印支持编码器.mediasdk::Codecs(false);//打印支持的解码器.mediasdk::Protocols();//打印支持的协议.mediasdk::Filters();//打印支持过滤器.mediasdk::PixFmts();//打印支持像素格式.mediasdk::SampleFmts();//打印支持采样格式.std::vector<std::string> names = media::sdk::DisplayCardNames();for(name: names)std::cout << "Display card: " << name << std::endl;return 0;
}

未完待续…

相关文章:

FFMPEG C++封装(二)

4 详细设计 这章是FFMPEG C封装库的详细设计。 4.1 Init 该模块初始化FFMPEG库。 4.1.1 Init定义 namespace media { namespace sdk { void MEDIASDK_EXPORT Init(); } }函数说明&#xff1a; Init 初始化FFMPEG库&#xff0c;该函数可调用多次。 4.1.2 Init实现 name…...

使用unplugin-auto-import页面不引入api飘红

解决方案&#xff1a;. tsconfig.json文件夹加上 {"compilerOptions": {"target": "ES2020","useDefineForClassFields": true,"module": "ESNext","lib": ["ES2020", "DOM", &q…...

八大技术趋势案例(虚拟现实增强现实)

科技巨变,未来已来,八大技术趋势引领数字化时代。信息技术的迅猛发展,深刻改变了我们的生活、工作和生产方式。人工智能、物联网、云计算、大数据、虚拟现实、增强现实、区块链、量子计算等新兴技术在各行各业得到广泛应用,为各个领域带来了新的活力和变革。 为了更好地了解…...

Vue实现SQL语句关键字高亮显示?

SQL关键字高亮 要在Vue中实现SQL语句中关键字的高亮显示&#xff0c;你可以使用类似的方法&#xff0c;但是你需要根据SQL语法的特点来解析并高亮显示关键字。以下是一个示例代码&#xff0c;演示了如何在Vue中实现SQL语句关键字的高亮显示。 <template><div><…...

开始时间大于结束时间

1.dom中代码&#xff0c;监听所选日期值的变化&#xff0c;并把需要比较的时间字段作为参数传到监听方法中&#xff0c; <el-form-item label"起始日期" prop"startTime"><el-date-picker clearable size"small":disabled"isDisa…...

Java中 List 集合,通过 Stream 流进行排序总结

一、数据准备 public class OrderTest {private String channelCode;private BigDecimal rate;// 省略 getter、setter、toString()、constructor }List<OrderTest> orderTestList new ArrayList<>();OrderTest z09 new OrderTest("Z09", new BigDeci…...

1688中国站按关键字搜索工厂数据 API

公共参数 名称类型必须描述keyString是申请免费调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_search,item_get,item_search_shop等]cacheString否[yes,no]默认y…...

YOLOV8逐步分解(2)_DetectionTrainer类初始化过程

接上篇文章yolov8逐步分解(1)--默认参数&超参配置文件加载继续讲解。 1. 默认配置文件加载完成后&#xff0c;创建对象trainer时&#xff0c;需要从默认配置中获取类DetectionTrainer初始化所需的参数args&#xff0c;如下所示 def train(cfgDEFAULT_CFG, use_pythonFalse…...

Java是用什么语言写的?PHP呢?

Java底层是C语言。 Sun公司研发人员根据嵌入式软件的要求&#xff0c;对C进行了改造&#xff0c;去除了留在C的一些不太实用及影响安全的成分&#xff0c;并结合嵌入式系统的实时性要求&#xff0c;开发了一种称为Oak的面向对象语言。而后&#xff0c;经过迭代更新&#xff0c…...

SpringBoot Redis的使用

官方文档&#xff1a; 官方文档&#xff1a;Spring Data Redis :: Spring Data Redis 和jedis一样&#xff0c;SpringBoot Redis 也可以让我在Java代码中使用redis&#xff0c;同样也是通过引入maven依赖的形式。 加速访问github: 使用steam可以免费加速访问github Spring…...

数据仓库——维度表特性

企业信息化工厂 数据集市中的一致性&#xff0c;由于企业信息化工厂的数据集市是从集成仓库中获得信息的&#xff0c;因此至少从维度建模的角度来看&#xff0c;一致性维护的问题减少了。尽管合并不同数据源的问题依然在&#xff0c;但是负担主要在设计者身上。尽管压力降低了…...

从电荷角度理解开关电容中的电荷守恒

目录 一些铺垫电容的电荷量的解释电荷流入流出对节点电压的影响 从电荷角度理解开关电容加法器中的电荷守恒以开关电容积分器为例说明什么样的节点是电荷守恒 一些铺垫 电容的电荷量的解释 对于一个1F的电容&#xff0c;当它的压差为1V时&#xff0c;它所携带的电荷量是QCU1库…...

1.7.1 python 作业 15道

1、求出1 / 1 1 / 3 1 / 5……1 / 99的和 (1分之一1分之三1分支5....) sum0 for i in range(1,100,2): sum 1/i sum; print(sum) 2、用循环语句&#xff0c;计算2 - 10之间整数的循环相乘的值 &#xff08;2*3*4*5....10) sum 1 for i in range(2,11): sum sum *…...

synchronized 和 ReentrantLock 的区别是什么

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:synchronized 和 ReentrantLock 的区别是什么 1. 获取锁的方式 synchronized:synchronized的锁获取是隐式的。当线程进入synchronized修饰的代码…...

大话设计模式之迪米特法则

迪米特法则&#xff0c;也称为最少知识原则&#xff08;Law of Demeter&#xff09;&#xff0c;是面向对象设计中的一个重要原则&#xff0c;其核心思想是降低耦合度、减少对象之间的依赖关系&#xff0c;从而使系统更加灵活、易于维护和扩展。 根据迪米特法则&#xff0c;一…...

KSD测试系统使用方法和注意事项

①下载链接在最顶部&#xff1b; ②安装方法&#xff1a;应该先将测试设备绑定在假人身上&#xff0c;测试设备不能过度往下拉&#xff0c;传感器绑在脖子上&#xff0c;切记最后才开传感器开关&#xff01;&#xff01;&#xff01;开传感器后3秒内不要碰测试设备衣服&#x…...

IT服务营销管理案例分析题

习题一 企业随着业务的蓬勃发展&#xff0c;所投入的基础设施资源不断增加。企业员工数倍数增长&#xff0c;办公场地、办公环境等要求也越来越高。 可是该企业的IT部门人员短缺&#xff0c;对IT管理还处于被动的“救火”阶段&#xff0c;每天至少15个突发故障&#xff0c;故障…...

NRF52832修改OTA升级时的bootloader蓝牙MAC

NRF52832在OTA升级时&#xff0c;修改了APP的蓝牙MAC会导致无法升级&#xff0c;原因是OTA程序的蓝牙MAC没有被修改所以手机扫描蓝牙时无法连接 解决办法 在bootloader的程序里面加入修改蓝牙mac地址的代码实现原理&#xff1a; 在bootloader蓝牙广播开启之前修改蓝牙mac 通…...

# Python 编程入门教程

欢迎来到 Python 编程入门教程!Python 是一种简单易学、功能强大的编程语言,适用于各种应用场景,从简单的脚本到大型软件开发项目。无论你是初学者还是有一定编程经验的开发者,本教程都将为你提供全面的学习路径,帮助你掌握 Python 编程的基础知识和技能。 ## 目录 1. 简…...

Sqoop【实践 02】Sqoop1最新版 全库导入 + 数据过滤 + 字段类型支持 说明及举例代码(query参数及字段类型强制转换)

Sqoop1最新版举例 1.环境说明2.import-all-tables3.query4.字段类型支持 1.环境说明 还是之前的环境&#xff1a; # 不必要信息不再贴出 # JDK [roottcloud ~]# java -version java version "1.8.0_251" # MySQL [roottcloud ~]# mysql -V mysql Ver 14.14 Distrib…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...