ffmpeg中的时间单位以及时间转换函数(av_q2d av_rescale_q)

简介: ffmpeg中的时间单位以及时间转换函数(av_q2d av_rescale_q)

相关概念


tbr: 是我们通常所说的帧率。time base of rate
tbn: 视频流的时间基。 time base of stream
tbc: 视频解码的时间基。time base of codec
tbn = the time base in AVStream that has come from the container
tbc = the time base in AVCodecContext for the codec used for a particular stream
tbr = tbr is guessed from the video stream and is the value users want to see when they look for the video frame rate.

ffmpeg内部时间基

ffmpeg中的内部计时单位(时间基),ffmepg中的所有时间都是于它为一个单位,
比如AVStream中的duration,即这个流的长度为duration个AV_TIME_BASE.

#define AV_TIME_BASE 1000000

它还有一种分数所表式法:

#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE}

在 ffmpeg中进行换算,将不同时间基的值转成按秒为单位的值计算如下:

timestamp(秒) = pts * av_q2d(time_base)


相关定义

AVRatioal的定义如下:

typedef struct AVRational{
int num; //numerator
int den; //denominator
} AVRational;
 }

AVRatioal结构转double的函数:

static inline double av_q2d(AVRational a){
/**
* Convert rational to double.
* @param a rational to convert
**/
    return a.num / (double) a.den;
}

av_get_time_base_q函数

返回内部时基的小数表示.

/**
 * Return the fractional representation of the internal time base.
 */
AVRational av_get_time_base_q(void);

av_rescale_q函数

av_rescale_q(a,b,c)的作用是,把时间戳从一个时基调整到另外一个时基时候用的函数。其中,a 表式要换算的值;b 表式原来的时间基;c表式要转换的时间基。其计算公式为 a * b / c。

/**  * Rescale a 64-bit integer by 2 rational numbers.  
** The operation is mathematically equivalent to `a * bq / cq`.  
**  This function is equivalent to av_rescale_q_rnd() with #AV_ROUND_NEAR_INF. 
*  * @see av_rescale(), av_rescale_rnd(), av_rescale_q_rnd()  */
 int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const;

用例

用于计算Packet中的pts

if (pkt->pts != AV_NOPTS_VALUE) {
            pkt->pts = av_rescale_q(pkt->pts, mCtx->streams[pkt->stream_index]->time_base, av_get_time_base_q());
        }
        if (pkt->dts != AV_NOPTS_VALUE) {
            pkt->dts = av_rescale_q(pkt->dts, mCtx->streams[pkt->stream_index]->time_base, av_get_time_base_q());
        }

根据pts来计算一桢在整个视频中的时间位置

timestamp(秒) = pts * av_q2d(st->time_base) 

计算视频长度的方法

time(秒) = st->duration * av_q2d(st->time_base)

这里的st是一个AVStream对象指针。


时间基转换公式

timestamp(ffmpeg内部时间戳) = AV_TIME_BASE * time(秒)
time(秒) = AV_TIME_BASE_Q * timestamp(ffmpeg内部时间戳)

示例

int64_t timestamp = N * AV_TIME_BASE; 
av_seek_frame(fmtctx, index_of_video, timestamp, AVSEEK_FLAG_BACKWARD);
//ffmpeg同样为我们提供了不同时间基之间的转换函数:
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
//时间戳转秒
    time_in_seconds = av_q2d(AV_TIME_BASE_Q) * timestamp
//秒转时间戳
    timestamp = AV_TIME_BASE * time_in_seconds


目录
相关文章
|
1月前
FFmpeg中结构释放小函数
本文介绍了FFmpeg中用于释放不同结构体内存的泛化变参模板函数CleanUp,以及如何特化该模板以释放AVFormatContext、AVCodecContext、AVPacket、AVFrame和uint8_t*类型的内存,并提供了一个测试文件来演示这些函数的使用。
23 3
|
4月前
|
存储 编解码 容器
FFmpeg avformat_open_input() 函数返回错误protocol not found解决方法(实测有效!附简单FFMPEG的编解码流程)
我个人出现这个错误的时候是在打开文件时报的错误,开始以为我需要加上资源文件,那样QT确实能检测到文件的存在,但是在Debug中他是检测不到这个文件的。
469 1
|
6月前
|
编解码 算法 C++
【ffmpeg 基础函数】详解FFmpeg中的av_packet_ref函数
【ffmpeg 基础函数】详解FFmpeg中的av_packet_ref函数
64 0
|
6月前
|
算法
FFmpeg关键函数介绍
FFmpeg关键函数介绍
48 0
|
6月前
|
API 开发工具 C语言
解决新版本ffmpeg找不到avpriv_io_delete函数等问题
解决新版本ffmpeg找不到avpriv_io_delete函数等问题
99 0
|
编解码 Android开发
【Android FFMPEG 开发】Android Studio 中配置 FFMPEG 库注意事项 ( 静态库 链接 libz.so 库 | 导入 FFMPEG 函数库顺序 )
【Android FFMPEG 开发】Android Studio 中配置 FFMPEG 库注意事项 ( 静态库 链接 libz.so 库 | 导入 FFMPEG 函数库顺序 )
429 0
【Android FFMPEG 开发】Android Studio 中配置 FFMPEG 库注意事项 ( 静态库 链接 libz.so 库 | 导入 FFMPEG 函数库顺序 )
|
Android开发 C++
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(二)
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(二)
224 0
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(二)
|
Ubuntu 编译器 Android开发
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(一)
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(一)
225 0
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(一)