Skip to content

Commit

Permalink
FrameRate Changes, Implement CFR and estimated buffer framerate (amme…
Browse files Browse the repository at this point in the history
…n99#190)

* allow fixed framerate encoders to work

* minor fix

* dont code while sleepy

* this should get put behind an if too

* 'r' to CFR, implement buffrate

this sets the framerate toggle to a propeer CFR, and implements buffrate for encoder hinting

buffrate is used to preserve VFR on encoders that require a framerate cap or target framerate (IE encoders without proper VFR support). it can also be used as a soft fps cap, but unless set at an integer value of the display, it may provide poor results

* fix woops

* Update manpage
  • Loading branch information
Quackdoc authored Jan 2, 2023
1 parent a40f9ad commit d982add
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 8 deletions.
1 change: 0 additions & 1 deletion config.h.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#define DEFAULT_CODEC "@default_codec@"
#define DEFAULT_FRAMERATE @default_framerate@
#define DEFAULT_AUDIO_CODEC "@default_audio_codec@"
#define DEFAULT_AUDIO_SAMPLE_RATE @default_audio_sample_rate@
#define DEFAULT_CONTAINER_FORMAT "@default_container_format@"
Expand Down
8 changes: 7 additions & 1 deletion manpage/wf-recorder.1
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
.Op Fl abcCdDefFghlmopPrRvxX
.Op Fl a, -audio Op Ar =DEVICE
.Op Fl b, -bframes Ar max_b_frames
.Op Fl B, -buffrate Ar buffrate
.Op Fl c, -codec Ar output_codec
.Op Fl r, -framerate Ar framerate
.Op Fl d, -device Ar encoding_device
Expand Down Expand Up @@ -61,6 +62,10 @@ You can find your device by running
.Pp
.It Fl b , -bframes Ar max_b_frames
Sets the maximum number of B-Frames to use.
.It Fl B , -buffrate Ar buffrate
Tells the encoder a prediction of what framerate to expect.
This preserves VFR and Solves FPS limit issue of some encoders (like svt-av1).
Should be set to the same framerate as display.
.Pp
.It Fl c , -codec Ar output_codec
Specifies the codec of the video. Supports GIF output as well.
Expand All @@ -69,7 +74,8 @@ To modify codec parameters, use
.Fl p Ar option_name=option_value
.Pp
.It Fl r , -framerate Ar framerate
Changes an approximation of the video framerate. The default is 60.
Sets hard constant framerate. Will duplicate frames to reach it.
This makes the resulting video CFR. Solves FPS limit issue of some encoders.
.Pp
.It Fl d , -device Ar encoding_device
Selects the device to use when encoding the video.
Expand Down
1 change: 0 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ project(
conf_data = configuration_data()

conf_data.set('default_codec', get_option('default_codec'))
conf_data.set('default_framerate', get_option('default_framerate'))
conf_data.set('default_audio_codec', get_option('default_audio_codec'))
conf_data.set('default_audio_sample_rate', get_option('default_audio_sample_rate'))
conf_data.set('default_container_format', get_option('default_container_format'))
Expand Down
1 change: 0 additions & 1 deletion meson_options.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
option('default_codec', type: 'string', value: 'libvpx', description: 'Codec that will be used by default')
option('default_framerate', type: 'integer', value: 60, description: 'Video framerate that will be used by default')
option('default_audio_codec', type: 'string', value: 'libvorbis', description: 'Audio codec that will be used by default')
option('default_audio_sample_rate', type: 'integer', value: 48000, description: 'Audio sample rate that will be used by default')
option('default_container_format', type: 'string', value: 'webm', description: 'Container file format that will be used by default')
Expand Down
14 changes: 14 additions & 0 deletions src/frame-writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,15 @@ void FrameWriter::init_video_filters(const AVCodec *codec)
}
}

if (params.framerate != 0){
if (params.video_filter != "null" && params.video_filter.find("fps") == std::string::npos) {
params.video_filter += ",fps=" + std::to_string(params.framerate);
}
else if (params.video_filter == "null"){
params.video_filter = "fps=" + std::to_string(params.framerate);
}
}

