pixelflux 1.3.1__tar.gz → 1.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pixelflux might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pixelflux
3
- Version: 1.3.1
3
+ Version: 1.3.2
4
4
  Summary: A performant web native pixel delivery pipeline for diverse sources, blending VNC-inspired parallel processing of pixel buffers with flexible modern encoding formats.
5
5
  Home-page: https://github.com/linuxserver/pixelflux
6
6
  Author: Linuxserver.io
@@ -92,10 +92,12 @@ settings.jpeg_quality = 75 # Quality for changed stripes (0-100)
92
92
  settings.paint_over_jpeg_quality = 90 # Quality for static "paint-over" stripes (0-100)
93
93
 
94
94
  # --- H.264 Settings ---
95
- settings.h264_crf = 23 # CRF value (0-51, lower is better quality/higher bitrate)
96
- settings.h264_fullcolor = False # Use I444 (full color) instead of I420 for software encoding
97
- settings.h264_fullframe = True # Encode full frames (required for HW accel) instead of just changed stripes
98
- settings.h264_streaming_mode = False # Bypass all VNC logic and work like a normal video encoder, higher constant CPU usage for fullscreen gaming/videos
95
+ settings.h264_crf = 25 # CRF value (0-51, lower is better quality/higher bitrate)
96
+ settings.h264_paintover_crf = 18 # CRF for H.264 paintover on static content. Must be lower than h264_crf to activate.
97
+ settings.h264_paintover_burst_frames = 5 # Number of high-quality frames to send in a burst when a paintover is triggered.
98
+ settings.h264_fullcolor = False # Use I444 (full color) instead of I420 for software encoding
99
+ settings.h264_fullframe = True # Encode full frames (required for HW accel) instead of just changed stripes
100
+ settings.h264_streaming_mode = False # Bypass all VNC logic and work like a normal video encoder, higher constant CPU usage for fullscreen gaming/videos
99
101
 
100
102
  # --- Hardware Acceleration ---
101
103
  # Set to >= 0 to enable VA-API on a specific /dev/dri/renderD* node.
@@ -78,10 +78,12 @@ settings.jpeg_quality = 75 # Quality for changed stripes (0-100)
78
78
  settings.paint_over_jpeg_quality = 90 # Quality for static "paint-over" stripes (0-100)
79
79
 
80
80
  # --- H.264 Settings ---
81
- settings.h264_crf = 23 # CRF value (0-51, lower is better quality/higher bitrate)
82
- settings.h264_fullcolor = False # Use I444 (full color) instead of I420 for software encoding
83
- settings.h264_fullframe = True # Encode full frames (required for HW accel) instead of just changed stripes
84
- settings.h264_streaming_mode = False # Bypass all VNC logic and work like a normal video encoder, higher constant CPU usage for fullscreen gaming/videos
81
+ settings.h264_crf = 25 # CRF value (0-51, lower is better quality/higher bitrate)
82
+ settings.h264_paintover_crf = 18 # CRF for H.264 paintover on static content. Must be lower than h264_crf to activate.
83
+ settings.h264_paintover_burst_frames = 5 # Number of high-quality frames to send in a burst when a paintover is triggered.
84
+ settings.h264_fullcolor = False # Use I444 (full color) instead of I420 for software encoding
85
+ settings.h264_fullframe = True # Encode full frames (required for HW accel) instead of just changed stripes
86
+ settings.h264_streaming_mode = False # Bypass all VNC logic and work like a normal video encoder, higher constant CPU usage for fullscreen gaming/videos
85
87
 
86
88
  # --- Hardware Acceleration ---
87
89
  # Set to >= 0 to enable VA-API on a specific /dev/dri/renderD* node.
@@ -16,6 +16,8 @@ class CaptureSettings(ctypes.Structure):
16
16
  ("damage_block_duration", ctypes.c_int),
17
17
  ("output_mode", ctypes.c_int),
18
18
  ("h264_crf", ctypes.c_int),
19
+ ("h264_paintover_crf", ctypes.c_int),
20
+ ("h264_paintover_burst_frames", ctypes.c_int),
19
21
  ("h264_fullcolor", ctypes.c_bool),
20
22
  ("h264_fullframe", ctypes.c_bool),
21
23
  ("h264_streaming_mode", ctypes.c_bool),
