FFmpeg常用API与示例(一)—— 工具库篇(av_log、AVDictionary、avio)

工具层

1.av_log

可以设置日志的级别,这个看看名字就明白了,也不用过多的解释。

  • AV_LOG_PANIC
  • AV_LOG_FATAL
  • AV_LOG_ERROR
  • AV_LOG_WARNING
  • AV_LOG_INFO
  • AV_LOG_VERBOSE
  • AV_LOG_DEBUG
void test_log()
{/ av_register_all();AVFormatContext *pAVFmtCtx = NULL;pAVFmtCtx = avformat_alloc_context();printf("====================================\n");av_log(pAVFmtCtx, AV_LOG_PANIC, "Panic: Something went really wrong and we will crash now.\n");av_log(pAVFmtCtx, AV_LOG_FATAL, "Fatal: Something went wrong and recovery is not possible.\n");av_log(pAVFmtCtx, AV_LOG_ERROR, "Error: Something went wrong and cannot losslessly be recovered.\n");av_log(pAVFmtCtx, AV_LOG_WARNING, "Warning: This may or may not lead to problems.\n");av_log(pAVFmtCtx, AV_LOG_INFO, "Info: Standard information.\n");av_log(pAVFmtCtx, AV_LOG_VERBOSE, "Verbose: Detailed information.\n");av_log(pAVFmtCtx, AV_LOG_DEBUG, "Debug: Stuff which is only useful for libav* developers.\n");printf("====================================\n");avformat_free_context(pAVFmtCtx);
}
2.AVDictionary
  • AVDictionary
  • AVDictionaryEntry
  • av_dict_set
  • av_dict_count
  • av_dict_get
  • av_dict_free
void test_avdictionary()
{AVDictionary *d = NULL;AVDictionaryEntry *t = NULL;av_dict_set(&d, "name", "zhangsan", 0);av_dict_set(&d, "age", "22", 0);av_dict_set(&d, "gender", "man", 0);av_dict_set(&d, "email", "www@www.com", 0);// av_strdup()char *k = av_strdup("location");char *v = av_strdup("Beijing-China");av_dict_set(&d, k, v, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);printf("====================================\n");int dict_cnt = av_dict_count(d);printf("dict_count:%d\n", dict_cnt);printf("dict_element:\n");while (t = av_dict_get(d, "", t, AV_DICT_IGNORE_SUFFIX)){printf("key:%10s  |  value:%s\n", t->key, t->value);}t = av_dict_get(d, "email", t, AV_DICT_IGNORE_SUFFIX);printf("email is %s\n", t->value);printf("====================================\n");av_dict_free(&d);
}
3.AVParseUtil
  • av_parse_video_size
  • av_parse_video_rate
  • av_parse_time
  • av_parse_color
  • av_parse_ratio
void test_parseutil()
{char input_str[100] = {0};printf("========= Parse Video Size =========\n");int output_w = 0;int output_h = 0;strcpy(input_str, "1920x1080");av_parse_video_size(&output_w, &output_h, input_str);printf("w:%4d | h:%4d\n", output_w, output_h);// strcpy(input_str,"vga");//640x480(4:3)// strcpy(input_str,"hd1080");//high definitionstrcpy(input_str, "pal"); // ntsc(N制720x480), pal(啪制720x576)av_parse_video_size(&output_w, &output_h, input_str);printf("w:%4d | h:%4d\n", output_w, output_h);printf("========= Parse Frame Rate =========\n");AVRational output_rational = {0, 0};strcpy(input_str, "15/1");av_parse_video_rate(&output_rational, input_str);printf("framerate:%d/%d\n", output_rational.num, output_rational.den);strcpy(input_str, "pal"); // fps:25/1av_parse_video_rate(&output_rational, input_str);printf("framerate:%d/%d\n", output_rational.num, output_rational.den);printf("=========== Parse Time =============\n");int64_t output_timeval; // 单位:微妙, 1S=1000MilliSeconds, 1MilliS=1000MacroSecondsstrcpy(input_str, "00:01:01");av_parse_time(&output_timeval, input_str, 1);printf("microseconds:%lld\n", output_timeval);printf("====================================\n");
}

协议层

协议操作:三大数据结构

  • AVIOContext
  • **URLContext **
  • URLProtocol

协议(文件)操作的顶层结构是 AVIOContext,这个对象实现了带缓冲的读写操作;FFMPEG的输入对象 AVFormat 的 pb 字段指向一个 AVIOContext。

AVIOContext 的 opaque 实际指向一个 URLContext 对象,这个对象封装了协议对象及协议操作对象,其中 prot 指向具体的协议操作对象,priv_data 指向具体的协议对象。

