FFMPEG C++ Не правильно воспроизводит видео, записанное в файл

Я получаю с камеры ip видео наблюдения кадры по rtsp протоколу. И когда я записываю видео файл в HEVC кодеком, то у меня видео воспроизводится либо быстро или медленно. Это из за того что я не могу правильно установить pts / dts. А потому нужна мне помощь в виде разъяснения что я делаю не так.

while (true) {
    std::cout << "Текущая (целевая) частота кадров: " << framesPerSecond << " FPS\n";
    auto start = std::chrono::high_resolution_clock::now();
    if (av_read_frame(formatContext, packet) >= 0) {
        if (packet->stream_index == videoStreamIndex) {
        ;
            if (avcodec_send_packet(codecContext, packet) >= 0) {
                while (avcodec_receive_frame(codecContext, frame) >= 0) {
                    if (first) {
                        first = false;
                        AVDictionaryEntry* rotation_entry = av_dict_get(frame->metadata, "rotate", NULL, 0);
                        if (rotation_entry) {
                            int rotate_method = atoi(rotation_entry->value);
                            switch (rotate_method) {
                            case 90:
                                av_dict_set_int(&outputStream->metadata, "rotate", 90, 0);
                                break;
                            case 180:
                                av_dict_set_int(&outputStream->metadata, "rotate", 180, 0);
                                break;
                            case 270:
                                av_dict_set_int(&outputStream->metadata, "rotate", 270, 0);
                                break;
                            }
                        }
                    }

                    // Если ПК выключается, нужно немедленно сохранить видео. 
                    if (EXIT_APP == true) {
                        av_write_trailer(outputFmtContext);
                        if (outputFmtContext && !(outputFmtContext->oformat->flags & AVFMT_NOFILE)) {
                            avio_closep(&outputFmtContext->pb);
                        }

                        av_frame_free(&frame);
                        av_packet_free(&packet);
                        avcodec_free_context(&codecContext);
                        avcodec_free_context(&outputCodecContext);
                        avformat_close_input(&formatContext);
                        avformat_free_context(outputFmtContext);
                        // Затем можно выйти из программы
                        Beep(1000, 1000);
                        PostQuitMessage(0);
                        return 0;
                    }

                    time_t currentTime = time(0); // Снова получаем текущее время

                    if (currentTime - startTime1 > durationSeconds) {
                        // Завершаем запись по времени.


                        av_write_trailer(outputFmtContext);

                        if (outputFmtContext && !(outputFmtContext->oformat->flags & AVFMT_NOFILE)) {
                            avio_closep(&outputFmtContext->pb);
                        }

                        av_frame_free(&frame);
                        av_packet_free(&packet);
                        avcodec_free_context(&codecContext);
                        avcodec_free_context(&outputCodecContext);
                        avformat_close_input(&formatContext);
                        avformat_free_context(outputFmtContext);

                        return 0;

                    }
        


                    AVPacket* outputPacket = av_packet_alloc();
                    avcodec_send_frame(outputCodecContext, frame);

                
                    AVRounding rounding = static_cast<AVRounding>(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);

                


                    while (avcodec_receive_packet(outputCodecContext, outputPacket) >= 0) {

                        // Установки времени для видеофайла.                
                        outputPacket->pts = av_rescale_q_rnd(outputPacket->pts, formatContext->streams[videoStreamIndex]->time_base, outputStream->time_base, rounding);
                        outputPacket->dts = av_rescale_q_rnd(outputPacket->dts, formatContext->streams[videoStreamIndex]->time_base, outputStream->time_base, rounding);
                        outputPacket->duration = av_rescale_q(outputPacket->duration, formatContext->streams[videoStreamIndex]->time_base, outputStream->time_base);

                        outputPacket->stream_index = outputStream->index;

                        //------------------------------------------------------------------------------
                        if (av_interleaved_write_frame(outputFmtContext, outputPacket) < 0) {
                            handleFFmpegError(AVERROR(ENOMEM));
                        }

                        av_packet_unref(outputPacket);
                    }
                    //av_packet_unref(outputPacket);
                }
            }
        }
    }
    auto end = std::chrono::high_resolution_clock::now();
    auto duration1 = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

    // Если обработка кадра заняла меньше времени, чем ожидаемый интервал, подождем оставшееся время
    if (duration1 < std::chrono::milliseconds(static_cast<int>(std::round(expectedInterval)))) {
        std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int>(std::round(expectedInterval))) - duration1);
    }
    av_packet_unref(packet);
}

Ответы (0 шт):