@@ -288,12 +288,6 @@ enum class WatermarkLocation : int {
288
288
  NONE = 0, TL = 1, TR = 2, BL = 3, BR = 4, MI = 5, AN = 6
289
289
  };
290
290
 
291
- /**
292
- * @brief Defines static paintover settings for CPU encoding
293
- */
294
- const int H264_PAINTOVER_BURST_FRAMES = 3;
295
- const int H264_PAINTOVER_CRF = 18;
296
-
297
291
  /**
298
292
  * @brief Holds settings for screen capture and encoding.
299
293
  * This struct aggregates all configurable parameters for the capture process,
@@ -313,6 +307,8 @@ struct CaptureSettings {
313
307
  int damage_block_duration;
314
308
  OutputMode output_mode;
315
309
  int h264_crf;
310
+ int h264_paintover_crf;
311
+ int h264_paintover_burst_frames;
316
312
  bool h264_fullcolor;
317
313
  bool h264_fullframe;
318
314
  bool h264_streaming_mode;
@@ -340,6 +336,8 @@ struct CaptureSettings {
340
336
  damage_block_duration(30),
341
337
  output_mode(OutputMode::JPEG),
342
338
  h264_crf(25),
339
+ h264_paintover_crf(18),
340
+ h264_paintover_burst_frames(5),
343
341
  h264_fullcolor(false),
344
342
  h264_fullframe(false),
345
343
  h264_streaming_mode(false),
@@ -371,7 +369,7 @@ struct CaptureSettings {
371
369
  */