URLProtocol 为协议操作对象,针对每种协议,会有一个这样的对象,每个协议操作对象和一个协议对象关联,比如,文件操作对象为 ff_file_protocol,它关联的结构体是FileContext。

1.avio 实战:打开本地文件或网络直播流
  • avformat_network_init
  • avformat_alloc_context
  • avformat_open_input
  • avformat_find_stream_info
int main_222929s(int argc, char *argv[]){/av_register_all();avformat_network_init();printf("hello,ffmpeg\n");AVFormatContext* pFormatCtx = NULL;AVInputFormat *piFmt = NULL;printf("hello,avformat_alloc_context\n");// Allocate the AVFormatContext:pFormatCtx = avformat_alloc_context();printf("hello,avformat_open_input\n");//打开本地文件或网络直播流//rtsp://127.0.0.1:8554/rtsp1//ande_10s.mp4if (avformat_open_input(&pFormatCtx, "rtsp://127.0.0.1:8554/rtsp1", piFmt, NULL) < 0) {printf("avformat open failed.\n");goto quit;}else {printf("open stream success!\n");}if (avformat_find_stream_info(pFormatCtx, NULL)<0){printf("av_find_stream_info error \n");goto quit;}else {printf("av_find_stream_info success \n");printf("******nb_streams=%d\n",pFormatCtx->nb_streams);}quit:avformat_free_context(pFormatCtx);avformat_close_input(&pFormatCtx);avformat_network_deinit();return 0;
}
2.avio 实战:自定义 AVIO
int read_func(void* ptr, uint8_t* buf, int buf_size)
{FILE* fp = (FILE*)ptr;size_t size = fread(buf, 1, buf_size, fp);int ret = size;printf("Read Bytes:%d\n", size);return ret;}int64_t seek_func(void *opaque, int64_t offset, int whence)
{int64_t ret;FILE *fp = (FILE*)opaque;if (whence == AVSEEK_SIZE) {return -1;}fseek(fp, offset, whence);return ftell(fp);}int main(int argc, char *argv[]){///av_register_all();printf("hello,ffmpeg\n");int ret = 0;FILE* fp = fopen("ande_10s.flv", "rb");int nBufferSize = 1024;unsigned char* pBuffer = (unsigned char*)malloc(nBufferSize);AVFormatContext* pFormatCtx = NULL;AVInputFormat *piFmt = NULL;printf("hello,avio_alloc_context\n");// Allocate the AVIOContext://请同学们自己揣摩AVIOContext* pIOCtx = avio_alloc_context(pBuffer, nBufferSize,0,fp,read_func,0,seek_func);printf("hello,avformat_alloc_context\n");// Allocate the AVFormatContext:pFormatCtx = avformat_alloc_context();// Set the IOContext:pFormatCtx->pb = pIOCtx;//关联,绑定pFormatCtx->flags = AVFMT_FLAG_CUSTOM_IO;printf("hello,avformat_open_input\n");//打开流if (avformat_open_input(&pFormatCtx, "", piFmt, NULL) < 0) {printf("avformat open failed.\n");goto quit;}else {printf("open stream success!\n");}if (avformat_find_stream_info(pFormatCtx, NULL)<0){printf("av_find_stream_info error \n");goto quit;}else {printf("av_find_stream_info success \n");printf("******nb_streams=%d\n",pFormatCtx->nb_streams);}quit:avformat_free_context(pFormatCtx);avformat_close_input(&pFormatCtx);free(pBuffer);return 0;
}
3.avio 实战:自定义数据来源
  • av_file_map
  • avformat_alloc_context
  • av_malloc
  • avio_alloc_context
  • avformat_open_input
  • avformat_find_stream_info
