Finetuning options for ProRes and VP8 encoders to achieve reasonable

performance and quality. Added MultipleJpeg recording profile.
This commit is contained in:
brunoherbelin
2020-07-27 22:11:47 +02:00
parent c788187e3b
commit 5010ec85cd
4 changed files with 64 additions and 18 deletions

View File

@@ -122,7 +122,14 @@ void PNGRecorder::addFrame(FrameBuffer *frame_buffer, float)
} }
const char* VideoRecorder::profile_name[4] = { "H264 (low)", "H264 (high)", "Apple ProRes 4444", "WebM VP9" }; const char* VideoRecorder::profile_name[VideoRecorder::DEFAULT] = {
"H264 (Standard)",
"H264 (high)",
"Apple ProRes (Standard)",
"Apple ProRes (HQ 4444)",
"WebM VP8 (Standard)",
"Multiple JPEG"
};
const std::vector<std::string> VideoRecorder::profile_description { const std::vector<std::string> VideoRecorder::profile_description {
// Control x264 encoder quality : // Control x264 encoder quality :
// pass=4 // pass=4
@@ -138,18 +145,28 @@ const std::vector<std::string> VideoRecorder::profile_description {
"x264enc pass=4 quantizer=23 speed-preset=3 ! video/x-h264, profile=baseline ! h264parse ! ", "x264enc pass=4 quantizer=23 speed-preset=3 ! video/x-h264, profile=baseline ! h264parse ! ",
"x264enc pass=5 quantizer=18 speed-preset=4 ! video/x-h264, profile=high ! h264parse ! ", "x264enc pass=5 quantizer=18 speed-preset=4 ! video/x-h264, profile=high ! h264parse ! ",
// Apple ProRes encoding parameters // Apple ProRes encoding parameters
// pass=2 // pass
// cbr (0) Constant Bitrate Encoding // cbr (0) Constant Bitrate Encoding
// quant (2) Constant Quantizer // quant (2) Constant Quantizer
// pass1 (512) VBR Encoding - Pass 1 // pass1 (512) VBR Encoding - Pass 1
"avenc_prores bitrate=60000 pass=2 ! ", // profile
// WebM VP9 encoding parameters // 0 proxy
// https://www.webmproject.org/docs/encoder-parameters/ // 1 lt
// https://developers.google.com/media/vp9/settings/vod/ // 2 standard
"vp9enc end-usage=vbr end-usage=vbr cpu-used=3 max-quantizer=35 target-bitrate=200000 keyframe-max-dist=360 token-partitions=2 static-threshold=1000 ! " // 3 hq
// 4 4444
"avenc_prores_ks pass=2 profile=2 quantizer=25 ! ",
"avenc_prores_ks pass=2 profile=4 quantizer=8 ! ",
"vp8enc end-usage=vbr cpu-used=8 max-quantizer=35 deadline=100000 target-bitrate=200000 keyframe-max-dist=360 token-partitions=2 static-threshold=100 ! ",
"jpegenc ! "
}; };
// Too slow
//// WebM VP9 encoding parameters
//// https://www.webmproject.org/docs/encoder-parameters/
//// https://developers.google.com/media/vp9/settings/vod/
//"vp9enc end-usage=vbr end-usage=vbr cpu-used=3 max-quantizer=35 target-bitrate=200000 keyframe-max-dist=360 token-partitions=2 static-threshold=1000 ! "
// FAILED // FAILED
// x265 encoder quality // x265 encoder quality
// string description = "appsrc name=src ! videoconvert ! " // string description = "appsrc name=src ! videoconvert ! "
@@ -158,14 +175,8 @@ const std::vector<std::string> VideoRecorder::profile_description {
VideoRecorder::VideoRecorder() : Recorder(), frame_buffer_(nullptr), width_(0), height_(0), VideoRecorder::VideoRecorder() : Recorder(), frame_buffer_(nullptr), width_(0), height_(0),
recording_(false), accept_buffer_(false), pipeline_(nullptr), src_(nullptr), timeframe_(0), timestamp_(0) recording_(false), accept_buffer_(false), pipeline_(nullptr), src_(nullptr), timestamp_(0)
{ {
// auto filename
std::string path = SystemToolkit::path_directory(Settings::application.record.path);
if (path.empty())
path = SystemToolkit::home_path();
filename_ = path + SystemToolkit::date_time_string() + "_vimix.mov";
// configure fix parameter // configure fix parameter
frame_duration_ = gst_util_uint64_scale_int (1, GST_SECOND, 30); // 30 FPS frame_duration_ = gst_util_uint64_scale_int (1, GST_SECOND, 30); // 30 FPS
@@ -213,7 +224,27 @@ void VideoRecorder::addFrame (FrameBuffer *frame_buffer, float dt)
// create a gstreamer pipeline // create a gstreamer pipeline
string description = "appsrc name=src ! videoconvert ! "; string description = "appsrc name=src ! videoconvert ! ";
description += profile_description[Settings::application.record.profile]; description += profile_description[Settings::application.record.profile];
description += "qtmux ! filesink name=sink";
// verify location path (path is always terminated by the OS dependent separator)
std::string path = SystemToolkit::path_directory(Settings::application.record.path);
if (path.empty())
path = SystemToolkit::home_path();
// setup filename & muxer
if( Settings::application.record.profile == JPEG_MULTI) {
std::string folder = path + SystemToolkit::date_time_string() + "_vimix_jpg";
filename_ = SystemToolkit::full_filename(folder, "%05d.jpg");
if (SystemToolkit::create_directory(folder))
description += "multifilesink name=sink";
}
else if( Settings::application.record.profile == VP8) {
filename_ = path + SystemToolkit::date_time_string() + "_vimix.webm";
description += "webmmux ! filesink name=sink";
}
else {
filename_ = path + SystemToolkit::date_time_string() + "_vimix.mov";
description += "qtmux ! filesink name=sink";
}
// parse pipeline descriptor // parse pipeline descriptor
GError *error = NULL; GError *error = NULL;
@@ -389,6 +420,9 @@ void VideoRecorder::addFrame (FrameBuffer *frame_buffer, float dt)
finished_ = true; finished_ = true;
} }
} }
// if (timestamp_ > 10000000000)
// stop();
} }
void VideoRecorder::stop () void VideoRecorder::stop ()

View File

@@ -75,7 +75,16 @@ class VideoRecorder : public Recorder
public: public:
static const char* profile_name[4]; typedef enum {
H264_STANDARD = 0,
H264_HQ,
PRORES_STANDARD,
PRORES_HQ,
VP8,
JPEG_MULTI,
DEFAULT
} Profile;
static const char* profile_name[DEFAULT];
static const std::vector<std::string> profile_description; static const std::vector<std::string> profile_description;
VideoRecorder(); VideoRecorder();

View File

@@ -204,7 +204,7 @@ std::string SystemToolkit::username()
return string(user); return string(user);
} }
bool create_directory(const string& path) bool SystemToolkit::create_directory(const string& path)
{ {
return !mkdir(path.c_str(), 0755) || errno == EEXIST; return !mkdir(path.c_str(), 0755) || errno == EEXIST;

View File

@@ -54,6 +54,9 @@ namespace SystemToolkit
// true of file exists // true of file exists
bool file_exists(const std::string& path); bool file_exists(const std::string& path);
bool create_directory(const std::string& path);
// try to open the file with system // try to open the file with system
void open(const std::string& path); void open(const std::string& path);