* @see av_d2q()
static
inline
double
av_q2d(AVRational a){
return
a.num / (
double
) a.den;
时间戳换算
比如计算视频的总时长:
AVFormatContext *ifmt_ctx = NULL;
avformat_open_input(&ifmt_ctx, filename, NULL, NULL);
double totle_seconds = ifmt_ctx->duration * av_q2d(AV_TIME_BASE_Q);
根据pts计算一帧在视频中对应的秒数位置:
double sec = enc_pkt.pts * av_q2d(ofmt_ctx->streams[stream_index]->time_base);
ffmpeg内部的时间戳与标准的时间转换方法
timestamp(ffmpeg内部时间戳) = AV_TIME_BASE * time(秒)
time(秒) = AV_TIME_BASE_Q * timestamp(ffmpeg内部时间戳)
当需要把视频跳转到N秒的时候:
int64_t timestamp = N * AV_TIME_BASE;
av_seek_frame(fmtctx, index_of_video, timestamp, AVSEEK_FLAG_BACKWARD);
时间基转换函数
另外,FFmpeg为我们提供了不同时间基之间的转换函数,把时间戳从一个时基调整到另外一个时基:
* 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;
dts/pts计算
dts: decoding time stamp (解码时间戳)
pts: present time stamp (显示时间戳)
转码流程中的
dts/pts
转换:
AVPacket packet;
av_read_frame(ifmt_ctx, &packet)
AVFrame *frame = NULL;
// 转换为解码器的时间戳
av_packet_rescale_ts(&packet,
ifmt_ctx->streams[stream_index]->time_base,
ifmt_ctx->streams[stream_index]->codec->time_base);
dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
avcodec_decode_audio4;
ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame,
&got_frame, &packet);
AVPacket enc_pkt;
int (*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) =
(ifmt_ctx->streams[stream_index]->codec->codec_type ==
AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2;
/* encode filtered frame */
enc_pkt.data = NULL;
enc_pkt.size = 0;
av_init_packet(&enc_pkt);
ret = enc_func(ofmt_ctx->streams[stream_index]->codec, &enc_pkt,
filt_frame, got_frame);
// 编码后的enc_pkt的时间戳以AVCodecContext->time_base为单位
// 编码器时间戳转为输出流AVStream时间戳
av_packet_rescale_ts(&enc_pkt,
ofmt_ctx->streams[stream_index]->codec->time_base,
ofmt_ctx->streams[stream_index]->time_base);
av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
http://blog.csdn.net/leixiaohua1020/article/details/28114081
http://www.cnblogs.com/yinxiangpei/articles/3892982.html
http://blog.csdn.net/TopsLuo/article/details/76239136
https://www.jianshu.com/p/bf323cee3b8e
http://blog.csdn.net/leixiaohua1020/article/details/15811977
本文出处:https://www.suninf.net/2018/02/ffmpeg-timestamps.html
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
如果觉得本博客对您有帮助,欢迎 赞赏作者