//自定义缓冲区
struct buffer_data {uint8_t *ptr;size_t size; ///< size left in the buffer
};//读取数据(回调函数)
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
{struct buffer_data *bd = (struct buffer_data *)opaque;buf_size = FFMIN(buf_size, bd->size);if (!buf_size)return AVERROR_EOF;printf("ptr:%p size:%d\n", bd->ptr, bd->size);/* copy internal buffer data to buf *//// 灵活应用[内存buf]:读取的是内存,比如:加密播放器,这里解密memcpy(buf, bd->ptr, buf_size);bd->ptr  += buf_size;bd->size -= buf_size;return buf_size;
}int main(int argc, char *argv[])
{AVFormatContext *fmt_ctx = NULL;AVIOContext *avio_ctx = NULL;uint8_t *buffer = NULL, *avio_ctx_buffer = NULL;size_t buffer_size, avio_ctx_buffer_size = 4096;char *input_filename = NULL;int ret = 0;struct buffer_data bd = { 0 };printf("Hello,ffmpeg\n");if (argc != 2) {fprintf(stderr, "usage: %s input_file\n""API example program to show how to read from a custom buffer ""accessed through AVIOContext.\n", argv[0]);return 1;}input_filename = argv[1];/* slurp file content into buffer *////内存映射文件ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL);if (ret < 0)goto end;printf("av_file_map,ok\n");/* fill opaque structure used by the AVIOContext read callback */bd.ptr  = buffer;bd.size = buffer_size;/// 创建对象:AVFormatContextif (!(fmt_ctx = avformat_alloc_context())) {ret = AVERROR(ENOMEM);goto end;}printf("avformat_alloc_context,ok\n");/// 分配内存avio_ctx_buffer = av_malloc(avio_ctx_buffer_size);if (!avio_ctx_buffer) {ret = AVERROR(ENOMEM);goto end;}/// 创建对象:AVIOContext,注意参数avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,0,&bd,&read_packet,NULL,NULL);if (!avio_ctx) {ret = AVERROR(ENOMEM);goto end;}fmt_ctx->pb = avio_ctx;printf("avio_alloc_context,ok\n");/// 打开输入流ret = avformat_open_input(&fmt_ctx, NULL, NULL, NULL);if (ret < 0) {fprintf(stderr, "Could not open input\n");goto end;}printf("avformat_open_input,ok\n");/// 查找流信息ret = avformat_find_stream_info(fmt_ctx, NULL);if (ret < 0) {fprintf(stderr, "Could not find stream information\n");goto end;}printf("avformat_find_stream_info,ok\n");printf("******nb_streams=%d\n",fmt_ctx->nb_streams);av_dump_format(fmt_ctx, 0, input_filename, 0);end:avformat_close_input(&fmt_ctx);/* note: the internal buffer could have changed, and be != avio_ctx_buffer */if (avio_ctx)av_freep(&avio_ctx->buffer);avio_context_free(&avio_ctx);/// 内存映射文件:解绑定av_file_unmap(buffer, buffer_size);if (ret < 0) {fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));return 1;}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式事务技术方案

什么是分布式事务 一次课程发布操作需要向数据库、redis、elasticsearch、MinIO写四份数据&#xff0c;这里存在分布式事务问题。 什么是分布式事务&#xff1f; 首先理解什么是本地事务&#xff1f; 平常我们在程序中通过spring去控制事务是利用数据库本身的事务特性来实现…

Offline: Overcoming Model Bias for Robust Offline Deep Reinforcement Learning

EAAI 2023 paper Intro model-free的离线强化学习由于价值函数估计问题存在训练的稳定性以及鲁棒性较低。本文提出基于模型的方法&#xff0c;同构构建稳定的动力学模型帮助策略的稳定训练。 method 本文基于模型的方法&#xff0c;所构造的转移模型输入状态动作&#xff0…

图鸟模板-官网:基于Vue 3的前端开发新篇章

一、引言 随着前端技术的飞速发展&#xff0c;企业对于官网的需求也从简单的展示型网站向功能丰富、交互体验良好的方向转变。在这样的背景下&#xff0c;图鸟模板-官网以其基于Vue 3的纯前端开发特性&#xff0c;以及支持微信小程序、支付宝小程序、APP和H5的跨平台能力&…

Android Native发布广播Intent步骤和原理解析

Android Native层发布广播Intent步骤和原理解析 一、Native层发送广播的机制和原理1.1 广播发送接口1.2 应该如何去发送广播1.3 调用流程1.4 IActivityManager.java 二、具体实现2.1 cpp实现代码2.2 实现过程遇到的问题2.3 发送多个值 最近出于工作需要&#xff0c;要在Native层…

REFORMER: 更高效的TRANSFORMER模型

大型Transformer模型通常在许多任务上都能达到最先进的结果&#xff0c;但是训练这些模型的成本可能会非常高昂&#xff0c;特别是在处理长序列时。我们引入了两种技术来提高Transformer的效率。首先&#xff0c;我们用一种使用局部敏感哈希的点积注意力替换了原来的点积注意力…

验证码生成--kaptcha

验证码生成与点击重新获取验证码 如图所示&#xff0c;本文档仅展示了验证码的生成和刷新显示。 1. 概述 系统通过生成随机验证码图像和文本。 2. 代码分析 2.1. Maven依赖 <dependency><groupId>com.github.penggle</groupId><artifactId>kaptch…

JAVA基础--File

文件 为什么要知道文件 在计算机磁盘中&#xff0c;文件是一个非常重要的存在&#xff0c;大家知道我们数据都是保存在计算机磁盘&#xff0c;而磁盘以文件为载体&#xff0c;将信息存储在磁盘文件中&#xff0c;接下来我们学习的IO流也主要是对文件中的数据进行读写操作&…

第四百九十九回

文章目录 1. 概念介绍2. 使用方法2.1 固定样式2.2 自定义样式 3. 示例代码4. 内容总结 我们在上一章回中介绍了"GetMaterialApp组件"相关的内容&#xff0c;本章回中将介绍使用get显示SnackBar.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在介…

毕业论文凑字数——关于IVR自动语音应答交互式电话导航自动总机等等概念的一些剖析

目录 IVR毕业论文的讨巧思路IVR自动语音应答IVR的使用流程IVR的各种应用IVR的基本配置 一个小朋友的毕业论文要凑字数&#xff0c;所以推荐她讲一讲IVR&#xff0c;因为IVR可以翻译的名字很多&#xff0c;比如交互式语音应答&#xff0c;自动语音应答&#xff0c;自动语音服务&…

C语言例题36、判断一个数是否是回文数

题目要求&#xff1a;输入一个5位数&#xff0c;判断它是不是回文数。即12321是回文数 #include <stdio.h>int main() {int x;int ge, shi, qian, wan;printf("请输入一个5位数&#xff1a;");scanf("%d", &x);ge x % 10; //个sh…

Xshell连接提示“SSH服务器拒绝了密码”

原因1&#xff1a;数字锁没有打开 没有打开NumLock&#xff08;数字小键盘上面有一个【Num】按键&#xff09;&#xff0c;需要按键开启。 注意要检查NumLock灯是否亮起。 或者改成用字母键上面的数字键输入就好了。 原因2&#xff1a;root密码设置错误&#xff08;这个是比较常…

fatal error: ros/ros.h: 没有那个文件或目录

解决方法&#xff1a; 在出错的文件的包下的CMakeLists.txt文件里&#xff0c;加上 find_package(catkin REQUIRED COMPONENTSroscpp )include_directories(include ${catkin_INCLUDE_DIRS} )【ROS-解决问题】 fatal error: ros/ros.h: 没有那个文件或目录-CSDN博客

GO语言核心30讲 实战与应用 (第三​部分)

原站地址&#xff1a;Go语言核心36讲_Golang_Go语言-极客时间 一、io包中的接口和工具

设计模式-09 - 享元模式 flyweight pattern

设计模式-09 - 享元模式 flyweight pattern 1.定义 享元模式是一种设计模式&#xff0c;它使用共享对象来减少内存使用和提高性能。它通过存储共享的对象实例池来实现&#xff0c;这些实例可以被多个客户端同时使用。 享元模式定义了一个接口&#xff0c;使客户端可以访问共…

安全关闭Tcp连接

close与shutdwon int close(int sockfd);关闭sokcet&#xff0c;这里注意&#xff1a;当程序调用close关闭socket的时候,如果缓冲区中仍然有数据的话,协议栈会发送RST包代替FIN包&#xff0c;丢弃缓冲的数据&#xff0c;强行关闭连接 int shutdown(int sockfd, int howto);该…

【Rollup】用rollup从0到1开发一个js插件并发布到npm

Rollup 是一个 JavaScript 模块打包器&#xff0c;专注于打包 ES6 模块将其编译回多种模块化格式&#xff0c;尤其适合打包库和框架&#xff0c;因为它可以生成更小、更高效的代码&#xff0c;并且特别适合将代码打包成可在浏览器中使用的库。 从0到1开发js插件 1.创建文件夹…

es终止快照恢复进程的方法

方法1、删除索引可以终止&#xff0c;恢复进程。 DELETE index_* // 按通配符删除以index_开头的索引 DELETE _all // 删除全部索引 POST *,-.*/_close 关闭索引 POST *,-.*/_open 打开索引 DELETE *,-.* 删除全部索引方法2、强制重启es 集群也可也终…

安全狗入选福建省网信系统2024年度网络安全技术支撑单位

近日&#xff0c;福建省委网信办会同国家互联网应急中心福建分中心确定并公示了福建省网信系统2024年度网络安全技术支撑单位名单。 作为国内云原生安全领导厂商&#xff0c;安全狗也成功入选。 据悉&#xff0c;此次遴选工作依据《中华人民共和国网络安全法》《国家网络安全事…

如何通过AI技术实现员工培训的革命性变革

AI个性化培训&#xff1a;开启员工潜力的新篇章 在当今这个信息爆炸的时代&#xff0c;人工智能&#xff08;AI&#xff09;技术的影响力已经渗透到社会的各个层面&#xff0c;包括教育与培训行业。AI技术正在彻底改变我们获取知识与技能的方式&#xff0c;特别是在员工培训领域…

IDEA使用技巧2—发布web项目

作者&#xff1a;私语茶馆 1.War包类型 发布Web项目有两种模式&#xff1a;war和war exploded&#xff0c; war模式&#xff1a;将WEB工程以包的形式上传到服务器 &#xff1b;war exploded模式&#xff1a;将WEB工程以当前文件夹的位置关系上传到服务器&#xff1b; war ex…