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

FFmpeg-aac、h264封装flv及时间转换

文章目录

      • 时间概念
      • 流程
      • api
      • 核心代码

时间概念

dts: 解码时间戳, 表示压缩帧的解码时间
pts: 显示时间戳, 表示将压缩帧解码后得到的原始帧的显示时间
时间基: time_base , 通常以ms为单位
时间戳: timestamp , 多少个时间基
真实时间:time_base * timestamp

如一个视频帧的dts为40(时间戳) ,time_base:1/1000s
真实时间: 40 * 1/1000 s

ffmpeg/ffplay命令参数:
tbr: 通常为帧率
tbn: 视频流的时间基
tbc: 视频解码的时间基

ffmepg内部时间基:
#define AV_TIME_BASE 1000000 //微妙

时间转换
av_q2d():将时间从AVRational(分数)形式转换为double形式

static inline double av_q2d(AVRational a){return a.num / (double) a.den;
}

时间基转换函数
av_rescale_q() :⽤于将时间值从⼀种时间基转换为另⼀种时间基
av_rescale_rnd():用于时间取整
av_packet_rescale_ts:⽤于将AVPacket中各种时间值从⼀种时间基转换为另⼀种时间基

1 视频流

转封装过程中的时间基转换

AVStream.time_base是AVPacket中pts和dts的时间单位

  • 对于输⼊流:打开输⼊⽂件后,调⽤avformat_find_stream_info()可获取到每个流中的time_base
  • 对于输出流:打开输出⽂件后,调⽤avformat_write_header()可根据输出⽂件封装格式确定每个流的time_base并写⼊输出⽂件中

转码过程中的时间基转换

编解码器中的时间基为 AVCodecContext.time_base,值为帧率(视频帧)的倒数

解码视频帧:

时间基为 1/framerate

  • 视频解码过程中的时间基转换处理:
    若从av_read_frame读取的packet,是以AVSteam->time_base,是avcodec_receive_frame后以AVSteam->time_base为准
  • 视频编码过程中的时间基转换处理:
    编码的时候frame如果以AVstream为time_base送编码器,
    则avcodec_receive_packet读取的时候也是以转成AVSteam->time_base

2 视频流

解码后的原始视频帧时间基为 1/framerate

流程

首先生成一个h264和aac,封装为flv add_stream函数类似编码过程
请添加图片描述

api

  • avformat_write_header : 写⽂件头
  • av_write_frame/av_interleaved_write_frame: 写packet
  • av_write_trailer : 写⽂件尾
  • avcodec_parameters_from_context: 将AVCodecContext结构体中码流参数拷⻉到AVCodecParameters结构体中
  • int avformat_alloc_output_context2 – 根据filename申请上下文
  • AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) // 新增流通道
 int avformat_alloc_output_context2(AVFormatContext **ctx, ff_const59 AVOutputFormat *oformat,const char *format_name, const char *filename) {}        ctx:需要创建的context,返回NULL表示失败format:指定对应的AVOutputFormatformat_name: 指定⾳视频的格式,⽐如“flv”,“mpeg”等,如果设置为NULL,则由filename进⾏指定,让ffmpeg⾃⼰推断filename: 指定⾳视频⽂件的路径

核心代码

命令行参数: test.flv aac h264创建流生成

如何转换时间time_base:
open_audio: 关联编码器,会设置codec_ctx->time_base
avformat_write_header: base_time 转化为 1/1000

write_audio_frame中调用write_frame,pts会进行转化
如采样率44.1hz , pts_after = pts_before(-1024) * 1/44100 * 1000 = -23

