mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Transcode: Support video codec such as h264_qsv and libx265. v6.0.145 (#4127)
Currently only libx264 ffmpeg encoder is supported. This pull request add also h264_qsv. But maybe a more generic solution with oder encoders would be useful to. --------- Co-authored-by: winlin <winlinvip@gmail.com>
This commit is contained in:
parent
65ad907fe4
commit
331ef9ffae
3 changed files with 53 additions and 48 deletions
|
@ -7,6 +7,7 @@ The changelog for SRS.
|
||||||
<a name="v6-changes"></a>
|
<a name="v6-changes"></a>
|
||||||
|
|
||||||
## SRS 6.0 Changelog
|
## SRS 6.0 Changelog
|
||||||
|
* v6.0, 2024-07-27, Merge [#4127](https://github.com/ossrs/srs/pull/4127): Transcode: Support video codec such as h264_qsv and libx265. v6.0.145 (#4127)
|
||||||
* v6.0, 2024-07-27, Merge [#4101](https://github.com/ossrs/srs/pull/4101): GB28181: Support external SIP server. v6.0.144 (#4101)
|
* v6.0, 2024-07-27, Merge [#4101](https://github.com/ossrs/srs/pull/4101): GB28181: Support external SIP server. v6.0.144 (#4101)
|
||||||
* v6.0, 2024-07-24, Merge [#4115](https://github.com/ossrs/srs/pull/4115): HLS: Add missing newline to end of session manifest. v6.0.143 (#4115)
|
* v6.0, 2024-07-24, Merge [#4115](https://github.com/ossrs/srs/pull/4115): HLS: Add missing newline to end of session manifest. v6.0.143 (#4115)
|
||||||
* v6.0, 2024-07-24, Merge [#4029](https://github.com/ossrs/srs/pull/4029): Player: Fix empty img tag occupy 20px size in safari. v6.0.142 (#4029)
|
* v6.0, 2024-07-24, Merge [#4029](https://github.com/ossrs/srs/pull/4029): Player: Fix empty img tag occupy 20px size in safari. v6.0.142 (#4029)
|
||||||
|
|
|
@ -33,8 +33,10 @@ using namespace std;
|
||||||
#define SRS_RTMP_ENCODER_COPY "copy"
|
#define SRS_RTMP_ENCODER_COPY "copy"
|
||||||
#define SRS_RTMP_ENCODER_NO_VIDEO "vn"
|
#define SRS_RTMP_ENCODER_NO_VIDEO "vn"
|
||||||
#define SRS_RTMP_ENCODER_NO_AUDIO "an"
|
#define SRS_RTMP_ENCODER_NO_AUDIO "an"
|
||||||
// only support libx264 encoder.
|
// only support libx264, libx265 and h264_qsv encoder.
|
||||||
#define SRS_RTMP_ENCODER_VCODEC_LIBX264 "libx264"
|
#define SRS_RTMP_ENCODER_VCODEC_LIBX264 "libx264"
|
||||||
|
#define SRS_RTMP_ENCODER_VCODEC_LIBX265 "libx265"
|
||||||
|
#define SRS_RTMP_ENCODER_VCODEC_H264QSV "h264_qsv"
|
||||||
#define SRS_RTMP_ENCODER_VCODEC_PNG "png"
|
#define SRS_RTMP_ENCODER_VCODEC_PNG "png"
|
||||||
// any aac encoder is ok which contains the aac,
|
// any aac encoder is ok which contains the aac,
|
||||||
// for example, libaacplus, aac, fdkaac
|
// for example, libaacplus, aac, fdkaac
|
||||||
|
@ -45,7 +47,7 @@ using namespace std;
|
||||||
SrsFFMPEG::SrsFFMPEG(std::string ffmpeg_bin)
|
SrsFFMPEG::SrsFFMPEG(std::string ffmpeg_bin)
|
||||||
{
|
{
|
||||||
ffmpeg = ffmpeg_bin;
|
ffmpeg = ffmpeg_bin;
|
||||||
|
|
||||||
vbitrate = 0;
|
vbitrate = 0;
|
||||||
vfps = 0;
|
vfps = 0;
|
||||||
vwidth = 0;
|
vwidth = 0;
|
||||||
|
@ -54,14 +56,14 @@ SrsFFMPEG::SrsFFMPEG(std::string ffmpeg_bin)
|
||||||
abitrate = 0;
|
abitrate = 0;
|
||||||
asample_rate = 0;
|
asample_rate = 0;
|
||||||
achannels = 0;
|
achannels = 0;
|
||||||
|
|
||||||
process = new SrsProcess();
|
process = new SrsProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsFFMPEG::~SrsFFMPEG()
|
SrsFFMPEG::~SrsFFMPEG()
|
||||||
{
|
{
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
srs_freep(process);
|
srs_freep(process);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,18 +85,18 @@ string SrsFFMPEG::output()
|
||||||
srs_error_t SrsFFMPEG::initialize(string in, string out, string log)
|
srs_error_t SrsFFMPEG::initialize(string in, string out, string log)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
input = in;
|
input = in;
|
||||||
_output = out;
|
_output = out;
|
||||||
log_file = log;
|
log_file = log;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsFFMPEG::initialize_transcode(SrsConfDirective* engine)
|
srs_error_t SrsFFMPEG::initialize_transcode(SrsConfDirective* engine)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
perfile = _srs_config->get_engine_perfile(engine);
|
perfile = _srs_config->get_engine_perfile(engine);
|
||||||
iformat = _srs_config->get_engine_iformat(engine);
|
iformat = _srs_config->get_engine_iformat(engine);
|
||||||
vfilter = _srs_config->get_engine_vfilter(engine);
|
vfilter = _srs_config->get_engine_vfilter(engine);
|
||||||
|
@ -113,18 +115,20 @@ srs_error_t SrsFFMPEG::initialize_transcode(SrsConfDirective* engine)
|
||||||
achannels = _srs_config->get_engine_achannels(engine);
|
achannels = _srs_config->get_engine_achannels(engine);
|
||||||
aparams = _srs_config->get_engine_aparams(engine);
|
aparams = _srs_config->get_engine_aparams(engine);
|
||||||
oformat = _srs_config->get_engine_oformat(engine);
|
oformat = _srs_config->get_engine_oformat(engine);
|
||||||
|
|
||||||
// ensure the size is even.
|
// ensure the size is even.
|
||||||
vwidth -= vwidth % 2;
|
vwidth -= vwidth % 2;
|
||||||
vheight -= vheight % 2;
|
vheight -= vheight % 2;
|
||||||
|
|
||||||
if (vcodec == SRS_RTMP_ENCODER_NO_VIDEO && acodec == SRS_RTMP_ENCODER_NO_AUDIO) {
|
if (vcodec == SRS_RTMP_ENCODER_NO_VIDEO && acodec == SRS_RTMP_ENCODER_NO_AUDIO) {
|
||||||
return srs_error_new(ERROR_ENCODER_VCODEC, "video and audio disabled");
|
return srs_error_new(ERROR_ENCODER_VCODEC, "video and audio disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vcodec != SRS_RTMP_ENCODER_COPY && vcodec != SRS_RTMP_ENCODER_NO_VIDEO && vcodec != SRS_RTMP_ENCODER_VCODEC_PNG) {
|
if (vcodec != SRS_RTMP_ENCODER_COPY && vcodec != SRS_RTMP_ENCODER_NO_VIDEO && vcodec != SRS_RTMP_ENCODER_VCODEC_PNG) {
|
||||||
if (vcodec != SRS_RTMP_ENCODER_VCODEC_LIBX264) {
|
if (vcodec != SRS_RTMP_ENCODER_VCODEC_LIBX264 && vcodec != SRS_RTMP_ENCODER_VCODEC_LIBX265 && vcodec != SRS_RTMP_ENCODER_VCODEC_H264QSV) {
|
||||||
return srs_error_new(ERROR_ENCODER_VCODEC, "invalid vcodec, must be %s, actual %s", SRS_RTMP_ENCODER_VCODEC_LIBX264, vcodec.c_str());
|
return srs_error_new(
|
||||||
|
ERROR_ENCODER_VCODEC, "invalid vcodec, must be %s, %s or %s, actual %s",
|
||||||
|
SRS_RTMP_ENCODER_VCODEC_LIBX264, SRS_RTMP_ENCODER_VCODEC_LIBX265, SRS_RTMP_ENCODER_VCODEC_H264QSV, vcodec.c_str());
|
||||||
}
|
}
|
||||||
if (vbitrate < 0) {
|
if (vbitrate < 0) {
|
||||||
return srs_error_new(ERROR_ENCODER_VBITRATE, "invalid vbitrate: %d", vbitrate);
|
return srs_error_new(ERROR_ENCODER_VBITRATE, "invalid vbitrate: %d", vbitrate);
|
||||||
|
@ -148,14 +152,14 @@ srs_error_t SrsFFMPEG::initialize_transcode(SrsConfDirective* engine)
|
||||||
return srs_error_new(ERROR_ENCODER_VPRESET, "invalid vpreset: %s", vpreset.c_str());
|
return srs_error_new(ERROR_ENCODER_VPRESET, "invalid vpreset: %s", vpreset.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @see, https://github.com/ossrs/srs/issues/145
|
// @see, https://github.com/ossrs/srs/issues/145
|
||||||
if (acodec == SRS_RTMP_ENCODER_LIBAACPLUS && acodec != SRS_RTMP_ENCODER_LIBFDKAAC) {
|
if (acodec == SRS_RTMP_ENCODER_LIBAACPLUS && acodec != SRS_RTMP_ENCODER_LIBFDKAAC) {
|
||||||
if (abitrate != 0 && (abitrate < 16 || abitrate > 72)) {
|
if (abitrate != 0 && (abitrate < 16 || abitrate > 72)) {
|
||||||
return srs_error_new(ERROR_ENCODER_ABITRATE, "invalid abitrate for aac: %d, must in [16, 72]", abitrate);
|
return srs_error_new(ERROR_ENCODER_ABITRATE, "invalid abitrate for aac: %d, must in [16, 72]", abitrate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (acodec != SRS_RTMP_ENCODER_COPY && acodec != SRS_RTMP_ENCODER_NO_AUDIO) {
|
if (acodec != SRS_RTMP_ENCODER_COPY && acodec != SRS_RTMP_ENCODER_NO_AUDIO) {
|
||||||
if (abitrate < 0) {
|
if (abitrate < 0) {
|
||||||
return srs_error_new(ERROR_ENCODER_ABITRATE, "invalid abitrate: %d", abitrate);
|
return srs_error_new(ERROR_ENCODER_ABITRATE, "invalid abitrate: %d", abitrate);
|
||||||
|
@ -170,47 +174,47 @@ srs_error_t SrsFFMPEG::initialize_transcode(SrsConfDirective* engine)
|
||||||
if (_output.empty()) {
|
if (_output.empty()) {
|
||||||
return srs_error_new(ERROR_ENCODER_OUTPUT, "invalid empty output");
|
return srs_error_new(ERROR_ENCODER_OUTPUT, "invalid empty output");
|
||||||
}
|
}
|
||||||
|
|
||||||
// for not rtmp input, donot append the iformat,
|
// for not rtmp input, donot append the iformat,
|
||||||
// for example, "-f flv" before "-i udp://192.168.1.252:2222"
|
// for example, "-f flv" before "-i udp://192.168.1.252:2222"
|
||||||
if (!srs_string_starts_with(input, "rtmp://")) {
|
if (!srs_string_starts_with(input, "rtmp://")) {
|
||||||
iformat = "";
|
iformat = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsFFMPEG::initialize_copy()
|
srs_error_t SrsFFMPEG::initialize_copy()
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
vcodec = SRS_RTMP_ENCODER_COPY;
|
vcodec = SRS_RTMP_ENCODER_COPY;
|
||||||
acodec = SRS_RTMP_ENCODER_COPY;
|
acodec = SRS_RTMP_ENCODER_COPY;
|
||||||
|
|
||||||
if (_output.empty()) {
|
if (_output.empty()) {
|
||||||
return srs_error_new(ERROR_ENCODER_OUTPUT, "invalid empty output");
|
return srs_error_new(ERROR_ENCODER_OUTPUT, "invalid empty output");
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsFFMPEG::start()
|
srs_error_t SrsFFMPEG::start()
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
if (process->started()) {
|
if (process->started()) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the argv for process.
|
// the argv for process.
|
||||||
params.clear();
|
params.clear();
|
||||||
|
|
||||||
// argv[0], set to ffmpeg bin.
|
// argv[0], set to ffmpeg bin.
|
||||||
// The execv() and execvp() functions ....
|
// The execv() and execvp() functions ....
|
||||||
// The first argument, by convention, should point to
|
// The first argument, by convention, should point to
|
||||||
// the filename associated with the file being executed.
|
// the filename associated with the file being executed.
|
||||||
params.push_back(ffmpeg);
|
params.push_back(ffmpeg);
|
||||||
|
|
||||||
// input params
|
// input params
|
||||||
for (int i = 0; i < (int)iparams.size(); i++) {
|
for (int i = 0; i < (int)iparams.size(); i++) {
|
||||||
string iparam = iparams.at(i);
|
string iparam = iparams.at(i);
|
||||||
|
@ -218,7 +222,7 @@ srs_error_t SrsFFMPEG::start()
|
||||||
params.push_back(iparam);
|
params.push_back(iparam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// build the perfile
|
// build the perfile
|
||||||
if (!perfile.empty()) {
|
if (!perfile.empty()) {
|
||||||
std::vector<std::string>::iterator it;
|
std::vector<std::string>::iterator it;
|
||||||
|
@ -229,16 +233,16 @@ srs_error_t SrsFFMPEG::start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// input.
|
// input.
|
||||||
if (iformat != "off" && !iformat.empty()) {
|
if (iformat != "off" && !iformat.empty()) {
|
||||||
params.push_back("-f");
|
params.push_back("-f");
|
||||||
params.push_back(iformat);
|
params.push_back(iformat);
|
||||||
}
|
}
|
||||||
|
|
||||||
params.push_back("-i");
|
params.push_back("-i");
|
||||||
params.push_back(input);
|
params.push_back(input);
|
||||||
|
|
||||||
// build the filter
|
// build the filter
|
||||||
if (!vfilter.empty()) {
|
if (!vfilter.empty()) {
|
||||||
std::vector<std::string>::iterator it;
|
std::vector<std::string>::iterator it;
|
||||||
|
@ -249,7 +253,7 @@ srs_error_t SrsFFMPEG::start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// video specified.
|
// video specified.
|
||||||
if (vcodec != SRS_RTMP_ENCODER_NO_VIDEO) {
|
if (vcodec != SRS_RTMP_ENCODER_NO_VIDEO) {
|
||||||
params.push_back("-vcodec");
|
params.push_back("-vcodec");
|
||||||
|
@ -257,45 +261,45 @@ srs_error_t SrsFFMPEG::start()
|
||||||
} else {
|
} else {
|
||||||
params.push_back("-vn");
|
params.push_back("-vn");
|
||||||
}
|
}
|
||||||
|
|
||||||
// the codec params is disabled when copy
|
// the codec params is disabled when copy
|
||||||
if (vcodec != SRS_RTMP_ENCODER_COPY && vcodec != SRS_RTMP_ENCODER_NO_VIDEO) {
|
if (vcodec != SRS_RTMP_ENCODER_COPY && vcodec != SRS_RTMP_ENCODER_NO_VIDEO) {
|
||||||
if (vbitrate > 0) {
|
if (vbitrate > 0) {
|
||||||
params.push_back("-b:v");
|
params.push_back("-b:v");
|
||||||
params.push_back(srs_int2str(vbitrate * 1000));
|
params.push_back(srs_int2str(vbitrate * 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vfps > 0) {
|
if (vfps > 0) {
|
||||||
params.push_back("-r");
|
params.push_back("-r");
|
||||||
params.push_back(srs_float2str(vfps));
|
params.push_back(srs_float2str(vfps));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vwidth > 0 && vheight > 0) {
|
if (vwidth > 0 && vheight > 0) {
|
||||||
params.push_back("-s");
|
params.push_back("-s");
|
||||||
params.push_back(srs_int2str(vwidth) + "x" + srs_int2str(vheight));
|
params.push_back(srs_int2str(vwidth) + "x" + srs_int2str(vheight));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add aspect if needed.
|
// TODO: add aspect if needed.
|
||||||
if (vwidth > 0 && vheight > 0) {
|
if (vwidth > 0 && vheight > 0) {
|
||||||
params.push_back("-aspect");
|
params.push_back("-aspect");
|
||||||
params.push_back(srs_int2str(vwidth) + ":" + srs_int2str(vheight));
|
params.push_back(srs_int2str(vwidth) + ":" + srs_int2str(vheight));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vthreads > 0) {
|
if (vthreads > 0) {
|
||||||
params.push_back("-threads");
|
params.push_back("-threads");
|
||||||
params.push_back(srs_int2str(vthreads));
|
params.push_back(srs_int2str(vthreads));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vprofile.empty()) {
|
if (!vprofile.empty()) {
|
||||||
params.push_back("-profile:v");
|
params.push_back("-profile:v");
|
||||||
params.push_back(vprofile);
|
params.push_back(vprofile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vpreset.empty()) {
|
if (!vpreset.empty()) {
|
||||||
params.push_back("-preset");
|
params.push_back("-preset");
|
||||||
params.push_back(vpreset);
|
params.push_back(vpreset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// vparams
|
// vparams
|
||||||
if (!vparams.empty()) {
|
if (!vparams.empty()) {
|
||||||
std::vector<std::string>::iterator it;
|
std::vector<std::string>::iterator it;
|
||||||
|
@ -307,7 +311,7 @@ srs_error_t SrsFFMPEG::start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// audio specified.
|
// audio specified.
|
||||||
if (acodec != SRS_RTMP_ENCODER_NO_AUDIO) {
|
if (acodec != SRS_RTMP_ENCODER_NO_AUDIO) {
|
||||||
params.push_back("-acodec");
|
params.push_back("-acodec");
|
||||||
|
@ -315,7 +319,7 @@ srs_error_t SrsFFMPEG::start()
|
||||||
} else {
|
} else {
|
||||||
params.push_back("-an");
|
params.push_back("-an");
|
||||||
}
|
}
|
||||||
|
|
||||||
// the codec params is disabled when copy
|
// the codec params is disabled when copy
|
||||||
if (acodec != SRS_RTMP_ENCODER_NO_AUDIO) {
|
if (acodec != SRS_RTMP_ENCODER_NO_AUDIO) {
|
||||||
if (acodec != SRS_RTMP_ENCODER_COPY) {
|
if (acodec != SRS_RTMP_ENCODER_COPY) {
|
||||||
|
@ -323,17 +327,17 @@ srs_error_t SrsFFMPEG::start()
|
||||||
params.push_back("-b:a");
|
params.push_back("-b:a");
|
||||||
params.push_back(srs_int2str(abitrate * 1000));
|
params.push_back(srs_int2str(abitrate * 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asample_rate > 0) {
|
if (asample_rate > 0) {
|
||||||
params.push_back("-ar");
|
params.push_back("-ar");
|
||||||
params.push_back(srs_int2str(asample_rate));
|
params.push_back(srs_int2str(asample_rate));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (achannels > 0) {
|
if (achannels > 0) {
|
||||||
params.push_back("-ac");
|
params.push_back("-ac");
|
||||||
params.push_back(srs_int2str(achannels));
|
params.push_back(srs_int2str(achannels));
|
||||||
}
|
}
|
||||||
|
|
||||||
// aparams
|
// aparams
|
||||||
std::vector<std::string>::iterator it;
|
std::vector<std::string>::iterator it;
|
||||||
for (it = aparams.begin(); it != aparams.end(); ++it) {
|
for (it = aparams.begin(); it != aparams.end(); ++it) {
|
||||||
|
@ -346,7 +350,7 @@ srs_error_t SrsFFMPEG::start()
|
||||||
// for audio copy.
|
// for audio copy.
|
||||||
for (int i = 0; i < (int)aparams.size();) {
|
for (int i = 0; i < (int)aparams.size();) {
|
||||||
std::string pn = aparams[i++];
|
std::string pn = aparams[i++];
|
||||||
|
|
||||||
// aparams, the adts to asc filter "-bsf:a aac_adtstoasc"
|
// aparams, the adts to asc filter "-bsf:a aac_adtstoasc"
|
||||||
if (pn == "-bsf:a" && i < (int)aparams.size()) {
|
if (pn == "-bsf:a" && i < (int)aparams.size()) {
|
||||||
std::string pv = aparams[i++];
|
std::string pv = aparams[i++];
|
||||||
|
@ -358,16 +362,16 @@ srs_error_t SrsFFMPEG::start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// output
|
// output
|
||||||
if (oformat != "off" && !oformat.empty()) {
|
if (oformat != "off" && !oformat.empty()) {
|
||||||
params.push_back("-f");
|
params.push_back("-f");
|
||||||
params.push_back(oformat);
|
params.push_back(oformat);
|
||||||
}
|
}
|
||||||
|
|
||||||
params.push_back("-y");
|
params.push_back("-y");
|
||||||
params.push_back(_output);
|
params.push_back(_output);
|
||||||
|
|
||||||
// when specified the log file.
|
// when specified the log file.
|
||||||
if (!log_file.empty()) {
|
if (!log_file.empty()) {
|
||||||
// stdout
|
// stdout
|
||||||
|
@ -379,12 +383,12 @@ srs_error_t SrsFFMPEG::start()
|
||||||
params.push_back(">");
|
params.push_back(">");
|
||||||
params.push_back(log_file);
|
params.push_back(log_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize the process.
|
// initialize the process.
|
||||||
if ((err = process->initialize(ffmpeg, params)) != srs_success) {
|
if ((err = process->initialize(ffmpeg, params)) != srs_success) {
|
||||||
return srs_error_wrap(err, "init process");
|
return srs_error_wrap(err, "init process");
|
||||||
}
|
}
|
||||||
|
|
||||||
return process->start();
|
return process->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
|
|
||||||
#define VERSION_MAJOR 6
|
#define VERSION_MAJOR 6
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 144
|
#define VERSION_REVISION 145
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue