报错描述

ffmpeg进行rtmp推流、录制flv、MP4文件时报错: Application provided invalid, non monotonically increasing dts to muxer in stream x: xxx>= xxx 导致 av_interleaved_write_frame 或 av_write_frame 失败。 所以在av_write_frame 前对AVPacket进行检查。

// 代码片段
// 函数调用:av_read_frame  >  check_packet  >  av_interleaved_write_frame 

int64_t m_last_video_dts = AV_NOPTS_VALUE; 	// 上一帧的dts
int64_t m_last_audio_dts = AV_NOPTS_VALUE;  // 上一帧的dts
int64_t m_video_interframe_dts = AV_NOPTS_VALUE; // 视频帧与帧之间的dts增量

int check_packet(AVPacket* pkt)
{
    AVStream *in_stream = m_inputFormatContext->streams[pkt->stream_index];
    //处理 Application provided invalid, non monotonically increasing dts to muxer in stream
    // dts >= last_dts 时, 处理方法:
    // 1. 音频采取丢帧处理。
    // 2. 视频丢帧可能出现花屏; 重新计算视频帧的dts = m_last_video_dts + 帧间dts增量
    if (in_stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
        if (m_last_video_dts == AV_NOPTS_VALUE) {
            // 大华摄像机的第一帧视频 pts:-9223372036854775808,  dts:-9223372036854775808
            // 海康摄像机的第一帧视频 pts:21600,  dts:21600
            if ( pkt->dts != 0) {
                pkt->pts = pkt->dts = m_last_video_dts = 0;
            }
        }
        
        if (m_last_video_dts && m_last_video_dts >= pkt->dts) {
            if (m_video_interframe_dts == AV_NOPTS_VALUE) {
                //计算每帧dts的增量方式: 1 / 帧率 / 时间基
                AVRational r = {in_stream->avg_frame_rate.den, in_stream->avg_frame_rate.num};
                m_video_interframe_dts = av_rescale_q_rnd(1, r, in_stream->time_base,
                                static_cast<AVRounding>(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
               
            }
            pkt->pts = pkt->dts = m_last_video_dts = m_last_video_dts + m_video_interframe_dts;
        } else {
            m_last_video_dts = pkt->dts;
        }
    } else if (in_stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
        if (m_last_audio_dts && m_last_audio_dts >= pkt->dts) {
            return CHECK_PACKET_LOSS_FRAME;
        } else {
            m_last_audio_dts = pkt->dts;
        }
    } else {
        av_packet_unref(pkt);
        return CHECK_PACKET_LOSS_FRAME;
    }

    return CHECK_PACKET_OK;
}
Logo

一站式 AI 云服务平台

更多推荐