From f63c1e0a65c6d1031cd1a55e0dde1a75fd21830d Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Sun, 16 Feb 2020 10:00:18 -0800 Subject: [PATCH 1/7] Newer codecs --- src/FFmpegWriter.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 8d060d776..dec430d1e 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -255,7 +255,7 @@ void FFmpegWriter::SetVideoOptions(bool has_video, std::string codec, Fraction f } if (bit_rate >= 1000) // bit_rate is the bitrate in b/s info.video_bit_rate = bit_rate; - if ((bit_rate >= 0) && (bit_rate < 64)) // bit_rate is the bitrate in crf + if ((bit_rate >= 0) && (bit_rate < 256)) // bit_rate is the bitrate in crf info.video_bit_rate = bit_rate; info.interlaced_frame = interlaced; @@ -341,7 +341,7 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va // Was option found? if (option || (name == "g" || name == "qmin" || name == "qmax" || name == "max_b_frames" || name == "mb_decision" || name == "level" || name == "profile" || name == "slices" || name == "rc_min_rate" || name == "rc_max_rate" || - name == "rc_buffer_size" || name == "crf" || name == "cqp")) { + name == "rc_buffer_size" || name == "crf" || name == "cqp" || name == "qp")) { // Check for specific named options if (name == "g") // Set gop_size @@ -462,6 +462,18 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va case AV_CODEC_ID_AV1 : c->bit_rate = 0; av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); + if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { + //av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); + av_opt_set_int(c->priv_data, "preset", 6, 0); + av_opt_set_int(c->priv_data, "forced-idr",1,0); + } + if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { + //av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),255), 0); + av_opt_set_int(c->priv_data, "speed", 7, 0); + av_opt_set_int(c->priv_data, "tile-rows", 2, 0); + av_opt_set_int(c->priv_data, "tile-columns", 4, 0); + //av_opt_set(c->priv_data, "tile-row", "", 0); + } break; #endif case AV_CODEC_ID_VP8 : @@ -503,6 +515,36 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va c->bit_rate = (int) (mbs); } } +#endif + } else if (name == "qp") { + // encode quality and special settings like lossless + // This might be better in an extra methods as more options + // and way to set quality are possible +#if (LIBAVCODEC_VERSION_MAJOR >= 58) + switch (c->codec_id) { + case AV_CODEC_ID_AV1 : + c->bit_rate = 0; + av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); + if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { + av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); + av_opt_set_int(c->priv_data, "preset", 6, 0); + av_opt_set_int(c->priv_data, "forced-idr",1,0); + } + if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { + av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),255), 0); + av_opt_set_int(c->priv_data, "speed", 7, 0); + av_opt_set_int(c->priv_data, "tile-rows", 2, 0); + av_opt_set_int(c->priv_data, "tile-columns", 4, 0); + //av_opt_set(c->priv_data, "tile-row", "", 0); + } + if (strstr(info.vcodec.c_str(), "aom") != NULL) { + // Hack to set tiles; libaom doesn have qp only crf + av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); + av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows + av_opt_set_int(c->priv_data, "tile-columns", 2, 0); // log2 of number of columns + } + break; + } #endif } else { // Set AVOption From 6711c9c788eea07595b9627fb6e428f841dc557f Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Sun, 16 Feb 2020 19:16:45 -0800 Subject: [PATCH 2/7] Minor improvements --- src/FFmpegWriter.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index dec430d1e..b3a0b59c8 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -463,16 +463,13 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va c->bit_rate = 0; av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { - //av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); av_opt_set_int(c->priv_data, "preset", 6, 0); av_opt_set_int(c->priv_data, "forced-idr",1,0); } if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { - //av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),255), 0); av_opt_set_int(c->priv_data, "speed", 7, 0); av_opt_set_int(c->priv_data, "tile-rows", 2, 0); av_opt_set_int(c->priv_data, "tile-columns", 4, 0); - //av_opt_set(c->priv_data, "tile-row", "", 0); } break; #endif @@ -524,25 +521,30 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va switch (c->codec_id) { case AV_CODEC_ID_AV1 : c->bit_rate = 0; - av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) { av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); av_opt_set_int(c->priv_data, "preset", 6, 0); av_opt_set_int(c->priv_data, "forced-idr",1,0); } - if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { + else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) { + // Set number of tiles to a fixed value + // TODO Let user choose number of tiles av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),255), 0); av_opt_set_int(c->priv_data, "speed", 7, 0); - av_opt_set_int(c->priv_data, "tile-rows", 2, 0); - av_opt_set_int(c->priv_data, "tile-columns", 4, 0); - //av_opt_set(c->priv_data, "tile-row", "", 0); + av_opt_set_int(c->priv_data, "tile-rows", 2, 0); // number of rows + av_opt_set_int(c->priv_data, "tile-columns", 4, 0); // number of columns } - if (strstr(info.vcodec.c_str(), "aom") != NULL) { - // Hack to set tiles; libaom doesn have qp only crf + else if (strstr(info.vcodec.c_str(), "aom") != NULL) { + // Set number of tiles to a fixed value + // TODO Let user choose number of tiles + // libaom doesn't have qp only crf av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows av_opt_set_int(c->priv_data, "tile-columns", 2, 0); // log2 of number of columns } + else { + av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); + } break; } #endif From e03cd87373faf119057da3914af6dda1d06e9fa2 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Mon, 17 Feb 2020 10:56:00 -0800 Subject: [PATCH 3/7] Initial svt-hevc (h.265) encoder support added --- src/FFmpegWriter.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index b3a0b59c8..beb195342 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -492,7 +492,14 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va } break; case AV_CODEC_ID_HEVC : - av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value), 51), 0); // 0-51 + if (strstr(info.vcodec.c_str(), "svt_hevc") != NULL) { + av_opt_set_int(c->priv_data, "preset", 7, 0); + av_opt_set_int(c->priv_data, "forced-idr",1,0); + av_opt_set_int(c->priv_data, "qp",std::min(std::stoi(value), 51),0); + } + else { + av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value), 51), 0); // 0-51 + } if (std::stoi(value) == 0) { av_opt_set(c->priv_data, "preset", "veryslow", 0); av_opt_set_int(c->priv_data, "lossless", 1, 0); @@ -545,6 +552,13 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va else { av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0); } + case AV_CODEC_ID_HEVC : + c->bit_rate = 0; + if (strstr(info.vcodec.c_str(), "svt_hevc") != NULL) { + av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),51), 0); + av_opt_set_int(c->priv_data, "preset", 7, 0); + av_opt_set_int(c->priv_data, "forced-idr",1,0); + } break; } #endif From ddd52460e17f37d7078ee5ac4ae3335301c9ea86 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Sun, 1 Mar 2020 16:59:06 -0800 Subject: [PATCH 4/7] Fix handling of RAWIMAGE under ffmpeg 4 --- src/FFmpegWriter.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index beb195342..cc71e11a1 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -842,6 +842,9 @@ void FFmpegWriter::flush_encoders() { #if (LIBAVFORMAT_VERSION_MAJOR < 58) if (info.has_video && video_codec && AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && (oc->oformat->flags & AVFMT_RAWPICTURE) && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) return; +#else + if (info.has_video && video_codec && AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) + return; #endif int error_code = 0; @@ -1991,10 +1994,14 @@ void FFmpegWriter::process_video_packet(std::shared_ptr frame) { bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *frame_final) { #if (LIBAVFORMAT_VERSION_MAJOR >= 58) ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags", oc->oformat->flags); + + if (video_st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && + video_st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO) { #else ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE); if (oc->oformat->flags & AVFMT_RAWPICTURE) { +#endif // Raw video case. AVPacket pkt; av_init_packet(&pkt); @@ -2019,7 +2026,6 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra AV_FREE_PACKET(&pkt); } else -#endif { AVPacket pkt; From 6476f930bb601cebe7f8470776e7a4f836e46ca6 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Sun, 1 Mar 2020 17:10:39 -0800 Subject: [PATCH 5/7] Simplify fix for RAWVIDEO handling for ffmpeg 4+ --- src/FFmpegWriter.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index cc71e11a1..cc4b3d3a7 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1995,8 +1995,7 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr frame, AVFrame *fra #if (LIBAVFORMAT_VERSION_MAJOR >= 58) ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags", oc->oformat->flags); - if (video_st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && - video_st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO) { + if (AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) { #else ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE); From 93d12e7f14e8c4f002e5f98af14412b80a4cd53b Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Tue, 2 Jun 2020 08:53:39 -0700 Subject: [PATCH 6/7] Include data for fps in clip created by ffmpeg 4+ --- src/FFmpegWriter.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index cc4b3d3a7..e10b7026f 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1266,6 +1266,13 @@ AVStream *FFmpegWriter::add_video_stream() { st->avg_frame_rate = av_inv_q(c->time_base); st->time_base.num = info.video_timebase.num; st->time_base.den = info.video_timebase.den; +#if (LIBAVFORMAT_VERSION_MAJOR >= 58) + _Pragma ("GCC diagnostic push"); + _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\""); \ + st->codec->time_base.num = info.video_timebase.num; + st->codec->time_base.den = info.video_timebase.den; + _Pragma ("GCC diagnostic pop"); +#endif c->gop_size = 12; /* TODO: add this to "info"... emit one intra frame every twelve frames at most */ c->max_b_frames = 10; From d9e6af5cda54ad7d33569563d86653bcfc58a890 Mon Sep 17 00:00:00 2001 From: eisneinechse <42617957+eisneinechse@users.noreply.github.com> Date: Tue, 2 Jun 2020 11:35:07 -0700 Subject: [PATCH 7/7] Refert last commit --- src/FFmpegWriter.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index e10b7026f..cc4b3d3a7 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1266,13 +1266,6 @@ AVStream *FFmpegWriter::add_video_stream() { st->avg_frame_rate = av_inv_q(c->time_base); st->time_base.num = info.video_timebase.num; st->time_base.den = info.video_timebase.den; -#if (LIBAVFORMAT_VERSION_MAJOR >= 58) - _Pragma ("GCC diagnostic push"); - _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\""); \ - st->codec->time_base.num = info.video_timebase.num; - st->codec->time_base.den = info.video_timebase.den; - _Pragma ("GCC diagnostic pop"); -#endif c->gop_size = 12; /* TODO: add this to "info"... emit one intra frame every twelve frames at most */ c->max_b_frames = 10;