微信网站开发视频教程,大气有格局的公司名字,怎么找网站模板,广告宣传方式有哪些PTS和DTS和时间基time_base
首先我们知道PTS是一帧音频或视频显示的时间#xff0c;DTS是解码时间戳 既然是时间#xff0c;PST和DTS的单位是什么呢?秒还是毫秒#xff0c;抑或是纳秒#xff1f; 先说结论—都不是 先引入FFmpeg中时间基的概念#xff0c;也就是time_bas…PTS和DTS和时间基time_base
首先我们知道PTS是一帧音频或视频显示的时间DTS是解码时间戳 既然是时间PST和DTS的单位是什么呢?秒还是毫秒抑或是纳秒 先说结论—都不是 先引入FFmpeg中时间基的概念也就是time_base它也是用来度量时间的。 如果把1秒分为25等份你可以理解就是一把尺那么每一格表示的就是1/25秒。此时的time_base{125} 。如果你是把1秒分成90000份每一个刻度就是1/90000秒此时的time_base{190000}也就是1/90000秒 所谓时间基表示的就是每个刻度是多少秒pts的值就是占多少个时间刻度占多少个格子。它的单位不是秒而是时间刻度。只有pts加上time_base两者同时在一起才能表达出时间是多少。 好比我只告诉你某物体的长度占某一把尺上的20个刻度。但是我不告诉你这把尺总共是多少厘米的你就没办法计算每个刻度是多少厘米你也就无法知道物体的长度如果知道了每个刻度占多少厘米就可以通过20刻度值获取到物体的长度pts20个刻度time_base{1,10} 每一个刻度是1/10厘米所以物体的长度ptstime_base20*1/10 厘米 2厘米 所以PTS和DTS的值只是占用了多少个时间刻度真实的显示时间和解码时间需要经过计算pts * (AVRational){1,time_base} 在ffmpeg中(AVRational){1,time_base}可以使用av_q2d(time_base)代替av_q2d(time_base)就代表了每个刻度是多少秒 此时你应该不难理解pts*av_q2d(time_base)才是帧的显示时间戳此时才能知道是这一帧在时间轴的第多少秒时显示。
时间基的转换 比如视频帧率为25也就是一秒钟25帧在ffmpeg中的时间基是90000所以在ffmpeg中的时间记得转换转化 AVRational src_time_base (AVRational){1, 25}; AVRational dst_time_base (AVRational){1, 90000}; int64_t pts 2; int64_t new_pts av_rescale_q(pts, src_time_base , dst_time_base);
下面理解时间基的转换为什么要有时间基转换。 首先不同的封装格式timebase是不一样的。另外整个转码过程不同的数据状态对应的时间基也不一致。拿mpegts封装格式25fps来说只说视频音频大致一样但也略有不同。非压缩时候的数据即YUV或者其它在ffmpeg中对应的结构体为AVFrame,它的时间基为AVCodecContext 的time_base ,AVRational{1,25}。 压缩后的数据对应的结构体为AVPacket对应的时间基为AVStream的time_baseAVRational{1,90000}。 因为数据状态不同时间基不一样所以我们必须转换在1/25时间刻度下占10格在1/90000下是占多少格。这就是pts的转换。 根据pts来计算一桢在整个视频中的时间位置 timestamp(秒) pts * av_q2d(st-time_base) duration和pts单位一样duration表示当前帧的持续时间占多少格。或者理解是两帧的间隔时间是占多少格。一定要理解单位。 pts格子数 av_q2d(st-time_base): 秒/格 计算一帧在什么位置也就是第多少秒显示ptsav_q2d(st-time_base)这一帧显示的时长duration这里的duration指的是packet-duration 计算视频长度 time(秒) st-duration * av_q2d(st-time_base) ffmpeg内部的时间与标准的时间转换方法 ffmpeg内部的时间戳 AV_TIME_BASE * time(秒) AV_TIME_BASE_Q1/AV_TIME_BASE av_rescale_q(int64_t a, AVRational bq, AVRational cq)函数这个函数的作用是计算abq / cq来把时间戳从一个时间基调整到另外一个时间基。在进行时间基转换的时候应该首先这个函数因为它可以避免溢出的情况发生。 函数表示在bq下的占a个格子在cq下是多少。 关于音频pts的计算 音频sample_rate:samples per second即采样率表示每秒采集多少采样点。 比如44100HZ就是一秒采集44100个sample. 即每个sample的时间是1/44100秒 一个音频帧的AVFrame有nb_samples个sample所以一个AVFrame耗时是nb_samples1/44100秒 即标准时间下duration_snb_samples1/44100秒 转换成AVStream时间基下 durationduration_s / av_q2d(st-time_base) 基于st-time_base的num值一般等于采样率,所以durationnb_samples. ptsndurationnnb_samples
例 在拉网络流并将音视频帧进行封装保存时就要进行时间基的转换将输入流的ptsdtsduration转化为输出流的时间基 //转换 PTS/DTS 时序
avPacket.pts av_rescale_q_rnd(avPacket.pts,in_stream-time_base,out_stream-time_base,(enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
avPacket.dts av_rescale_q_rnd(avPacket.dts, in_stream-time_base, out_stream-time_base, (enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
avPacket.duration av_rescale_q(avPacket.duration, in_stream-time_base, out_stream-time_base);
avPacket.pos -1;这里用了av_rescale_q_rnd这个函数来将时间基进行转化
int64_t av_rescale_q_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd); 它的作用是计算 “a * b / c” 的值并分五种方式来取整. 在FFmpeg中,则是将以 “时钟基c” 表示的 数值a 转换成以 “时钟基b” 来表示。 最终的情况就是将原来在in_stream-time_base时间基下的pts转为在out_stream-time_base时间基下的pts