this->videoFilterGraph = avfilter_graph_alloc();
av_opt_set(videoFilterGraph, "scale_sws_opts", "flags=fast_bilinear:src_range=1:dst_range=1", 0);

Expand All @@ -195,6 +204,9 @@ void FrameWriter::init_video_filters(const AVCodec *codec)
buffer_filter_config << "video_size=" << params.width << "x" << params.height;
buffer_filter_config << ":pix_fmt=" << (int)this->get_input_format();
buffer_filter_config << ":time_base=" << US_RATIONAL.num << "/" << US_RATIONAL.den;
if (params.buffrate != 0) {
buffer_filter_config << ":frame_rate=" << params.buffrate;
}
buffer_filter_config << ":pixel_aspect=1/1";

int err = avfilter_graph_create_filter(&this->videoFilterSourceCtx, source,
Expand Down Expand Up @@ -330,7 +342,9 @@ void FrameWriter::init_video_stream()
videoCodecCtx->height = params.height;
videoCodecCtx->time_base = US_RATIONAL;
videoCodecCtx->color_range = AVCOL_RANGE_JPEG;
if (params.framerate) {
std::cout << "Framerate: " << params.framerate << std::endl;
}

if (params.bframes != -1)
videoCodecCtx->max_b_frames = params.bframes;
Expand Down
3 changes: 2 additions & 1 deletion src/frame-writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ struct FrameWriterParams
std::string hw_device; // used only if codec contains vaapi
std::map<std::string, std::string> codec_options;
std::map<std::string, std::string> audio_codec_options;
int framerate;
int framerate = 0;
int sample_rate;
int buffrate = 0;

int64_t audio_sync_offset;

Expand Down
13 changes: 10 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ Use Ctrl+C to stop.)");
ffmpeg -encoders
To modify codec parameters, use -p <option_name>=<option_value>
-r, --framerate Changes an approximation of the video framerate. The default is 60.
-r, --framerate Changes framerate to constant framerate with a given value.
-d, --device Selects the device to use when encoding the video
Some drivers report support for rgb0 data for vaapi input but
Expand Down Expand Up @@ -604,6 +604,9 @@ Use Ctrl+C to stop.)");
-b, --bframes This option is used to set the maximum number of b-frames to be used.
If b-frames are not supported by your hardware, set this to 0.
-B. --buffrate This option is used to specify the buffers expected framerate. this
may help when encoders are expecting specifc or limited framerate.
-C, --audio-codec Specifies the codec of the audio. These can be found by running:
ffmpeg -encoders
Expand Down Expand Up @@ -699,7 +702,6 @@ int main(int argc, char *argv[])
FrameWriterParams params = FrameWriterParams(exit_main_loop);
params.file = "recording." + std::string(DEFAULT_CONTAINER_FORMAT);
params.codec = DEFAULT_CODEC;
params.framerate = DEFAULT_FRAMERATE;
params.audio_codec = DEFAULT_AUDIO_CODEC;
params.sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
params.enable_ffmpeg_debug_output = false;
Expand Down Expand Up @@ -728,13 +730,14 @@ int main(int argc, char *argv[])
{ "audio", optional_argument, NULL, 'a' },
{ "help", no_argument, NULL, 'h' },
{ "bframes", required_argument, NULL, 'b' },
{ "buffrate", required_argument, NULL, 'B' },
{ "version", no_argument, NULL, 'v' },
{ "no-damage", no_argument, NULL, 'D' },
{ 0, 0, NULL, 0 }
};

int c, i;
while((c = getopt_long(argc, argv, "o:f:m:g:c:p:r:x:C:P:R:X:d:b:la::hvDF:", opts, &i)) != -1)
while((c = getopt_long(argc, argv, "o:f:m:g:c:p:r:x:C:P:R:X:d:b:B:la::hvDF:", opts, &i)) != -1)
{
switch(c)
{
Expand Down Expand Up @@ -790,6 +793,10 @@ int main(int argc, char *argv[])
params.bframes = atoi(optarg);
break;

case 'B':
params.buffrate = atoi(optarg);
break;

case 'l':
params.enable_ffmpeg_debug_output = true;
break;
Expand Down

0 comments on commit d982add

Please sign in to comment.