//输出⽂件容器格式,生成flv文件,对应的ffmepg的源文件为flvenc.c
AVOutputFormat ff_flv_muxer = {.name           = "flv",.long_name      = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),.mime_type      = "video/x-flv",.extensions     = "flv",.priv_data_size = sizeof(FLVContext),.audio_codec    = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_ADPCM_SWF,.video_codec    = AV_CODEC_ID_FLV1,.init           = flv_init,.write_header   = flv_write_header,.write_packet   = flv_write_packet,.write_trailer  = flv_write_trailer,.check_bitstream= flv_check_bitstream,
};static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
{int ret;AVCodecContext *codec_ctx;AVFrame *frame;int got_packet = 0;AVPacket pkt = { 0 };codec_ctx = ost->enc;frame = get_video_frame(ost);av_init_packet(&pkt);/* encode the image */avcodec_encode_video2(codec_ctx, &pkt, frame, &got_packet);if (got_packet){ret = write_frame(oc, &codec_ctx->time_base, ost->st, &pkt);}else{ret = 0;}if (ret < 0){fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));exit(1);}return (frame || got_packet) ? 0 : 1;
}int main(int argc, char **argv)
{OutputStream video_st = { 0 }; // 封装视频编码相关的OutputStream audio_st = { 0 }; // 封装音频编码相关的const char *filename;   // 输出文件// AVOutputFormat ff_flv_muxerAVOutputFormat *fmt;    // 输出文件容器格式, 封装了复用规则,AVInputFormat则是封装了解复用规则AVFormatContext *oc;AVCodec *audio_codec, *video_codec;int ret;int have_video = 0, have_audio = 0;int encode_video = 0, encode_audio = 0;AVDictionary *opt = NULL;int i;filename = argv[1];/* 分配AVFormatContext并根据filename绑定合适的AVOutputFormat */avformat_alloc_output_context2(&oc, NULL, NULL, filename);fmt = oc->oformat; // 获取绑定的AVOutputFormat// 我们音视频课程音视频编解码主要涉及H264和AAC, 所以我们指定为H264+AACfmt->video_codec = AV_CODEC_ID_H264;    // 指定编码器fmt->audio_codec = AV_CODEC_ID_AAC;     // 指定编码器/* 使用指定的音视频编码格式增加音频流和视频流 */if (fmt->video_codec != AV_CODEC_ID_NONE){add_stream(&video_st, oc, &video_codec, fmt->video_codec);have_video = 1;encode_video = 1;}if (fmt->audio_codec != AV_CODEC_ID_NONE){add_stream(&audio_st, oc, &audio_codec, fmt->audio_codec);have_audio = 1;encode_audio = 1;}if (have_video)open_video(oc, video_codec, &video_st, opt);if (have_audio)open_audio(oc, audio_codec, &audio_st, opt);/* open the output file, if needed */if (!(fmt->flags & AVFMT_NOFILE)){// 打开对应的输出文件,没有则创建avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);}// audio AVstream->base_time = 1/44100, video AVstream->base_time = 1/25// base_time audio = 1/1000 video = 1/1000avformat_write_header(oc, &opt);while (encode_video || encode_audio){/* select the stream to encode */if (encode_video &&         // video_st.next_pts值 <= audio_st.next_pts时(!encode_audio || av_compare_ts(video_st.next_pts, video_st.enc->time_base,audio_st.next_pts, audio_st.enc->time_base) <= 0)) {printf("\nwrite_video_frame\n");encode_video = !write_video_frame(oc, &video_st);}else{printf("\nwrite_audio_frame\n");encode_audio = !write_audio_frame(oc, &audio_st);}}av_write_trailer(oc);/* Close each codec. */if (have_video)close_stream(oc, &video_st);if (have_audio)close_stream(oc, &audio_st);if (!(fmt->flags & AVFMT_NOFILE))avio_closep(&oc->pb);avformat_free_context(oc);return 0;
}

相关文章:

FFmpeg-aac、h264封装flv及时间转换

文章目录 时间概念流程api核心代码 时间概念 dts: 解码时间戳, 表示压缩帧的解码时间 pts: 显示时间戳, 表示将压缩帧解码后得到的原始帧的显示时间 时间基: time_base &#xff0c; 通常以ms为单位 时间戳: timestamp , 多少个时间基 真实时间&#xff1a;time_base * timest…...

TCP并发模型 || select || poll || epoll

TCP并发模型: 1.TCP多线程模型: 缺点: 1.创建线程会带来资源开销,能够实现的并发量比较有限 2.IO模型: 1.阻塞IO: 没有数据到来时,可以让任务挂起,节省CPU资源开销,提高系统效率 2.非阻塞IO: 程序未接收到数据时一直执行,效率很低 3…...

【开源】SpringBoot框架开发房屋出售出租系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 房屋销售模块2.2 房屋出租模块2.3 预定意向模块2.4 交易订单模块 三、系统展示四、核心代码4.1 查询房屋求租单4.2 查询卖家的房屋求购单4.3 出租意向预定4.4 出租单支付4.5 查询买家房屋销售交易单 五、免责说明 一、摘…...

STM32的简单介绍

STM32是一种基于ARM Cortex-M内核的32位微控制器&#xff0c;由意法半导体公司开发和生产。STM32具有丰富的外设和功能&#xff0c;适用于各种应用场合&#xff0c;如工业控制、消费电子、物联网、人机交互等。STM32的优势包括低功耗、高性能、高可靠性、易于开发等。STM32的系…...

浏览器同源策略及跨域问题

同源策略&#xff1a;同源策略是一个重要的安全策略&#xff0c;它用于限制一个源的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档&#xff0c;减少可能被攻击的媒介。 同源策略的作用&#xff1a;保护浏览器中网站的安全&#xff0c;限制ajax只…...

【读书笔记】知识图谱概述

1、KG定义 1.1 背景知识 人工智能分为三个层次&#xff0c;分别是运算智能&#xff0c;感知智能和认知智能。运算智能是让机器能存会算&#xff1b;感知智能是让机器能听会说、能看会认&#xff1b;认知智能是解决机器能理解会思考的问题。由于知识图谱的数据组织方式是计算机…...

用尾插的思路实现 “合并两个有序链表”

一、题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [], l2 [] 输出&#…...

大数据 - Spark系列《十四》- spark集群部署模式

Spark系列文章&#xff1a; 大数据 - Spark系列《一》- 从Hadoop到Spark&#xff1a;大数据计算引擎的演进-CSDN博客 大数据 - Spark系列《二》- 关于Spark在Idea中的一些常用配置-CSDN博客 大数据 - Spark系列《三》- 加载各种数据源创建RDD-CSDN博客 大数据 - Spark系列《…...

