1、参考ffmpeg.c的get_input_packet来进行速度控制,当使用ffmpeg推流加上-re选项时,ffmpeg会使用此处进行流控;
直接上代码
void SetFirstDts(const AVMediaType type, const int64_t firstDts)
{
for (unsigned int i = 0; i < m_streamsContext.size(); i++) {
CheckStreamTsContext &streamCtx = m_streamsContext[i];
if (streamCtx.codecType == type) {
streamCtx.firstDts = av_rescale_q(firstDts, streamCtx.timebase, AV_TIME_BASE_Q);
TLOGI(m_e2eId.c_str(), "firstDts: %lld, type: %d", streamCtx.firstDts, type);
}
}
}
...
ret = av_read_frame(m_fmtContext, packet);
...
void CheckPktTs(AVPacket &pkt)
{
CheckStreamTsContext &streamCtx = m_streamsContext.at(pkt.stream_index);
AVRational avgFrameRate = streamCtx.avgFrameRate;
AVRational streamTimeBase = streamCtx.timebase;
if (streamCtx.codecType != AVMEDIA_TYPE_VIDEO &&
streamCtx.codecType != AVMEDIA_TYPE_AUDIO &&
streamCtx.codecType != AVMEDIA_TYPE_SUBTITLE) {
return;
}
if (!streamCtx.sawFirstTs) {
...
streamCtx.start = av_gettime_relative();
if (pkt.dts != AV_NOPTS_VALUE) {
streamCtx.firstDts = av_rescale_q(pkt.dts, streamTimeBase, AV_TIME_BASE_Q);
}
...
streamCtx.sawFirstTs = true;
}
...
int64_t pts = av_rescale(streamCtx.dts, 1000000, AV_TIME_BASE);
int64_t nowPts = pts - streamCtx.firstDts;
int64_t now = (av_gettime_relative() - streamCtx.start);
if (nowPts > now) {
int64_t sleepTime = nowPts - now;
av_usleep(sleepTime);
}
...
}