#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);
    int64_t lastDts[2] = {0, 0};

    while (load_packet(inputFormatContext, &packet)) {
        int input_stream_index = packet.stream_index;
        int64_t *lastDtsForStream = &lastDts[input_stream_index == videoStreamIndex ? 0 : 1];
        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) {
            AVPacket outputPacket;
            av_init_packet(&outputPacket);
            av_packet_ref(&outputPacket, &packet);

            av_packet_rescale_ts(&packet, input_time_base, output_time_base);

            // Make sure the output DTS is monotonically increasing
            if (packet.dts <= *lastDtsForStream) {
                packet.dts = *lastDtsForStream + 1;
                packet.pts = packet.dts; // Assume no B-frames
            }
            *lastDtsForStream = packet.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(packet.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;
}

上面例子：
要求：
1.请计算出h265 25 fps的pts,dts的间隔，我估算是3600，并以此来计算视频的Pts,dts
2.请计算出aac 44.1KHZ的pts,dts的间隔，我估算是1024，并以此来计算视频的Pts,dts