372
370
  CaptureSettings(int cw, int ch, int cx, int cy, double fps, int jq,
373
371
  int pojq, bool upoq, int potf, int dbt, int dbd,
374
- OutputMode om = OutputMode::JPEG, int crf = 25,
372
+ OutputMode om = OutputMode::JPEG, int crf = 25, int h264_po_crf = 18, int h264_po_burst = 5,
375
373
  bool h264_fc = false, bool h264_ff = false, bool h264_sm = false,
376
374
  bool capture_cursor = false,
377
375
  const char* wm_path = nullptr,
@@ -390,6 +388,8 @@ struct CaptureSettings {
390
388
  damage_block_duration(dbd),
391
389
  output_mode(om),
392
390
  h264_crf(crf),
391
+ h264_paintover_crf(h264_po_crf),
392
+ h264_paintover_burst_frames(h264_po_burst),
393
393
  h264_fullcolor(h264_fc),
394
394
  h264_fullframe(h264_ff),
395
395
  h264_streaming_mode(h264_sm),
@@ -708,6 +708,34 @@ bool initialize_nvenc_encoder(int width,
708
708
  return true;
709
709
  }
710
710
 
711
+ if (g_nvenc_state.initialized && g_nvenc_state.initialized_width == width &&
712
+ g_nvenc_state.initialized_height == height &&
713
+ g_nvenc_state.initialized_buffer_format == target_buffer_format) {
714
+
715
+ NV_ENC_RECONFIGURE_PARAMS reconfigure_params = {0};
716
+ NV_ENC_CONFIG new_config = g_nvenc_state.encode_config;
717
+
718
+ reconfigure_params.version = NV_ENC_RECONFIGURE_PARAMS_VER;
719
+ reconfigure_params.reInitEncodeParams = g_nvenc_state.init_params;
720
+ reconfigure_params.reInitEncodeParams.encodeConfig = &new_config;
721
+
722
+ new_config.rcParams.constQP.qpInterP = target_qp;
723
+ new_config.rcParams.constQP.qpIntra = target_qp;
724
+ new_config.rcParams.constQP.qpInterB = target_qp;
725
+
726
+ bool is_quality_increasing = (target_qp < g_nvenc_state.initialized_qp);
727
+ reconfigure_params.forceIDR = is_quality_increasing;
728
+
729
+ NVENCSTATUS status = g_nvenc_state.nvenc_funcs.nvEncReconfigureEncoder(
730
+ g_nvenc_state.encoder_session, &reconfigure_params);
731
+
732
+ if (status == NV_ENC_SUCCESS) {
733
+ g_nvenc_state.initialized_qp = target_qp;
734
+ g_nvenc_state.encode_config = new_config;
735
+ return true;
736
+ }
737
+ }
738
+
711
739
  if (g_nvenc_state.initialized) {
712
740
  g_nvenc_mutex.unlock();
713
741
  reset_nvenc_encoder();
@@ -1705,6 +1733,8 @@ public:
1705
1733
  int damage_block_threshold = 15;
1706
1734
  int damage_block_duration = 30;
1707
1735
  int h264_crf = 25;
1736
+ int h264_paintover_crf = 18;
1737
+ int h264_paintover_burst_frames = 5;
1708
1738
  bool h264_fullcolor = false;
1709
1739
  bool h264_fullframe = false;
1710
1740
  bool h264_streaming_mode = false;
@@ -1852,6 +1882,8 @@ public:
1852
1882
  damage_block_duration = new_settings.damage_block_duration;
1853
1883
  output_mode = new_settings.output_mode;
1854
1884
  h264_crf = new_settings.h264_crf;
1885
+ h264_paintover_crf = new_settings.h264_paintover_crf;
1886
+ h264_paintover_burst_frames = new_settings.h264_paintover_burst_frames;
1855
1887
  h264_fullcolor = new_settings.h264_fullcolor;
1856
1888
  h264_fullframe = new_settings.h264_fullframe;
1857
1889
  h264_streaming_mode = new_settings.h264_streaming_mode;
@@ -1883,6 +1915,7 @@ public:
1883
1915
  jpeg_quality, paint_over_jpeg_quality, use_paint_over_quality,
1884
1916
  paint_over_trigger_frames, damage_block_threshold,
1885
1917
  damage_block_duration, output_mode, h264_crf,
1918
+ h264_paintover_crf, h264_paintover_burst_frames,
1886
1919
  h264_fullcolor, h264_fullframe, h264_streaming_mode, capture_cursor,
1887
1920
  watermark_path_internal.c_str(), watermark_location_internal,
1888
1921
  vaapi_render_node_index, use_cpu
@@ -2009,6 +2042,8 @@ private:
2009
2042
  int local_current_damage_block_threshold;
2010
2043
  int local_current_damage_block_duration;
2011
2044
  int local_current_h264_crf;
2045
+ int local_current_h264_paintover_crf;
2046
+ int local_current_h264_paintover_burst_frames;
2012
2047
  bool local_current_h264_fullcolor;
2013
2048
  bool local_current_h264_fullframe;
2014
2049
  bool local_current_h264_streaming_mode;
@@ -2036,6 +2071,8 @@ private:
2036
2071
  local_current_damage_block_duration = damage_block_duration;
2037
2072
  local_current_output_mode = output_mode;
2038
2073
  local_current_h264_crf = h264_crf;
2074
+ local_current_h264_paintover_crf = h264_paintover_crf;
2075
+ local_current_h264_paintover_burst_frames = h264_paintover_burst_frames;
2039
2076
  local_current_h264_fullcolor = h264_fullcolor;
2040
2077
  local_current_h264_fullframe = h264_fullframe;
2041
2078
  local_current_h264_streaming_mode = h264_streaming_mode;
@@ -2112,6 +2149,25 @@ private:
2112
2149
  }
2113
2150
  Window root_window = DefaultRootWindow(display);
2114
2151
  int screen = DefaultScreen(display);
2152
+ XWindowAttributes attributes;
2153
+ if (XGetWindowAttributes(display, root_window, &attributes)) {
2154
+ if (local_capture_width_actual > attributes.width) {
2155
+ local_capture_width_actual = attributes.width;
2156
+ local_capture_x_offset = 0;
2157
+ }
2158
+ if (local_capture_height_actual > attributes.height) {
2159
+ local_capture_height_actual = attributes.height;
2160
+ local_capture_y_offset = 0;
2161
+ }
2162
+ if (local_capture_x_offset + local_capture_width_actual > attributes.width) {
2163
+ local_capture_x_offset = attributes.width - local_capture_width_actual;
2164
+ }
2165
+ if (local_capture_y_offset + local_capture_height_actual > attributes.height) {
2166
+ local_capture_y_offset = attributes.height - local_capture_height_actual;
2167
+ }
2168
+ if (local_capture_x_offset < 0) local_capture_x_offset = 0;
2169
+ if (local_capture_y_offset < 0) local_capture_y_offset = 0;
2170
+ }
2115
2171
 
2116
2172
  if (!XShmQueryExtension(display)) {
2117
2173
  std::cerr << "Error: X Shared Memory Extension not available!" << std::endl;
@@ -2276,6 +2332,8 @@ private:
2276
2332
  }
2277
2333
  local_current_output_mode = output_mode;
2278
2334
  local_current_h264_crf = h264_crf;
2335
+ local_current_h264_paintover_crf = h264_paintover_crf;
2336
+ local_current_h264_paintover_burst_frames = h264_paintover_burst_frames;
2279
2337
  local_current_h264_fullcolor = h264_fullcolor;
2280
2338
  local_current_h264_fullframe = h264_fullframe;
2281
2339
  local_current_h264_streaming_mode = h264_streaming_mode;
@@ -2757,7 +2815,7 @@ private:
2757
2815
  int crf_for_encode = local_current_h264_crf;
2758
2816
  if (local_current_output_mode == OutputMode::H264 && h264_paintover_burst_frames_remaining[i] > 0) {
2759
2817
  send_this_stripe = true;
2760
- crf_for_encode = H264_PAINTOVER_CRF;
2818
+ crf_for_encode = local_current_h264_paintover_crf;
2761
2819
  h264_paintover_burst_frames_remaining[i]--;
2762
2820
  current_hash = calculate_current_hash();
2763
2821
  hash_calculated_this_iteration = true;
@@ -2808,17 +2866,27 @@ private:
2808
2866
  consecutive_stripe_changes[i] = 0;
2809
2867
  no_motion_frame_counts[i]++;
2810
2868
  if (no_motion_frame_counts[i] >= local_current_paint_over_trigger_frames && !paint_over_sent[i]) {
2811
- if (local_current_output_mode == OutputMode::JPEG && local_current_use_paint_over_quality) {
2869
+ if (local_current_output_mode == OutputMode::JPEG &&
2870
+ local_current_use_paint_over_quality &&
2871
+ local_current_paint_over_jpeg_quality > local_current_jpeg_quality) {
2812
2872
  send_this_stripe = true;
2813
2873
  current_jpeg_qualities[i] = local_current_paint_over_jpeg_quality;
2814
2874
  paint_over_sent[i] = true;
2815
2875
  } else if (local_current_output_mode == OutputMode::H264) {
2816
- if (H264_PAINTOVER_CRF < local_current_h264_crf) {
2876
+ if (local_current_use_paint_over_quality && local_current_h264_paintover_crf < local_current_h264_crf) {
2817
2877
  send_this_stripe = true;
2818
- force_idr_for_paintover = true;
2819
- crf_for_encode = H264_PAINTOVER_CRF;
2820
- h264_paintover_burst_frames_remaining[i] = H264_PAINTOVER_BURST_FRAMES - 1;
2821
2878
  paint_over_sent[i] = true;
2879
+ if (this->nvenc_operational) {
2880
+ g_nvenc_force_next_idr_global = true;
2881
+ h264_paintover_burst_frames_remaining[i] = local_current_h264_paintover_burst_frames - 1;
2882
+ } else if (this->vaapi_operational) {
2883
+ g_vaapi_force_next_idr_global = true;
2884
+ h264_paintover_burst_frames_remaining[i] = 0;
2885
+ } else {
2886
+ force_idr_for_paintover = true;
2887
+ crf_for_encode = local_current_h264_paintover_crf;
2888
+ h264_paintover_burst_frames_remaining[i] = local_current_h264_paintover_burst_frames - 1;
2889
+ }
2822
2890
  }
2823
2891
  }
2824
2892
  }
@@ -2865,6 +2933,16 @@ private:
2865
2933
  futures.push_back(task.get_future());
2866
2934
  threads.push_back(std::thread(std::move(task)));
2867
2935
  } else if (this->nvenc_operational) {
2936
+ int target_qp_for_frame = crf_for_encode;
2937
+ if (local_current_use_paint_over_quality && g_nvenc_force_next_idr_global) {
2938
+ target_qp_for_frame = local_current_h264_paintover_crf;
2939
+ }
2940
+ if (!initialize_nvenc_encoder(local_capture_width_actual, local_capture_height_actual, target_qp_for_frame, local_current_target_fps, local_current_h264_fullcolor)) {
2941
+ std::cerr << "NVENC: Re-initialization for QP change failed. Disabling NVENC." << std::endl;
2942
+ this->nvenc_operational = false;
2943
+ reset_nvenc_encoder();
2944
+ continue;
2945
+ }
2868
2946
  std::packaged_task<StripeEncodeResult()> task([=]() {
2869
2947
  bool force_idr = g_nvenc_force_next_idr_global.exchange(false);
2870
2948
  return encode_fullframe_nvenc(
@@ -2877,7 +2955,7 @@ private:
2877
2955
  );
2878
2956
  });
2879
2957
  futures.push_back(task.get_future());
2880
- threads.push_back(std::thread(std::move(task)));
2958
+ threads.push_back(std::thread(std::move(task)));
2881
2959
  } else {
2882
2960
  if (force_idr_for_paintover) {
2883
2961
  std::lock_guard<std::mutex> lock(g_h264_minimal_store.store_mutex);
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pixelflux
3
- Version: 1.3.1
3
+ Version: 1.3.2
4
4
  Summary: A performant web native pixel delivery pipeline for diverse sources, blending VNC-inspired parallel processing of pixel buffers with flexible modern encoding formats.
5
5
  Home-page: https://github.com/linuxserver/pixelflux
6
6
  Author: Linuxserver.io
@@ -92,10 +92,12 @@ settings.jpeg_quality = 75 # Quality for changed stripes (0-100)
92
92
  settings.paint_over_jpeg_quality = 90 # Quality for static "paint-over" stripes (0-100)
93
93
 
94
94
  # --- H.264 Settings ---
95
- settings.h264_crf = 23 # CRF value (0-51, lower is better quality/higher bitrate)
96
- settings.h264_fullcolor = False # Use I444 (full color) instead of I420 for software encoding
97
- settings.h264_fullframe = True # Encode full frames (required for HW accel) instead of just changed stripes
98
- settings.h264_streaming_mode = False # Bypass all VNC logic and work like a normal video encoder, higher constant CPU usage for fullscreen gaming/videos
95
+ settings.h264_crf = 25 # CRF value (0-51, lower is better quality/higher bitrate)
96
+ settings.h264_paintover_crf = 18 # CRF for H.264 paintover on static content. Must be lower than h264_crf to activate.
97
+ settings.h264_paintover_burst_frames = 5 # Number of high-quality frames to send in a burst when a paintover is triggered.
98
+ settings.h264_fullcolor = False # Use I444 (full color) instead of I420 for software encoding
99
+ settings.h264_fullframe = True # Encode full frames (required for HW accel) instead of just changed stripes
100
+ settings.h264_streaming_mode = False # Bypass all VNC logic and work like a normal video encoder, higher constant CPU usage for fullscreen gaming/videos
99
101
 
100
102
  # --- Hardware Acceleration ---
101
103
  # Set to >= 0 to enable VA-API on a specific /dev/dri/renderD* node.
@@ -5,6 +5,10 @@ build-backend = "setuptools.build_meta"
5
5
  [tool.cibuildwheel]
6
6
  archs = [ "x86_64", "aarch64" ]
7
7
 
8
+ # Add this new section
9
+ [tool.cibuildwheel.environment]
10
+ LD_LIBRARY_PATH = "/usr/local/lib:/usr/local/lib64"
11
+
8
12
  [tool.cibuildwheel.linux]
9
13
  before-all = """
10
14
  set -euxo pipefail
@@ -15,7 +19,6 @@ before-all = """
15
19
  dnf install -y \
16
20
  libX11-devel \
17
21
  libXext-devel \
18
- libjpeg-turbo-devel \
19
22
  libev-devel \
20
23
  libXcomposite-devel \
21
24
  libva-devel \
@@ -46,6 +49,14 @@ before-all = """
46
49
  make install); \
47
50
  fi && \
48
51
  \
52
+ (cd /tmp && \
53
+ git clone --branch 3.1.1 --depth 1 https://github.com/libjpeg-turbo/libjpeg-turbo.git && \
54
+ cd libjpeg-turbo && \
55
+ mkdir build && cd build && \
56
+ cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release && \
57
+ make -j$(nproc) && \
58
+ make install) && \
59
+ \
49
60
  ldconfig
50
61
 
51
62
  elif command -v apk; then
@@ -53,7 +53,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
53
53
 
54
54
  setup(
55
55
  name="pixelflux",
56
- version="1.3.1",
56
+ version="1.3.2",
57
57
  author="Linuxserver.io",
58
58
  author_email="pypi@linuxserver.io",
59
59
  description="A performant web native pixel delivery pipeline for diverse sources, blending VNC-inspired parallel processing of pixel buffers with flexible modern encoding formats.",
File without changes
File without changes
File without changes