考研C语言复习进阶(2)

目录 1. 字符指针 2. 指针数组 3. 数组指针 3.1 数组指针的定义 3.2 &数组名VS数组名 4. 函数指针 5. 函数指针数组 6. 指向函数指针数组的指针 7. 回调函数 8.三步辗转法 9. 指针和数组笔试题解析 10. 指针笔试题 指针的主题&#xff0c;我们在初级阶段的《指…...

设计模式学习笔记 - 设计原则与思想总结:1.总结回顾面向对象、设计原则、编程规范、重构技巧等知识点

概述 对前面的内容的回顾&#xff0c;温故而知新&#xff0c;包括&#xff1a;面向对象、设计原则、规范与重构三个模块的内容。 1.代码质量评判标准 如何评价代码质量的高低&#xff1f; 代码质量的评价具有很强的主观性&#xff0c;描述代码质量的词汇也有很多&#xff0c…...

WPF图表库LiveCharts的使用

这个LiveCharts非常考究版本&#xff0c;它有非常多个版本&#xff0c;.net6对应的是LiveChart2 我这里的wpf项目是.net6&#xff0c;所以安装的是这三个&#xff0c;搜索的时候要将按钮“包括愈发行版”打勾 git&#xff1a;https://github.com/beto-rodriguez/LiveCharts2?…...

第十三届蓝桥杯省赛C++ C组《全题目+题解》

填空题一般都是找规律题目&#xff0c;耐下心来慢慢分析即可。 第一题《排列字母》 【问题描述】 小蓝要把一个字符串中的字母按其在字母表中的顺序排列。 例如&#xff0c;LANQIAO 排列后为AAILNOQ。 又如&#xff0c;GOODGOODSTUDYDAYDAYUP 排列后为AADDDDDGGOOOOPSTUUYYY。…...

Linux——线程池

目录 线程池的概念 线程池的优点 线程池的实现 【注意】 线程池的线程安全 日志文件的实现 线程池的概念 线程池也是一种池化技术&#xff0c;可以预先申请一批线程&#xff0c;当我们后续有任务的时候就可以直接用&#xff0c;这本质上是一种空间换时间的策略。 如果有任…...

Linux:搭建ntp服务器

我准备两个centos7服务器 一个为主服务器连接着外网&#xff0c;并且搭建了ntp服务给其他主机同步 另外一个没有连接外网&#xff0c;通过第一台设备去同步时间 首先两个服务器都要安装ntp软件 yum -y install ntp 再把他俩的时间都改成别的 左侧的是主服务器&#xff0c;主…...

unity学习(57)——选择角色界面--删除角色2

1.客户端添加点击按钮所触发的事件&#xff0c;在selectMenu界面中增加myDelete函数&#xff0c;当点击“删除角色”按钮时触发该函数的内容。 public void myDelete() {string message nowPlayer.id;//string m Coding<StringDTO>.encode(message);NetWorkScript.get…...

Flutter:构建美观应用的跨平台方案

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

【深度学习模型移植】用torch普通算子组合替代torch.einsum方法

首先不得不佩服大模型的强大之处&#xff0c;在算法移植过程中遇到einsum算子在ONNX中不支持&#xff0c;因此需要使用普通算子替代。参考TensorRT - 使用torch普通算子组合替代torch.einsum爱因斯坦求和约定算子的一般性方法。可以写出简单的替换方法&#xff0c;但是该方法会…...

鸿蒙 Harmony 初体验

前言 看现在网上传得沸沸扬扬的鸿蒙&#xff0c;打算弄个 hello world 玩一下, 不然就跟不上时代的发展了 环境安装 我的环境 Windows 11 家庭中文版HarmonyOS SDK (API 9)DevEco Studio (3.1.1 Release)Node.js (16.19.1) 开发IDE下载 官方下载链接 配置 nodejs 这里帮…...

Jmeter+ant,ant安装与配置

1.ant含义 ant&#xff1a;Ant翻译过来是蚂蚁的意思&#xff0c;在我们做接口测试的时候&#xff0c;是可以用来做JMeter接口测试生成测试报告的工具 2.ant下载 下载地址&#xff1a;Apache Ant - Ant Manual Distributions download中选择ant 下载安装最新版zip文件 3.…...

【MySQL基础】MySQL基础操作三

文章目录 &#x1f349;1.联合查询&#x1f95d;笛卡尔积 &#x1f349;2.内连接&#x1f95d;查询单个数据&#x1f95d;查询多个数据 &#x1f349;3.外连接&#x1f349;4.自连接&#x1f349;5.合并查询 &#x1f349;1.联合查询 &#x1f95d;笛卡尔积 实际开发中往往数…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域&#xff0c;无损检测&#xff08;NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统&#xff0c;以非接触式光学麦克风技术为核心&#xff0c;打破传统检测瓶颈&#xff0c;为半导体、航空航天、汽车制造等行业提供了高灵敏…...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...

前端开发者常用网站

Can I use网站&#xff1a;一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use&#xff1a;Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站&#xff1a;MDN JavaScript权威网站&#xff1a;JavaScript | MDN...