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);
}