ffmpeg音视频同步原理
AVStream
该结构体描述一个媒体流
主要域的释义如下,其中大部分域的值可以由av_open_input_file根据文件头的信息确定,缺少的信息需要通过调用av_find_stream_info读帧及软解码进一步获取:
- index/id:index对应流的索引,这个数字是自动生成的,根据index可以从AVFormatContext::streams表中索引到该流;而id则是流的标识,依赖于具体的容器格式。比如对于MPEG TS格式,id就是pid。
- time_base:流的时间基准,是一个实数,该流中媒体数据的pts和dts都将以这个时间基准为粒度。通常,使用av_rescale/av_rescale_q可以实现不同时间基准的转换。
- start_time:流的起始时间,以流的时间基准为单位,通常是该流中第一个帧的pts。
- duration:流的总时间,以流的时间基准为单位。
- need_parsing:对该流parsing过程的控制域。
- nb_frames:流内的帧数目。
- r_frame_rate/framerate/avg_frame_rate:帧率相关。
- codec:指向该流对应的AVCodecContext结构,调用av_open_input_file时生成。
- parser:指向该流对应的AVCodecParserContext结构,调用av_find_stream_info时生成。
AVFormatContext
这个结构体描述了一个媒体文件或媒体流的构成和基本信息
这是FFMpeg中最为基本的一个结构,是其他所有结构的根,是一个多媒体文件或流的根本抽象。其中:
- nb_streams和streams所表示的AVStream结构指针数组包含了所有内嵌媒体流的描述;
- iformat和oformat指向对应的demuxer和muxer指针;
- pb则指向一个控制底层数据读写的ByteIOContext结构。
- start_time和duration是从streams数组的各个AVStream中推断出的多媒体文件的起始时间和长度,以微妙为单位。
通常,这个结构由av_open_input_file在内部创建并以缺省值初始化部分成员。但是,如果调用者希望自己创建该结构,则需要显式为该结构的一些成员置缺省值——如果没有缺省值的话,会导致之后的动作产生异常。以下成员需要被关注:
- probesize
- mux_rate
- packet_size
- flags
- max_analyze_duration
- key
- max_index_size
- max_picture_buffer
- max_delay
AVPacket
AVPacket定义在avcodec.h中
FFMPEG使用AVPacket来暂存解复用之后、解码之前的媒体数据(一个音/视频帧、一个字幕包等)及附加信息(解码时间戳、显示时间戳、时长等)。其中:
- dts表示解码时间戳,pts表示显示时间戳,它们的单位是所属媒体流的时间基准。
- stream_index给出所属媒体流的索引;
- data为数据缓冲区指针,size为长度;
- duration为数据的时长,也是以所属媒体流的时间基准为单位;
- pos表示该数据在媒体流中的字节偏移量;
- destruct为用于释放数据缓冲区的函数指针;
- flags为标志域,其中,最低为置1表示该数据是一个关键帧。
AVPacket 结构本身只是个容器,它使用data成员指向实际的数据缓冲区,这个缓冲区可以通过av_new_packet创建,可以通过av_dup_packet 拷贝,也可以由FFMPEG的API产生(如av_read_frame),使用之后需要通过调用av_free_packet释放。 av_free_packet调用的是结构体本身的destruct函数,它的值有两种情况:1)av_destruct_packet_nofree或 0;2)av_destruct_packet,其中,前者仅仅是将data和size的值清0而已,后者才会真正地释放缓冲区。FFMPEG内部使用 AVPacket结构建立缓冲区装载数据,同时提供destruct函数,如果FFMPEG打算自己维护缓冲区,则将destruct设为 av_destruct_packet_nofree,用户调用av_free_packet清理缓冲区时并不能够将其释放;如果FFMPEG不会再使用 该缓冲区,则将destruct设为av_destruct_packet,表示它能够被释放。对于缓冲区不能够被释放的AVPackt,用户在使用之前 最好调用av_dup_packet进行缓冲区的克隆,将其转化为缓冲区能够被释放的AVPacket,以免对缓冲区的不当占用造成异常错误。而 av_dup_packet会为destruct指针为av_destruct_packet_nofree的AVPacket新建一个缓冲区,然后将原 缓冲区的数据拷贝至新缓冲区,置data的值为新缓冲区的地址,同时设destruct指针为av_destruct_packet。
时间信息
时间信息用于实现多媒体同步。
同 步的目的在于展示多媒体信息时,能够保持媒体对象之间固有的时间关系。同步有两类,一类是流内同步,其主要任务是保证单个媒体流内的时间关系,以满足感知 要求,如按照规定的帧率播放一段视频;另一类是流间同步,主要任务是保证不同媒体流之间的时间关系,如音频和视频之间的关系(lipsync)。
对于固定速率的媒体,如固定帧率的视频或固定比特率的音频,可以将时间信息(帧率或比特率)置于文件首部(header),如AVI的hdrl List、MP4的moov box,还有一种相对复杂的方案是将时间信息嵌入媒体流的内部,如MPEG TS和Real video,这种方案可以处理变速率的媒体,亦可有效避免同步过程中的时间漂移。
FFMPEG会为每一个数据包打上时间标 签,以更有效地支持上层应用的同步机制。时间标签有两种,一种是DTS,称为解码时间标签,另一种是PTS,称为显示时间标签。对于声音来说 ,这两个时间标签是相同的,但对于某些视频编码格式,由于采用了双向预测技术,会造成DTS和PTS的不一致。
时间信息的获取:
通过调用av_find_stream_info,多媒体应用可以从AVFormatContext对象中拿到媒体文件的时间信息:主要是总时间长度和开始时间,此外还有与时间信息相关的比特率和文件大小。其中时间信息的单位是AV_TIME_BASE:微秒。
ffmpeg音视频同步原理相关推荐
- 音视频同步原理[ffmpeg]
音视频同步原理[ffmpeg] output_example.c 中AV同步的代码如下(我的代码有些修改),这个实现相当简单,不过挺说明问题. 阅读前希望大家先了解一下时间戳的概念. /* compu ...
- ffmpeg源码中ffplay音视频同步原理及实现
音视频指南 文章目录 音视频指南 前言 一.音视频同步简单介绍? 二.基本概念解释 1.为什么需要视频压缩 2.什么是I帧.p帧.b帧 3.什么是DTS,PTS 4.其他概念解释 三.常用同步策略 四 ...
- 音视频同步原理解析;音频编码和解码原理
视频流中的DTS/PTS到底是什么? DTS(解码时间戳)和PTS(显示时间戳)分别是解码器进行解码和显示帧时相对于SCR(系统参考)的时间戳.SCR可以理解为解码器应该开始从磁盘读取数据时的时间. ...
- NDK学习笔记:FFmpeg音视频同步3(你追我赶,升级ffmpeg/libyuv支持neon)
NDK学习笔记:FFmpeg音视频同步3 本篇内容说多不多,但如果要说得明明白白的,可能就有点难度了.所以我决定把我的调试过程日志都呈现出来,方便大家理解.继上一篇文末,我们学习到了什么是DTS/PT ...
- 音视频同步原理及实现
本文主要描述音视频同步原理,及常见的音视频同步方案,并以代码示例,展示如何以音频的播放时长为基准,将视频同步到音频上以实现视音频的同步播放.内容如下: 1.音视频同步简单介绍 2.DTS和PTS简介 ...
- FFMPEG音视频同步-音视频实时采集并编码推流
FFMPEG音视频同步-音视频实时采集并编码推流 //------------------------------------------------------------------------- ...
- FFmpeg 音视频同步
原地址:http://www.jianshu.com/p/27279255f67e 音视频播放器的工作的具体流程如下图所示: 播放器工作流程 简单的来说包括:解协议,解封装,对音频和视频分别进行解码, ...
- 录像音视频同步原理分析及PTS计算公式
图解分析 音视频同步要分别保证开始的PTS一样,PTS是控制帧的显示时间的,所以要实现音视频同步必须分别设置音视频的PTS. 注:音.视频最后一帧的PTS时刻不一定相同. 1. 视频时间戳计算 pts ...
- 【Android音视频开发】【020】音视频同步原理
音视频不同步现象 由于视频解码和显示,非常消耗性能,所以视频帧无法和音频帧一样,保证每一帧都能严格准时播放 在现有技术和硬件条件下,任何库都无法百分百保证音视频同步,只能尽力保证误差最小 同步方案 一 ...
- MPEG2-TS音视频同步原理
一.引言 MPEG2系统用于视音频同步以及系统时钟恢复的时间标签分别在ES,PES和TS这3个层次中. 在TS 层, TS头信息包含了节目时钟参考PCR(Program Clock Referen ...
最新文章
- c语言中空格字符怎么表示_漫画:腾讯面试题,请实现把字符串中的空格替换为“%20”...
- FckEditor2.6.4在VS2005中的使用过程
- 使用双栈实现一个队列
- 刚开始用 Go 做项目开发时都会面临哪些问题?
- centos6.5下的mysql5.6.30安装
- 微信个性状态来了,可以显示“等级”!
- Hutool 工具类
- 执行力,才是拉开人与人差距的关键
- jquery中Uncaught TypeError: $(...).ajaxUpload is not a function(…)错误解决方法
- 74hc165C语言程序,单片机驱动74hc165程序
- php做购物商品库存解决方法
- calipso是什么意思_porridge是什么意思_porridge的翻译_音标_读音_用法_例句_爱词霸在线词典...
- FTP软件FlashFXP下载和使用说明
- h3c无线认证服务器,H3C无线路由器配置样例之无认证接入
- 春季养生知识多 吃萝卜可预防上火
- 雪花算法:分布式唯一 ID 生成利器
- 无符号数与有符号数比较大小
- camera摄像原理之三:色温和自动白平衡
- No resource found that matches the given name ‘android.TextAppearance.Materia...
- python基于用户画像和协同过滤实现电影推荐系统