mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-21 15:20:00 +01:00
Finetuning options for ProRes and VP8 encoders to achieve reasonable
performance and quality. Added MultipleJpeg recording profile.
This commit is contained in:
66
Recorder.cpp
66
Recorder.cpp
@@ -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 ()
|
||||||
|
|||||||
11
Recorder.h
11
Recorder.h
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user