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

FFmpeg解复用器(解封装)简单测试【2】

解复用器(解封装)的相关函数

avformat_alloc_context();负责申请一个AVFormatContext结构的内存,并进行简单初始化
avformat_free_context();释放该结构里的所有东西以及该结构本身
avformat_close_input();关闭解复用器。关闭后就不再需要使用avformat_free_context 进行释放。
avformat_open_input();打开输入视频文件
avformat_find_stream_info();获取视频文件信息
av_read_frame(); 读取音视频包
avformat_seek_file(); 定位文件
av_seek_frame():定位帧

流程

在这里插入图片描述

测试

#include <iostream>
#include <thread>
using namespace std;extern "C"
{
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
}
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"avcodec.lib")static double r2d(AVRational r)
{return r.den == 0 ? 0 : (double)r.num / (double)r.den;
}void XSleep(int ms)
{//C++ 11 chrono::milliseconds du(ms);//延迟msthis_thread::sleep_for(du);
}int main(int argc, char* argv[])
{
//解封装
cout << " test Demux FFmpeg club" << endl;const char* path = "1.mp4";//1、初始化封装库av_register_all();//初始化网络库(可以打开rtsp rtmp http 协议的流媒体视频)//avformat_network_init();//参数设置AVDictionary* opts = NULL;//设置rtsp流已tcp协议打开//av_dict_set(&opts, "rtsp_transport", "tcp", 0);//设置网络延迟时间//av_dict_set(&opts, "max_delay", "500", 0);//解封装上下文AVFormatContext* ic = NULL;int re = avformat_open_input(&ic, //上下文结构体:保存音视频的构成和基本信息path, //音视频文件路径0, //自动选择解封器&opts//参数设置,比如rtsp的延迟设置);if (re != 0)//0为成功打开文件{char buf[1024] = {0};av_strerror(re, buf, sizeof(buf) - 1);//打印错误原因cout << " open--" << path << "--failed! : " << buf << endl;getchar();return -1;}cout << "open--" << path << "--success! : " << endl;//获取音视频流信息,包含了视频和音频 //mp4在这里flv有所不同re = avformat_find_stream_info(ic, 0);//AV_TIME_BASE是时间的计数百万, ic->duration / AV_TIME_BASE是秒。//打印总时长 msint total_time = ic->duration / (AV_TIME_BASE/1000);cout << "total time : " << total_time << " ms" << endl;//打印视频流的详细信息av_dump_format(ic,0,path,0);//音视频索引int videoStream = 0;int audioStream = 1;//获取音视频流信息(遍历,函数获取),ic->nb_streams是媒体流的数量for (int i = 0; i < ic->nb_streams; i++){AVStream* as = ic->streams[i];//as->codecpar->codec_type 中保存流的类别//音频if (as->codecpar->codec_type == AVMEDIA_TYPE_AUDIO){audioStream = i;cout << i << " : 音频信息" << endl;cout << "sample_rate = " << as->codecpar->sample_rate << endl;//cout << "format = " << as->codecpar->format << endl;//AVSampleFormatcout << "channnels = " << as->codecpar->channels << endl;//cout << "codec_id = " << as->codecpar->codec_id << endl;//AVCodecIDcout << "audio fps = " << r2d(as->avg_frame_rate) << endl;//存储浮点数是按照分子分母保存的//音频一帧数据 是 一定量的样本数 单通道cout<< "frame_size = " << as->codecpar->frame_size << endl;//fps = sample_rate/frame_size}//视频else if (as->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){videoStream = i;cout << i <<" : 视频信息" << endl;cout << "width = " << as->codecpar->width << endl;cout << "height = " << as->codecpar->height << endl;//帧率 fps 分数转换cout << "vedio fps = " << r2d(as->avg_frame_rate) << endl;//打印时长int as_duration =  (as->duration) * av_q2d(as->time_base);cout << "视频的总时长为: " << as_duration / 3600 << ":" << as_duration % 3600 / 60 << ":" << as_duration % 60 << endl;//av_q2d;}}//获取视频流 另一种方法//videoStream = av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);//ic->streams[videoStream];//获取一个包的数据AVPacket* pkt = av_packet_alloc();//分配包的内存(堆上),需要手动释放int pkt_count = 0;int print_max_count = 10;//打印10个包cout << "*****av_read_frame start*****" << endl;while (1){int ret = av_read_frame(ic, pkt);if (ret < 0){cout << "******av_read_frame end*****" << endl;break;//开辟空间失败,就不需要再释放,即减少引用计数//循环播放,跳转帧的位置//int ms = 100;//根据时间基数转换位置//long long pos = (double)ms / 1000 * r2d(ic->streams[pkt->stream_index]->time_base);//av_seek_frame(ic, videoStream, pos, AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_FRAME);//往后找一帧,且找到关键帧//getchar();//continue;}if (pkt_count++ < print_max_count){if (pkt->stream_index == audioStream){//显示时间cout << "******audio pts :"<< pkt->pts << endl;//显示为ms,方便同步cout << pkt->pts * r2d(ic->streams[pkt->stream_index]->time_base) * 1000 << endl;//解码时间cout << "******audio dts :" << pkt->dts << endl;cout << "******audio size :" << pkt->size << endl;cout << "******audio pos :" << pkt->pos << endl;cout << endl;}else if (pkt->stream_index == videoStream){cout << "******video pts :" << pkt->pts << endl;//显示为mscout << pkt->pts * r2d(ic->streams[pkt->stream_index]->time_base) * 1000 << endl;cout << "******video dts :" << pkt->dts << endl;cout << "******video size :" << pkt->size << endl;cout << "******video pos :" << pkt->pos << endl;cout << endl;}elsecout << "unknow stream_index" << pkt->stream_index << endl;}//每次拿到包的数据后减少引用计数av_packet_unref(pkt);}//最后释放包的内存av_packet_free(&pkt);if (ic){//释放封装上下文,并且把ic置为0avformat_close_input(&ic);}getchar();return 0;
}

