Skip to content

Commit 2834e77

Browse files
authored
Merge pull request #445 from eisneinechse/develop
Newer codecs (svt_av1, rav1e, svt_hevc)
2 parents 1cdb49f + d9e6af5 commit 2834e77

File tree

1 file changed

+67
-4
lines changed

1 file changed

+67
-4
lines changed

src/FFmpegWriter.cpp

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ void FFmpegWriter::SetVideoOptions(bool has_video, std::string codec, Fraction f
255255
}
256256
if (bit_rate >= 1000) // bit_rate is the bitrate in b/s
257257
info.video_bit_rate = bit_rate;
258-
if ((bit_rate >= 0) && (bit_rate < 64)) // bit_rate is the bitrate in crf
258+
if ((bit_rate >= 0) && (bit_rate < 256)) // bit_rate is the bitrate in crf
259259
info.video_bit_rate = bit_rate;
260260

261261
info.interlaced_frame = interlaced;
@@ -358,7 +358,7 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va
358358
// Was option found?
359359
if (option || (name == "g" || name == "qmin" || name == "qmax" || name == "max_b_frames" || name == "mb_decision" ||
360360
name == "level" || name == "profile" || name == "slices" || name == "rc_min_rate" || name == "rc_max_rate" ||
361-
name == "rc_buffer_size" || name == "crf" || name == "cqp")) {
361+
name == "rc_buffer_size" || name == "crf" || name == "cqp" || name == "qp")) {
362362
// Check for specific named options
363363
if (name == "g")
364364
// Set gop_size
@@ -479,6 +479,15 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va
479479
case AV_CODEC_ID_AV1 :
480480
c->bit_rate = 0;
481481
av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0);
482+
if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) {
483+
av_opt_set_int(c->priv_data, "preset", 6, 0);
484+
av_opt_set_int(c->priv_data, "forced-idr",1,0);
485+
}
486+
if (strstr(info.vcodec.c_str(), "rav1e") != NULL) {
487+
av_opt_set_int(c->priv_data, "speed", 7, 0);
488+
av_opt_set_int(c->priv_data, "tile-rows", 2, 0);
489+
av_opt_set_int(c->priv_data, "tile-columns", 4, 0);
490+
}
482491
break;
483492
#endif
484493
case AV_CODEC_ID_VP8 :
@@ -500,7 +509,14 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va
500509
}
501510
break;
502511
case AV_CODEC_ID_HEVC :
503-
av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value), 51), 0); // 0-51
512+
if (strstr(info.vcodec.c_str(), "svt_hevc") != NULL) {
513+
av_opt_set_int(c->priv_data, "preset", 7, 0);
514+
av_opt_set_int(c->priv_data, "forced-idr",1,0);
515+
av_opt_set_int(c->priv_data, "qp",std::min(std::stoi(value), 51),0);
516+
}
517+
else {
518+
av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value), 51), 0); // 0-51
519+
}
504520
if (std::stoi(value) == 0) {
505521
av_opt_set(c->priv_data, "preset", "veryslow", 0);
506522
av_opt_set_int(c->priv_data, "lossless", 1, 0);
@@ -520,6 +536,48 @@ void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string va
520536
c->bit_rate = (int) (mbs);
521537
}
522538
}
539+
#endif
540+
} else if (name == "qp") {
541+
// encode quality and special settings like lossless
542+
// This might be better in an extra methods as more options
543+
// and way to set quality are possible
544+
#if (LIBAVCODEC_VERSION_MAJOR >= 58)
545+
switch (c->codec_id) {
546+
case AV_CODEC_ID_AV1 :
547+
c->bit_rate = 0;
548+
if (strstr(info.vcodec.c_str(), "svt_av1") != NULL) {
549+
av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0);
550+
av_opt_set_int(c->priv_data, "preset", 6, 0);
551+
av_opt_set_int(c->priv_data, "forced-idr",1,0);
552+
}
553+
else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) {
554+
// Set number of tiles to a fixed value
555+
// TODO Let user choose number of tiles
556+
av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),255), 0);
557+
av_opt_set_int(c->priv_data, "speed", 7, 0);
558+
av_opt_set_int(c->priv_data, "tile-rows", 2, 0); // number of rows
559+
av_opt_set_int(c->priv_data, "tile-columns", 4, 0); // number of columns
560+
}
561+
else if (strstr(info.vcodec.c_str(), "aom") != NULL) {
562+
// Set number of tiles to a fixed value
563+
// TODO Let user choose number of tiles
564+
// libaom doesn't have qp only crf
565+
av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0);
566+
av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows
567+
av_opt_set_int(c->priv_data, "tile-columns", 2, 0); // log2 of number of columns
568+
}
569+
else {
570+
av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0);
571+
}
572+
case AV_CODEC_ID_HEVC :
573+
c->bit_rate = 0;
574+
if (strstr(info.vcodec.c_str(), "svt_hevc") != NULL) {
575+
av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),51), 0);
576+
av_opt_set_int(c->priv_data, "preset", 7, 0);
577+
av_opt_set_int(c->priv_data, "forced-idr",1,0);
578+
}
579+
break;
580+
}
523581
#endif
524582
} else {
525583
// Set AVOption
@@ -801,6 +859,9 @@ void FFmpegWriter::flush_encoders() {
801859
#if (LIBAVFORMAT_VERSION_MAJOR < 58)
802860
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)
803861
return;
862+
#else
863+
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)
864+
return;
804865
#endif
805866

806867
int error_code = 0;
@@ -1969,10 +2030,13 @@ void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
19692030
bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
19702031
#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
19712032
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags", oc->oformat->flags);
2033+
2034+
if (AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) {
19722035
#else
19732036
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
19742037

19752038
if (oc->oformat->flags & AVFMT_RAWPICTURE) {
2039+
#endif
19762040
// Raw video case.
19772041
AVPacket pkt;
19782042
av_init_packet(&pkt);
@@ -1997,7 +2061,6 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *fra
19972061
AV_FREE_PACKET(&pkt);
19982062

19992063
} else
2000-
#endif
20012064
{
20022065

20032066
AVPacket pkt;

0 commit comments

Comments
 (0)