#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 last_input_pts[2] = {0, 0};
int64_t last_input_dts[2] = {0, 0};
int64_t last_output_pts[2] = {0, 0};
int64_t last_output_dts[2] = {0, 0};

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

        packet.pts = std::max(packet.pts, last_input_pts[input_stream_index]);
        packet.dts = std::max(packet.dts, last_input_dts[input_stream_index]);

        last_input_pts[input_stream_index] = packet.pts;
        last_input_dts[input_stream_index] = packet.dts;

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

        int64_t new_pts = av_rescale_q(packet.pts, input_time_base, output_time_base);
        int64_t new_dts = av_rescale_q(packet.dts, input_time_base, output_time_base);

        new_pts = std::max(new_pts, last_output_pts[output_stream_index]);
        new_dts = std::max(new_dts, last_output_dts[output_stream_index]);

        outputPacket.pts = new_pts;
        outputPacket.dts = new_dts;

        last_output_pts[output_stream_index] = new_pts;
        last_output_dts[output_stream_index] = new_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(new_pts - last_output_pts[0], 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;
}

输入信息：ffprobe h264-aac-768x320.mp4 
ffprobe version 4.4.2 Copyright (c) 2007-2021 the FFmpeg developers
  built with gcc 11 (Ubuntu 11.2.0-19ubuntu1)
  configuration: --prefix=/home/zouyl/work/ffmpeg/ffmpeg-4.4.2/build --enable-shared --enable-gpl --enable-nonfree --enable-libopus --enable-libx264 --extra-cflags=-I/home/zouyl/work/ffmpeg/x264/build/include --extra-ldflags=-L/home/zouyl/work/ffmpeg/x264/build/lib --enable-libx265 --enable-libfdk-aac --enable-libvpx --enable-sdl2 --enable-ffplay
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
  libpostproc    55.  9.100 / 55.  9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'h264-aac-768x320.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.76.100
  Duration: 00:03:30.65, start: 0.000000, bitrate: 248 kb/s
  Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 768x320 [SAR 1:1 DAR 12:5], 212 kb/s, 25 fps, 25 tbr, 16k tbn, 50 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 30 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]，报错：[rtp_mpegts @ 0x55d4b1146080] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 18956539 >= 18956539
[rtp_mpegts @ 0x55d4b1146080] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 18943740 >= 18943740
[rtp_mpegts @ 0x55d4b1146080] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 18956539 >= 18956539
[rtp_mpegts @ 0x55d4b1146080] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 18956539 >= 18956539
[rtp_mpegts @ 0x55d4b1146080] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 18943740 >= 18943740
[rtp_mpegts @ 0x55d4b1146080] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 18956539 >= 18956539
[rtp_mpegts @ 0x55d4b1146080] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 18956539 >= 18956539
[rtp_mpegts @ 0x55d4b1146080] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 18943740 >= 18943740
[rtp_mpegts @ 0x55d4b1146080] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 18956539 >= 18956539
[rtp_mpegts @ 0x55d4b1146080] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 18943740 >= 18943740
[rtp_mpegts @ 0x55d4b1146080] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 18956539 >= 18956539，请修复