From c83f00e7bfd209ed7793ac92afc769d0a4b349bd Mon Sep 17 00:00:00 2001 From: Niellune Date: Thu, 12 Jun 2025 20:52:01 +0300 Subject: [PATCH] Options to control decoding codec --- settings.txt | 15 ++++++++++++++- src/decoder.cpp | 15 +++++++++++---- src/settings.h | 7 +++++++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/settings.txt b/settings.txt index fc46cd7..115cc06 100644 --- a/settings.txt +++ b/settings.txt @@ -90,6 +90,11 @@ # Enable vsync. This reduce tearing but can dramatically affect performance on low end systems #vsync = false +# Prefer HW decoding. +# If you have input lag that means that your hardware decoder can't work in streaming mode +# This is happening or Raspberry Pi Zero 2W. Disable this to use SW decoding for that case. +#hw-decode = true + # Corrects aspect of UI #aspect-correction = 1 @@ -153,4 +158,12 @@ # 2 - all commands except data streams # 3 - include outgoing commands # 4 - log everything -# protocol-debug = 0 \ No newline at end of file +# protocol-debug = 0 + +# Enable FFMPEG AV_CODEC_FLAG_LOW_DELAY for HW decoder. +# Force low delay. +#decode-low-delay = true + +# Enable FFMPEG AV_CODEC_FLAG2_FAST for HW decoder. +# Allow non spec compliant speedup tricks. +#decode-fast = false \ No newline at end of file diff --git a/src/decoder.cpp b/src/decoder.cpp index b846eb9..e0cb487 100644 --- a/src/decoder.cpp +++ b/src/decoder.cpp @@ -49,7 +49,7 @@ AVCodecContext *Decoder::load_codec(AVCodecID codec_id) AVCodecContext *result = nullptr; // Try hardware-accelerated decoders by iterating registered codecs - while ((codec = av_codec_iterate(&iter))) + while ((codec = av_codec_iterate(&iter)) && Settings::hwDecode) { if (!av_codec_is_decoder(codec) || codec->id != codec_id) continue; @@ -63,14 +63,21 @@ AVCodecContext *Decoder::load_codec(AVCodecID codec_id) break; } + if(Settings::codecLowDelay) + result->flags |= AV_CODEC_FLAG_LOW_DELAY; + if(Settings::codecFast) + result->flags2 |= AV_CODEC_FLAG2_FAST; + int ret = avcodec_open2(result, codec, nullptr); if (ret == 0) { std::cout << "[Video] Using HW decoder: " << codec->name << std::endl; + if (result->codec->capabilities & AV_CODEC_CAP_DELAY) + std::cout << "[Video] Codec has AV_CODEC_CAP_DELAY and can introduce lags, consider use SW decoding" << std::endl; return result; } - std::cout << "[Video] Can't load HW codec " << codec->name << ": " << avErrorText(ret) << std::endl; + std::cout << "[Video] Can't load HW decoder " << codec->name << ": " << avErrorText(ret) << std::endl; avcodec_free_context(&result); } @@ -78,7 +85,7 @@ AVCodecContext *Decoder::load_codec(AVCodecID codec_id) codec = avcodec_find_decoder(codec_id); if (!codec) { - std::cout << "[Video] Decoder not found for codec id " << codec_id << std::endl; + std::cout << "[Video] HW decoder not found for codec id " << codec_id << std::endl; return nullptr; } @@ -92,7 +99,7 @@ AVCodecContext *Decoder::load_codec(AVCodecID codec_id) int ret = avcodec_open2(result, codec, nullptr); if (ret < 0) { - std::cout << "[Video] Failed to open software decoder " << codec->name << ": " << avErrorText(ret) << std::endl; + std::cout << "[Video] Failed to open SW decoder " << codec->name << ": " << avErrorText(ret) << std::endl; avcodec_free_context(&result); return nullptr; } diff --git a/src/settings.h b/src/settings.h index 6ff27ac..1bf43a5 100644 --- a/src/settings.h +++ b/src/settings.h @@ -33,6 +33,7 @@ public: // Application configuration section static inline Setting fontSize{"font-size", 30}; static inline Setting vsync{"vsync", false}; + static inline Setting hwDecode{"hw-decode", true}; static inline Setting aspectCorrection{"aspect-correction", 1}; static inline Setting fastScale{"fast-render-scale", false}; static inline Setting videoQueue{"video-buffer-size", 32}; @@ -51,6 +52,12 @@ public: // Debug section static inline Setting protocolDebug{"protocol-debug", 0}; + static inline Setting codecLowDelay{"decode-low-delay", true}; + static inline Setting codecFast{"decode-fast", false}; + + + + static void load(const std::string &filename); static void print();