FFmpeg源码:avpriv_set_pts_info函数分析
一、avpriv_set_pts_info函数的声明
avpriv_set_pts_info函数声明在FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的头文件libavformat/internal.h中:
/**
* Set the time base and wrapping info for a given stream. This will be used
* to interpret the stream's timestamps. If the new time base is invalid
* (numerator or denominator are non-positive), it leaves the stream
* unchanged.
*
* @param st stream
* @param pts_wrap_bits number of bits effectively used by the pts
* (used for wrap control)
* @param pts_num time base numerator
* @param pts_den time base denominator
*/
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits,
unsigned int pts_num, unsigned int pts_den);
该函数的作用是:设置AVStream的time_base。
形参st:输出型参数,指向一个AVStream对象。执行avpriv_set_pts_info函数后,st->time_base和st->pts_wrap_bits会被设置。
形参pts_wrap_bits:输入型参数,pts有效使用的位数。执行avpriv_set_pts_info函数后,st->pts_wrap_bits的值会被设置为pts_wrap_bits。
形参pts_num:输入型参数。time_base的分子。
形参pts_den:输入型参数。time_base的分母。
二、avpriv_set_pts_info函数的定义
avpriv_set_pts_info函数定义在源文件libavformat/avformat.c中:
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits,
unsigned int pts_num, unsigned int pts_den)
{
FFStream *const sti = ffstream(st);
AVRational new_tb;
if (av_reduce(&new_tb.num, &new_tb.den, pts_num, pts_den, INT_MAX)) {
if (new_tb.num != pts_num)
av_log(NULL, AV_LOG_DEBUG,
"st:%d removing common factor %d from timebase\n",
st->index, pts_num / new_tb.num);
} else
av_log(NULL, AV_LOG_WARNING,
"st:%d has too large timebase, reducing\n", st->index);
if (new_tb.num <= 0 || new_tb.den <= 0) {
av_log(NULL, AV_LOG_ERROR,
"Ignoring attempt to set invalid timebase %d/%d for st:%d\n",
new_tb.num, new_tb.den,
st->index);
return;
}
st->time_base = new_tb;
if (sti->avctx)
sti->avctx->pkt_timebase = new_tb;
st->pts_wrap_bits = pts_wrap_bits;
}
关于av_reduce函数可以参考:《FFmpeg源码:av_reduce函数分析》。avpriv_set_pts_info函数的核心就是通过调用av_reduce函数对有理数进行化简:
av_reduce(&new_tb.num, &new_tb.den, pts_num, pts_den, INT_MAX)