diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 12365c0d..f8b13908 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,6 +22,7 @@ linux-builder: - make install - mv /usr/local/lib/python3.4/dist-packages/*openshot* install-x64/python - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" + - git log $(git describe --tags --abbrev=0)..HEAD --oneline --pretty=format:"%C(auto,yellow)%h%C(auto,magenta)% %C(auto,blue)%>(12,trunc)%ad %C(auto,green)%<(25,trunc)%aN%C(auto,reset)%s%C(auto,red)% gD% D" --date=short > "install-x64/share/$CI_PROJECT_NAME.log" when: always except: - tags @@ -48,6 +49,7 @@ mac-builder: - make install - mv /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/*openshot* install-x64/python - echo -e "CI_PROJECT_NAME:$CI_PROJECT_NAME\nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME\nCI_COMMIT_SHA:$CI_COMMIT_SHA\nCI_JOB_ID:$CI_JOB_ID" > "install-x64/share/$CI_PROJECT_NAME" + - git log $(git describe --tags --abbrev=0)..HEAD --oneline --pretty=format:"%C(auto,yellow)%h%C(auto,magenta)% %C(auto,blue)%>(12,trunc)%ad %C(auto,green)%<(25,trunc)%aN%C(auto,reset)%s%C(auto,red)% gD% D" --date=short > "install-x64/share/$CI_PROJECT_NAME.log" when: always except: - tags @@ -77,6 +79,8 @@ windows-builder-x86: - Move-Item -Force -path "C:\msys32\mingw32\lib\python3.6\site-packages\*openshot*" -destination "install-x86\python\" - cp src\libopenshot.dll install-x86\lib - New-Item -path "install-x86/share/" -Name "$CI_PROJECT_NAME" -Value "CI_PROJECT_NAME:$CI_PROJECT_NAME`nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME`nCI_COMMIT_SHA:$CI_COMMIT_SHA`nCI_JOB_ID:$CI_JOB_ID" -ItemType file -force + - $PREV_GIT_LABEL=(git describe --tags --abbrev=0) + - git log "$PREV_GIT_LABEL..HEAD" --oneline --pretty=format:"%C(auto,yellow)%h%C(auto,magenta)% %C(auto,blue)%>(12,trunc)%ad %C(auto,green)%<(25,trunc)%aN%C(auto,reset)%s%C(auto,red)% gD% D" --date=short > "install-x86/share/$CI_PROJECT_NAME.log" when: always except: - tags @@ -105,6 +109,8 @@ windows-builder-x64: - Move-Item -Force -path "C:\msys64\mingw64\lib\python3.6\site-packages\*openshot*" -destination "install-x64\python\" - cp src\libopenshot.dll install-x64\lib - New-Item -path "install-x64/share/" -Name "$CI_PROJECT_NAME" -Value "CI_PROJECT_NAME:$CI_PROJECT_NAME`nCI_COMMIT_REF_NAME:$CI_COMMIT_REF_NAME`nCI_COMMIT_SHA:$CI_COMMIT_SHA`nCI_JOB_ID:$CI_JOB_ID" -ItemType file -force + - $PREV_GIT_LABEL=(git describe --tags --abbrev=0) + - git log "$PREV_GIT_LABEL..HEAD" --oneline --pretty=format:"%C(auto,yellow)%h%C(auto,magenta)% %C(auto,blue)%>(12,trunc)%ad %C(auto,green)%<(25,trunc)%aN%C(auto,reset)%s%C(auto,red)% gD% D" --date=short > "install-x64/share/$CI_PROJECT_NAME.log" when: always except: - tags diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 778c352e..3ae1dd24 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -100,16 +100,24 @@ FFmpegWriter::FFmpegWriter(string path) : // Open the writer void FFmpegWriter::Open() { - // Open the writer - is_open = true; + if (!is_open) { + // Open the writer + is_open = true; - // Prepare streams (if needed) - if (!prepare_streams) - PrepareStreams(); + // Prepare streams (if needed) + if (!prepare_streams) + PrepareStreams(); - // Write header (if needed) - if (!write_header) - WriteHeader(); + // Now that all the parameters are set, we can open the audio and video codecs and allocate the necessary encode buffers + if (info.has_video && video_st) + open_video(oc, video_st); + if (info.has_audio && audio_st) + open_audio(oc, audio_st); + + // Write header (if needed) + if (!write_header) + WriteHeader(); + } } // auto detect format (from path) @@ -249,10 +257,8 @@ void FFmpegWriter::SetVideoOptions(bool has_video, string codec, Fraction fps, i } if (bit_rate >= 1000) // bit_rate is the bitrate in b/s info.video_bit_rate = bit_rate; - if ((bit_rate >= 0) && (bit_rate < 64) ) // bit_rate is the bitrate in b/s - info.video_bit_rate = bit_rate; - //else - // info.video_bit_rate = 0; + if ((bit_rate >= 0) && (bit_rate < 64) ) // bit_rate is the bitrate in crf + info.video_bit_rate = bit_rate; info.interlaced_frame = interlaced; info.top_field_first = top_field_first; @@ -390,45 +396,60 @@ void FFmpegWriter::SetOption(StreamType stream, string name, string value) // Buffer size convert >> c->rc_buffer_size; -/* else if (name == "crf") { + else if (name == "crf") { // encode quality and special settings like lossless // This might be better in an extra methods as more options // and way to set quality are possible - int tempi = stoi(value); #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101) switch (c->codec_id) { + #if (LIBAVCODEC_VERSION_MAJOR >= 58) + case AV_CODEC_ID_AV1 : + c->bit_rate = 0; + av_opt_set_int(c->priv_data, "crf", min(stoi(value),63), 0); + break; + #endif case AV_CODEC_ID_VP8 : - av_opt_set_int(c->priv_data, "crf", min(tempi,63), 0); + c->bit_rate = 10000000; + av_opt_set_int(c->priv_data, "crf", max(min(stoi(value),63),4), 0); // 4-63 break; case AV_CODEC_ID_VP9 : - av_opt_set_int(c->priv_data, "crf", min(tempi,63), 0); - if (tempi == 0) { + c->bit_rate = 0; // Must be zero! + av_opt_set_int(c->priv_data, "crf", min(stoi(value),63), 0); // 0-63 + if (stoi(value) == 0) { + av_opt_set(c->priv_data, "preset", "veryslow", 0); av_opt_set_int(c->priv_data, "lossless", 1, 0); - av_opt_set(c->priv_data, "preset", "veryslow", 0); } break; case AV_CODEC_ID_H264 : - av_opt_set_int(c->priv_data, "crf", min(tempi,51), 0); - if (tempi == 0) { - av_opt_set(c->priv_data, "preset", "veryslow", 0); - } + av_opt_set_int(c->priv_data, "crf", min(stoi(value),51), 0); // 0-51 + if (stoi(value) == 0) { + av_opt_set(c->priv_data, "preset", "veryslow", 0); + } break; case AV_CODEC_ID_H265 : - av_opt_set_int(c->priv_data, "crf", min(tempi,51), 0); - if (tempi == 0) { + av_opt_set_int(c->priv_data, "crf", min(stoi(value),51), 0); // 0-51 + if (stoi(value) == 0) { + av_opt_set(c->priv_data, "preset", "veryslow", 0); av_opt_set_int(c->priv_data, "lossless", 1, 0); - av_opt_set(c->priv_data, "preset", "veryslow", 0); - } + } break; - #ifdef AV_CODEC_ID_AV1 - case AV_CODEC_ID_AV1 : - av_opt_set_int(c->priv_data, "crf", min(tempi,63), 0); - break; - #endif + default: + // If this codec doesn't support crf calculate a bitrate + // TODO: find better formula + double mbs = 15000000.0; + if (info.video_bit_rate > 0) { + if (info.video_bit_rate > 42) { + mbs = 380000.0; + } + else { + mbs *= pow(0.912,info.video_bit_rate); + } + } + c->bit_rate = (int)(mbs); } #endif } -*/ + else // Set AVOption AV_OPTION_SET(st, c->priv_data, name.c_str(), value.c_str(), c); @@ -464,12 +485,6 @@ void FFmpegWriter::PrepareStreams() // Initialize the streams (i.e. add the streams) initialize_streams(); - // Now that all the parameters are set, we can open the audio and video codecs and allocate the necessary encode buffers - if (info.has_video && video_st) - open_video(oc, video_st); - if (info.has_audio && audio_st) - open_audio(oc, audio_st); - // Mark as 'prepared' prepare_streams = true; } @@ -1093,17 +1108,14 @@ AVStream* FFmpegWriter::add_video_stream() if (info.video_bit_rate >= 1000) { c->bit_rate = info.video_bit_rate; } -// else { -// c->bit_rate = 0; -// } #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101) else { -#if IS_FFMPEG_3_2 + #if IS_FFMPEG_3_2 if (hw_en_on) { double mbs = 15000000.0; if (info.video_bit_rate > 0) { if (info.video_bit_rate > 42) { - mbs = 380.0; + mbs = 380000.0; } else { mbs *= pow(0.912,info.video_bit_rate); @@ -1111,57 +1123,9 @@ AVStream* FFmpegWriter::add_video_stream() } c->bit_rate = (int)(mbs); } - else -#endif - { - switch (c->codec_id) { -#if (LIBAVCODEC_VERSION_MAJOR >= 58) - case AV_CODEC_ID_AV1 : - av_opt_set_int(c->priv_data, "crf", min(info.video_bit_rate,63), 0); - c->bit_rate = 0; - break; -#endif - case AV_CODEC_ID_VP8 : - av_opt_set_int(c->priv_data, "crf", min(info.video_bit_rate,63), 0); - c->bit_rate = 10000000; - if (info.video_bit_rate == 0) { - av_opt_set(c->priv_data, "preset", "veryslow", 0); - c->bit_rate = 30000000; - } - break; - case AV_CODEC_ID_VP9 : - av_opt_set_int(c->priv_data, "crf", min(info.video_bit_rate,63), 0); - c->bit_rate = 0; - if (info.video_bit_rate == 0) { - av_opt_set(c->priv_data, "preset", "veryslow", 0); - av_opt_set_int(c->priv_data, "lossless", 1, 0); - } - break; - case AV_CODEC_ID_H264 : - av_opt_set_int(c->priv_data, "crf", min(info.video_bit_rate,51), 0); - break; - case AV_CODEC_ID_H265 : - av_opt_set_int(c->priv_data, "crf", min(info.video_bit_rate,51), 0); - if (info.video_bit_rate == 0) { - av_opt_set(c->priv_data, "preset", "veryslow", 0); - av_opt_set_int(c->priv_data, "lossless", 1, 0); - } - break; - default: - double mbs = 15000000.0; - if (info.video_bit_rate > 0) { - if (info.video_bit_rate > 42) { - mbs = 380.0; - } - else { - mbs *= pow(0.912,info.video_bit_rate); - } - } - c->bit_rate = (int)(mbs); - } - } + #endif } -#endif + #endif //TODO: Implement variable bitrate feature (which actually works). This implementation throws //invalid bitrate errors and rc buffer underflow errors, etc...