#include <iostream>
#include <thread>
#include <chrono>
#include <cstdio>

extern "C" {
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libavutil/time.h>
}

// Load the next packet from the input format context, return whether a packet was loaded
// If the end of file is reached, it will seek to the beginning to loop the input
char load_packet(AVFormatContext *inputFormatContext, AVPacket *pkt)
{
    if (av_read_frame(inputFormatContext, pkt) >= 0)
    {
        return 1;
    }

    // Seek to the beginning and try reading again
    av_seek_frame(inputFormatContext, -1, 0, AVSEEK_FLAG_BACKWARD);
    return av_read_frame(inputFormatContext, pkt) >= 0;
}

int main(int argc, char *argv[])
{
    if (argc != 4){
        std::cerr << "Usage: " << argv[0] <<"<input.mp4> <host> <port>"<< std::endl;
        return 1;
    }

    const char *inputFilename = argv[1];
    const char *host = argv[2];
    int port = std::stoi(argv[3]);

    av_register_all();
    avformat_network_init();

    AVFormatContext *inputFormatContext = nullptr;
    if (avformat_open_input(&inputFormatContext, inputFilename, nullptr, nullptr) < 0){
        std::cerr << "Could not open input file: " << inputFilename << std::endl;
        return 2;
    }

    if (avformat_find_stream_info(inputFormatContext, nullptr) < 0){
        std::cerr << "Could not find stream info" << std::endl;
        return 3;
    }

    av_dump_format(inputFormatContext, 0, inputFilename, 0);

    int videoStreamIndex = -1;
    int audioStreamIndex = -1;

    for (unsigned int i = 0; i < inputFormatContext->nb_streams; i++) {
        if (inputFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
        } else if (inputFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
            audioStreamIndex = i;
        }
    }

    if (videoStreamIndex == -1 || audioStreamIndex == -1){
        std::cerr << "Could not find video and/or audio stream" << std::endl;
        return 4;
    }

    // Set up output.
    AVFormatContext *outputFormatContext = nullptr;
    if (avformat_alloc_output_context2(&outputFormatContext, nullptr, "rtp_mpegts", nullptr) < 0){
        std::cerr << "Could not allocate output context" << std::endl;
        return 5;
    }

    for (int i = 0; i < inputFormatContext->nb_streams; i++){
        AVStream *inputStream = inputFormatContext->streams[i];
        AVStream *outputStream = avformat_new_stream(outputFormatContext, nullptr);
        if (!outputStream) {
            std::cerr << "Could not allocate stream" << std::endl;
            return 6;
        }

        avcodec_parameters_copy(outputStream->codecpar, inputStream->codecpar);
    }

    av_dump_format(outputFormatContext, 0, host, 1);

    AVDictionary *outputOptions = nullptr;
    av_dict_set_int(&outputOptions, "ttl", 64, 0);

    std::string outputUri = "rtp://" + std::string(host) + ":" + std::to_string(port);
    if (avio_open2(&outputFormatContext->pb, outputUri.c_str(), AVIO_FLAG_WRITE, nullptr, &outputOptions) < 0){
        std::cerr << "Could not open output" << std::endl;
        return 7;
    }

    if (avformat_write_header(outputFormatContext, nullptr) < 0){
        std::cerr <<"Could not write header"<< std::endl;
        return 8;
    }

    // Start streaming.
    AVPacket packet;
    av_init_packet(&packet);	
	
	// Assign the values of 3600 and 1024 to video and audio streams
	// based on the stream index, to properly calculate pts and dts.
	int pts_intervals[2] = {3600, 1024};
	int64_t lastPts[2] = {0, 0};
	int64_t lastDts[2] = {0, 0};
	int64_t videoLastDts = 0;
	int64_t audioLastDts = 0;

int64_t lastInputVideoPts = 0;
int64_t lastInputVideoDts = 0;

while (load_packet(inputFormatContext, &packet)) {
    int input_stream_index = packet.stream_index;
    int output_stream_index = input_stream_index == videoStreamIndex ? 0 : 1;
    int64_t *lastDtsForOutputStream = &lastDts[output_stream_index];
    AVRational input_time_base = inputFormatContext->streams[input_stream_index]->time_base;
    AVRational output_time_base = outputFormatContext->streams[input_stream_index]->time_base;

    if (input_stream_index == videoStreamIndex || input_stream_index == audioStreamIndex) {

        if (input_stream_index == videoStreamIndex) {
            // Adjust input video packet PTS and DTS
            if (packet.pts < packet.dts) {
                packet.pts = packet.dts;
            }

            if (packet.pts < lastInputVideoPts) {
                packet.pts = lastInputVideoPts;
            }

            if (packet.dts < lastInputVideoDts) {
                packet.dts = lastInputVideoDts;
            }

            lastInputVideoPts = packet.pts;
            lastInputVideoDts = packet.dts;
        }

        AVPacket outputPacket;
        av_init_packet(&outputPacket);
        av_packet_ref(&outputPacket, &packet);

        // Rewrite PTS and calculate new PTS and DTS
        outputPacket.pts = av_rescale_q_rnd(packet.pts, input_time_base, output_time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
        outputPacket.dts = av_rescale_q_rnd(packet.dts, input_time_base, output_time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));

        // Fix DTS increment if required
        if (outputPacket.dts <= *lastDtsForOutputStream) {
            outputPacket.dts = *lastDtsForOutputStream + 1;
            outputPacket.pts = std::max(outputPacket.pts, outputPacket.dts);
        }

        // Save the output DTS value
        *lastDtsForOutputStream = outputPacket.dts;

        av_write_frame(outputFormatContext, &outputPacket);
        av_packet_unref(&outputPacket);

        // Sleep for synchronization
        std::this_thread::sleep_until(std::chrono::system_clock::now() +
                                      std::chrono::duration<int64_t, std::micro>(
                                          av_rescale_q(outputPacket.pts, output_time_base, {1, 1000000})));
    }

    av_packet_unref(&packet);
}

    av_write_trailer(outputFormatContext);
    avio_closep(&outputFormatContext->pb);

    // Cleaning up.
    avformat_free_context(outputFormatContext);
    avformat_close_input(&inputFormatContext);

    return 0;
}


上面例子，仍然报错：[rtp @ 0x55751e3a4ac0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 19044870 >= 18994997，请继续修复