在这里插入图片描述

相关文章:

  • 每日一练——分糖果2
  • 【Go语言精进之路】构建高效Go程序:零值可用、使用复合字面值作为初值构造器
  • CAPL如何发送一条UDP报文
  • 独立游戏开发的 6 个步骤
  • 游戏找不到d3dcompiler43.dll怎么办,分享5种有效的解决方法
  • 【全开源】种草分享|动态朋友圈|瀑布流|uniapp
  • MySQL—约束—外键约束(基础)
  • Scala 柯里化、sortBy方法
  • Linux配置java,maven,marshalsec环境
  • 实现Dropdown下拉菜单监听键盘上下键选中功能-React
  • vue3状态管理,pinia的使用
  • JavaScript、Kotlin、Flutter可以开发鸿蒙APP吗?
  • HTTP --tcp和keep-alive
  • oracle linux7安装oracle11g0204
  • 强化学习(一) 基本概念和赌博机问题
  • Angular6错误 Service: No provider for Renderer2
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • EventListener原理
  • fetch 从初识到应用
  • Mac转Windows的拯救指南
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • sublime配置文件
  • TCP拥塞控制
  • yii2中session跨域名的问题
  • Zsh 开发指南(第十四篇 文件读写)
  • 第十八天-企业应用架构模式-基本模式
  • 分类模型——Logistics Regression
  • 关于extract.autodesk.io的一些说明
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 离散点最小(凸)包围边界查找
  • 两列自适应布局方案整理
  • 浏览器缓存机制分析
  • 普通函数和构造函数的区别
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 如何胜任知名企业的商业数据分析师?
  • 十年未变!安全,谁之责?(下)
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • 阿里云API、SDK和CLI应用实践方案
  • 带你开发类似Pokemon Go的AR游戏
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • #ubuntu# #git# repository git config --global --add safe.directory
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (1)STL算法之遍历容器
  • (k8s)kubernetes 部署Promehteus学习之路
  • (PySpark)RDD实验实战——求商品销量排行
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (ros//EnvironmentVariables)ros环境变量
  • (独孤九剑)--文件系统
  • (一)基于IDEA的JAVA基础1
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m