pixelflux 1.3.1__tar.gz → 1.3.3__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.
- {pixelflux-1.3.1/pixelflux.egg-info → pixelflux-1.3.3}/PKG-INFO +10 -5
- {pixelflux-1.3.1 → pixelflux-1.3.3}/README.md +9 -4
- {pixelflux-1.3.1 → pixelflux-1.3.3}/pixelflux/__init__.py +3 -0
- {pixelflux-1.3.1 → pixelflux-1.3.3}/pixelflux/screen_capture_module.cpp +165 -19
- {pixelflux-1.3.1 → pixelflux-1.3.3/pixelflux.egg-info}/PKG-INFO +10 -5
- {pixelflux-1.3.1 → pixelflux-1.3.3}/pyproject.toml +12 -1
- {pixelflux-1.3.1 → pixelflux-1.3.3}/setup.py +1 -1
- {pixelflux-1.3.1 → pixelflux-1.3.3}/LICENSE +0 -0
- {pixelflux-1.3.1 → pixelflux-1.3.3}/MANIFEST.in +0 -0
- {pixelflux-1.3.1 → pixelflux-1.3.3}/pixelflux/__pycache__/__init__.cpython-311.pyc +0 -0
- {pixelflux-1.3.1 → pixelflux-1.3.3}/pixelflux/include/cuda.h +0 -0
- {pixelflux-1.3.1 → pixelflux-1.3.3}/pixelflux/include/nvEncodeAPI.h +0 -0
- {pixelflux-1.3.1 → pixelflux-1.3.3}/pixelflux/include/stb_image.h +0 -0
- {pixelflux-1.3.1 → pixelflux-1.3.3}/pixelflux/include/xxhash.c +0 -0
- {pixelflux-1.3.1 → pixelflux-1.3.3}/pixelflux/include/xxhash.h +0 -0
- {pixelflux-1.3.1 → pixelflux-1.3.3}/pixelflux.egg-info/SOURCES.txt +0 -0
- {pixelflux-1.3.1 → pixelflux-1.3.3}/pixelflux.egg-info/dependency_links.txt +0 -0
- {pixelflux-1.3.1 → pixelflux-1.3.3}/pixelflux.egg-info/top_level.txt +0 -0
- {pixelflux-1.3.1 → pixelflux-1.3.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pixelflux
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.3
|
|
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
|
|
@@ -87,15 +87,20 @@ settings.output_mode = 1
|
|
|
87
87
|
# Force CPU encoding and ignore hardware encoders
|
|
88
88
|
capture_settings.use_cpu = False
|
|
89
89
|
|
|
90
|
+
# --- Debugging ---
|
|
91
|
+
settings.debug_logging = False # Enable/disable the continuous FPS and settings log to the console.
|
|
92
|
+
|
|
90
93
|
# --- JPEG Settings ---
|
|
91
94
|
settings.jpeg_quality = 75 # Quality for changed stripes (0-100)
|
|
92
95
|
settings.paint_over_jpeg_quality = 90 # Quality for static "paint-over" stripes (0-100)
|
|
93
96
|
|
|
94
97
|
# --- H.264 Settings ---
|
|
95
|
-
settings.h264_crf =
|
|
96
|
-
settings.
|
|
97
|
-
settings.
|
|
98
|
-
settings.
|
|
98
|
+
settings.h264_crf = 25 # CRF value (0-51, lower is better quality/higher bitrate)
|
|
99
|
+
settings.h264_paintover_crf = 18 # CRF for H.264 paintover on static content. Must be lower than h264_crf to activate.
|
|
100
|
+
settings.h264_paintover_burst_frames = 5 # Number of high-quality frames to send in a burst when a paintover is triggered.
|
|
101
|
+
settings.h264_fullcolor = False # Use I444 (full color) instead of I420 for software encoding
|
|
102
|
+
settings.h264_fullframe = True # Encode full frames (required for HW accel) instead of just changed stripes
|
|
103
|
+
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
104
|
|
|
100
105
|
# --- Hardware Acceleration ---
|
|
101
106
|
# Set to >= 0 to enable VA-API on a specific /dev/dri/renderD* node.
|
|
@@ -73,15 +73,20 @@ settings.output_mode = 1
|
|
|
73
73
|
# Force CPU encoding and ignore hardware encoders
|
|
74
74
|
capture_settings.use_cpu = False
|
|
75
75
|
|
|
76
|
+
# --- Debugging ---
|
|
77
|
+
settings.debug_logging = False # Enable/disable the continuous FPS and settings log to the console.
|
|
78
|
+
|
|
76
79
|
# --- JPEG Settings ---
|
|
77
80
|
settings.jpeg_quality = 75 # Quality for changed stripes (0-100)
|
|
78
81
|
settings.paint_over_jpeg_quality = 90 # Quality for static "paint-over" stripes (0-100)
|
|
79
82
|
|
|
80
83
|
# --- H.264 Settings ---
|
|
81
|
-
settings.h264_crf =
|
|
82
|
-
settings.
|
|
83
|
-
settings.
|
|
84
|
-
settings.
|
|
84
|
+
settings.h264_crf = 25 # CRF value (0-51, lower is better quality/higher bitrate)
|
|
85
|
+
settings.h264_paintover_crf = 18 # CRF for H.264 paintover on static content. Must be lower than h264_crf to activate.
|
|
86
|
+
settings.h264_paintover_burst_frames = 5 # Number of high-quality frames to send in a burst when a paintover is triggered.
|
|
87
|
+
settings.h264_fullcolor = False # Use I444 (full color) instead of I420 for software encoding
|
|
88
|
+
settings.h264_fullframe = True # Encode full frames (required for HW accel) instead of just changed stripes
|
|
89
|
+
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
90
|
|
|
86
91
|
# --- Hardware Acceleration ---
|
|
87
92
|
# 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),
|
|
@@ -24,6 +26,7 @@ class CaptureSettings(ctypes.Structure):
|
|
|
24
26
|
("watermark_location_enum", ctypes.c_int),
|
|
25
27
|
("vaapi_render_node_index", ctypes.c_int),
|
|
26
28
|
("use_cpu", ctypes.c_bool),
|
|
29
|
+
("debug_logging", ctypes.c_bool),
|
|
27
30
|
]
|
|
28
31
|
|
|
29
32
|
WATERMARK_LOCATION_NONE = 0
|
|
@@ -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;
|
|
@@ -321,6 +317,7 @@ struct CaptureSettings {
|
|
|
321
317
|
WatermarkLocation watermark_location_enum;
|
|
322
318
|
int vaapi_render_node_index;
|
|
323
319
|
bool use_cpu;
|
|
320
|
+
bool debug_logging;
|
|
324
321
|
|
|
325
322
|
/**
|
|
326
323
|
* @brief Default constructor for CaptureSettings.
|
|
@@ -340,6 +337,8 @@ struct CaptureSettings {
|
|
|
340
337
|
damage_block_duration(30),
|
|
341
338
|
output_mode(OutputMode::JPEG),
|
|
342
339
|
h264_crf(25),
|
|
340
|
+
h264_paintover_crf(18),
|
|
341
|
+
h264_paintover_burst_frames(5),
|
|
343
342
|
h264_fullcolor(false),
|
|
344
343
|
h264_fullframe(false),
|
|
345
344
|
h264_streaming_mode(false),
|
|
@@ -347,7 +346,8 @@ struct CaptureSettings {
|
|
|
347
346
|
watermark_path(nullptr),
|
|
348
347
|
watermark_location_enum(WatermarkLocation::NONE),
|
|
349
348
|
vaapi_render_node_index(-1),
|
|
350
|
-
use_cpu(false)
|
|
349
|
+
use_cpu(false),
|
|
350
|
+
debug_logging(false) {}
|
|
351
351
|
|
|
352
352
|
/**
|
|
353
353
|
* @brief Parameterized constructor for CaptureSettings.
|
|
@@ -371,12 +371,12 @@ struct CaptureSettings {
|
|
|
371
371
|
*/
|
|
372
372
|
CaptureSettings(int cw, int ch, int cx, int cy, double fps, int jq,
|
|
373
373
|
int pojq, bool upoq, int potf, int dbt, int dbd,
|
|
374
|
-
OutputMode om = OutputMode::JPEG, int crf = 25,
|
|
374
|
+
OutputMode om = OutputMode::JPEG, int crf = 25, int h264_po_crf = 18, int h264_po_burst = 5,
|
|
375
375
|
bool h264_fc = false, bool h264_ff = false, bool h264_sm = false,
|
|
376
376
|
bool capture_cursor = false,
|
|
377
377
|
const char* wm_path = nullptr,
|
|
378
378
|
WatermarkLocation wm_loc = WatermarkLocation::NONE,
|
|
379
|
-
int vaapi_idx = -1, bool use_cpu_flag = false)
|
|
379
|
+
int vaapi_idx = -1, bool use_cpu_flag = false, bool debug_log = false)
|
|
380
380
|
: capture_width(cw),
|
|
381
381
|
capture_height(ch),
|
|
382
382
|
capture_x(cx),
|
|
@@ -390,6 +390,8 @@ struct CaptureSettings {
|
|
|
390
390
|
damage_block_duration(dbd),
|
|
391
391
|
output_mode(om),
|
|
392
392
|
h264_crf(crf),
|
|
393
|
+
h264_paintover_crf(h264_po_crf),
|
|
394
|
+
h264_paintover_burst_frames(h264_po_burst),
|
|
393
395
|
h264_fullcolor(h264_fc),
|
|
394
396
|
h264_fullframe(h264_ff),
|
|
395
397
|
h264_streaming_mode(h264_sm),
|
|
@@ -397,7 +399,8 @@ struct CaptureSettings {
|
|
|
397
399
|
watermark_path(wm_path),
|
|
398
400
|
watermark_location_enum(wm_loc),
|
|
399
401
|
vaapi_render_node_index(vaapi_idx),
|
|
400
|
-
use_cpu(use_cpu_flag)
|
|
402
|
+
use_cpu(use_cpu_flag),
|
|
403
|
+
debug_logging(debug_log) {}
|
|
401
404
|
};
|
|
402
405
|
|
|
403
406
|
/**
|
|
@@ -708,6 +711,34 @@ bool initialize_nvenc_encoder(int width,
|
|
|
708
711
|
return true;
|
|
709
712
|
}
|
|
710
713
|
|
|
714
|
+
if (g_nvenc_state.initialized && g_nvenc_state.initialized_width == width &&
|
|
715
|
+
g_nvenc_state.initialized_height == height &&
|
|
716
|
+
g_nvenc_state.initialized_buffer_format == target_buffer_format) {
|
|
717
|
+
|
|
718
|
+
NV_ENC_RECONFIGURE_PARAMS reconfigure_params = {0};
|
|
719
|
+
NV_ENC_CONFIG new_config = g_nvenc_state.encode_config;
|
|
720
|
+
|
|
721
|
+
reconfigure_params.version = NV_ENC_RECONFIGURE_PARAMS_VER;
|
|
722
|
+
reconfigure_params.reInitEncodeParams = g_nvenc_state.init_params;
|
|
723
|
+
reconfigure_params.reInitEncodeParams.encodeConfig = &new_config;
|
|
724
|
+
|
|
725
|
+
new_config.rcParams.constQP.qpInterP = target_qp;
|
|
726
|
+
new_config.rcParams.constQP.qpIntra = target_qp;
|
|
727
|
+
new_config.rcParams.constQP.qpInterB = target_qp;
|
|
728
|
+
|
|
729
|
+
bool is_quality_increasing = (target_qp < g_nvenc_state.initialized_qp);
|
|
730
|
+
reconfigure_params.forceIDR = is_quality_increasing;
|
|
731
|
+
|
|
732
|
+
NVENCSTATUS status = g_nvenc_state.nvenc_funcs.nvEncReconfigureEncoder(
|
|
733
|
+
g_nvenc_state.encoder_session, &reconfigure_params);
|
|
734
|
+
|
|
735
|
+
if (status == NV_ENC_SUCCESS) {
|
|
736
|
+
g_nvenc_state.initialized_qp = target_qp;
|
|
737
|
+
g_nvenc_state.encode_config = new_config;
|
|
738
|
+
return true;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
|
|
711
742
|
if (g_nvenc_state.initialized) {
|
|
712
743
|
g_nvenc_mutex.unlock();
|
|
713
744
|
reset_nvenc_encoder();
|
|
@@ -1705,6 +1736,8 @@ public:
|
|
|
1705
1736
|
int damage_block_threshold = 15;
|
|
1706
1737
|
int damage_block_duration = 30;
|
|
1707
1738
|
int h264_crf = 25;
|
|
1739
|
+
int h264_paintover_crf = 18;
|
|
1740
|
+
int h264_paintover_burst_frames = 5;
|
|
1708
1741
|
bool h264_fullcolor = false;
|
|
1709
1742
|
bool h264_fullframe = false;
|
|
1710
1743
|
bool h264_streaming_mode = false;
|
|
@@ -1713,6 +1746,7 @@ public:
|
|
|
1713
1746
|
std::string watermark_path_internal;
|
|
1714
1747
|
WatermarkLocation watermark_location_internal;
|
|
1715
1748
|
bool use_cpu = false;
|
|
1749
|
+
bool debug_logging = false;
|
|
1716
1750
|
|
|
1717
1751
|
std::atomic<bool> stop_requested;
|
|
1718
1752
|
std::thread capture_thread;
|
|
@@ -1852,12 +1886,15 @@ public:
|
|
|
1852
1886
|
damage_block_duration = new_settings.damage_block_duration;
|
|
1853
1887
|
output_mode = new_settings.output_mode;
|
|
1854
1888
|
h264_crf = new_settings.h264_crf;
|
|
1889
|
+
h264_paintover_crf = new_settings.h264_paintover_crf;
|
|
1890
|
+
h264_paintover_burst_frames = new_settings.h264_paintover_burst_frames;
|
|
1855
1891
|
h264_fullcolor = new_settings.h264_fullcolor;
|
|
1856
1892
|
h264_fullframe = new_settings.h264_fullframe;
|
|
1857
1893
|
h264_streaming_mode = new_settings.h264_streaming_mode;
|
|
1858
1894
|
capture_cursor = new_settings.capture_cursor;
|
|
1859
1895
|
vaapi_render_node_index = new_settings.vaapi_render_node_index;
|
|
1860
1896
|
use_cpu = new_settings.use_cpu;
|
|
1897
|
+
debug_logging = new_settings.debug_logging;
|
|
1861
1898
|
std::string new_wm_path_str = new_settings.watermark_path ? new_settings.watermark_path : "";
|
|
1862
1899
|
bool path_actually_changed_in_settings = (watermark_path_internal != new_wm_path_str);
|
|
1863
1900
|
|
|
@@ -1883,9 +1920,10 @@ public:
|
|
|
1883
1920
|
jpeg_quality, paint_over_jpeg_quality, use_paint_over_quality,
|
|
1884
1921
|
paint_over_trigger_frames, damage_block_threshold,
|
|
1885
1922
|
damage_block_duration, output_mode, h264_crf,
|
|
1923
|
+
h264_paintover_crf, h264_paintover_burst_frames,
|
|
1886
1924
|
h264_fullcolor, h264_fullframe, h264_streaming_mode, capture_cursor,
|
|
1887
1925
|
watermark_path_internal.c_str(), watermark_location_internal,
|
|
1888
|
-
vaapi_render_node_index, use_cpu
|
|
1926
|
+
vaapi_render_node_index, use_cpu, debug_logging
|
|
1889
1927
|
);
|
|
1890
1928
|
}
|
|
1891
1929
|
|
|
@@ -2009,6 +2047,8 @@ private:
|
|
|
2009
2047
|
int local_current_damage_block_threshold;
|
|
2010
2048
|
int local_current_damage_block_duration;
|
|
2011
2049
|
int local_current_h264_crf;
|
|
2050
|
+
int local_current_h264_paintover_crf;
|
|
2051
|
+
int local_current_h264_paintover_burst_frames;
|
|
2012
2052
|
bool local_current_h264_fullcolor;
|
|
2013
2053
|
bool local_current_h264_fullframe;
|
|
2014
2054
|
bool local_current_h264_streaming_mode;
|
|
@@ -2020,6 +2060,7 @@ private:
|
|
|
2020
2060
|
std::string local_watermark_path_setting;
|
|
2021
2061
|
WatermarkLocation local_watermark_location_setting;
|
|
2022
2062
|
bool local_use_cpu;
|
|
2063
|
+
bool local_debug_logging;
|
|
2023
2064
|
|
|
2024
2065
|
{
|
|
2025
2066
|
std::lock_guard<std::mutex> lock(settings_mutex);
|
|
@@ -2036,12 +2077,15 @@ private:
|
|
|
2036
2077
|
local_current_damage_block_duration = damage_block_duration;
|
|
2037
2078
|
local_current_output_mode = output_mode;
|
|
2038
2079
|
local_current_h264_crf = h264_crf;
|
|
2080
|
+
local_current_h264_paintover_crf = h264_paintover_crf;
|
|
2081
|
+
local_current_h264_paintover_burst_frames = h264_paintover_burst_frames;
|
|
2039
2082
|
local_current_h264_fullcolor = h264_fullcolor;
|
|
2040
2083
|
local_current_h264_fullframe = h264_fullframe;
|
|
2041
2084
|
local_current_h264_streaming_mode = h264_streaming_mode;
|
|
2042
2085
|
local_current_capture_cursor = capture_cursor;
|
|
2043
2086
|
local_vaapi_render_node_index = vaapi_render_node_index;
|
|
2044
2087
|
local_use_cpu = use_cpu;
|
|
2088
|
+
local_debug_logging = debug_logging;
|
|
2045
2089
|
local_watermark_path_setting = watermark_path_internal;
|
|
2046
2090
|
local_watermark_location_setting = watermark_location_internal;
|
|
2047
2091
|
}
|
|
@@ -2112,6 +2156,25 @@ private:
|
|
|
2112
2156
|
}
|
|
2113
2157
|
Window root_window = DefaultRootWindow(display);
|
|
2114
2158
|
int screen = DefaultScreen(display);
|
|
2159
|
+
XWindowAttributes attributes;
|
|
2160
|
+
if (XGetWindowAttributes(display, root_window, &attributes)) {
|
|
2161
|
+
if (local_capture_width_actual > attributes.width) {
|
|
2162
|
+
local_capture_width_actual = attributes.width;
|
|
2163
|
+
local_capture_x_offset = 0;
|
|
2164
|
+
}
|
|
2165
|
+
if (local_capture_height_actual > attributes.height) {
|
|
2166
|
+
local_capture_height_actual = attributes.height;
|
|
2167
|
+
local_capture_y_offset = 0;
|
|
2168
|
+
}
|
|
2169
|
+
if (local_capture_x_offset + local_capture_width_actual > attributes.width) {
|
|
2170
|
+
local_capture_x_offset = attributes.width - local_capture_width_actual;
|
|
2171
|
+
}
|
|
2172
|
+
if (local_capture_y_offset + local_capture_height_actual > attributes.height) {
|
|
2173
|
+
local_capture_y_offset = attributes.height - local_capture_height_actual;
|
|
2174
|
+
}
|
|
2175
|
+
if (local_capture_x_offset < 0) local_capture_x_offset = 0;
|
|
2176
|
+
if (local_capture_y_offset < 0) local_capture_y_offset = 0;
|
|
2177
|
+
}
|
|
2115
2178
|
|
|
2116
2179
|
if (!XShmQueryExtension(display)) {
|
|
2117
2180
|
std::cerr << "Error: X Shared Memory Extension not available!" << std::endl;
|
|
@@ -2215,6 +2278,66 @@ private:
|
|
|
2215
2278
|
std::cout << "CPU cores available: " << num_cores << std::endl;
|
|
2216
2279
|
int num_stripes_config = num_cores;
|
|
2217
2280
|
|
|
2281
|
+
int N_processing_stripes;
|
|
2282
|
+
if (local_capture_height_actual <= 0) {
|
|
2283
|
+
N_processing_stripes = 0;
|
|
2284
|
+
} else {
|
|
2285
|
+
if (local_current_output_mode == OutputMode::H264) {
|
|
2286
|
+
if (local_current_h264_fullframe) {
|
|
2287
|
+
N_processing_stripes = 1;
|
|
2288
|
+
} else {
|
|
2289
|
+
const int MIN_H264_STRIPE_HEIGHT_PX = 64;
|
|
2290
|
+
if (local_capture_height_actual < MIN_H264_STRIPE_HEIGHT_PX) {
|
|
2291
|
+
N_processing_stripes = 1;
|
|
2292
|
+
} else {
|
|
2293
|
+
int max_stripes_by_min_height =
|
|
2294
|
+
local_capture_height_actual / MIN_H264_STRIPE_HEIGHT_PX;
|
|
2295
|
+
N_processing_stripes =
|
|
2296
|
+
std::min(num_stripes_config, max_stripes_by_min_height);
|
|
2297
|
+
if (N_processing_stripes == 0) N_processing_stripes = 1;
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
} else {
|
|
2301
|
+
N_processing_stripes =
|
|
2302
|
+
std::min(num_stripes_config, local_capture_height_actual);
|
|
2303
|
+
if (N_processing_stripes == 0 && local_capture_height_actual > 0) {
|
|
2304
|
+
N_processing_stripes = 1;
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
if (N_processing_stripes == 0 && local_capture_height_actual > 0) {
|
|
2309
|
+
N_processing_stripes = 1;
|
|
2310
|
+
}
|
|
2311
|
+
std::stringstream settings_ss;
|
|
2312
|
+
settings_ss << "Stream settings active -> Res: " << local_capture_width_actual << "x"
|
|
2313
|
+
<< local_capture_height_actual
|
|
2314
|
+
<< " | FPS: " << std::fixed << std::setprecision(1) << local_current_target_fps
|
|
2315
|
+
<< " | Stripes: " << N_processing_stripes;
|
|
2316
|
+
if (local_current_output_mode == OutputMode::JPEG) {
|
|
2317
|
+
settings_ss << " | Mode: JPEG";
|
|
2318
|
+
settings_ss << " | Quality: " << local_current_jpeg_quality;
|
|
2319
|
+
if (local_current_use_paint_over_quality) {
|
|
2320
|
+
settings_ss << " | PaintOver Q: " << local_current_paint_over_jpeg_quality
|
|
2321
|
+
<< " (Trigger: " << local_current_paint_over_trigger_frames << "f)";
|
|
2322
|
+
}
|
|
2323
|
+
} else {
|
|
2324
|
+
std::string encoder_type = "CPU";
|
|
2325
|
+
if (this->vaapi_operational) encoder_type = "VAAPI";
|
|
2326
|
+
else if (this->nvenc_operational) encoder_type = "NVENC";
|
|
2327
|
+
settings_ss << " | Mode: H264 (" << encoder_type << ")";
|
|
2328
|
+
settings_ss << (local_current_h264_fullframe ? " FullFrame" : " Striped");
|
|
2329
|
+
if (local_current_h264_streaming_mode) settings_ss << " Streaming";
|
|
2330
|
+
settings_ss << " | CRF: " << local_current_h264_crf;
|
|
2331
|
+
if (local_current_use_paint_over_quality) {
|
|
2332
|
+
settings_ss << " | PaintOver CRF: " << local_current_h264_paintover_crf
|
|
2333
|
+
<< " (Burst: " << local_current_h264_paintover_burst_frames << "f)";
|
|
2334
|
+
}
|
|
2335
|
+
settings_ss << " | Colorspace: " << (local_current_h264_fullcolor ? "I444 (Full Range)" : "I420 (Limited Range)");
|
|
2336
|
+
}
|
|
2337
|
+
settings_ss << " | Damage Thresh: " << local_current_damage_block_threshold << "f"
|
|
2338
|
+
<< " | Damage Dur: " << local_current_damage_block_duration << "f";
|
|
2339
|
+
std::cout << settings_ss.str() << std::endl;
|
|
2340
|
+
|
|
2218
2341
|
std::vector<uint64_t> previous_hashes(num_stripes_config, 0);
|
|
2219
2342
|
std::vector<int> no_motion_frame_counts(num_stripes_config, 0);
|
|
2220
2343
|
std::vector<bool> paint_over_sent(num_stripes_config, false);
|
|
@@ -2276,6 +2399,8 @@ private:
|
|
|
2276
2399
|
}
|
|
2277
2400
|
local_current_output_mode = output_mode;
|
|
2278
2401
|
local_current_h264_crf = h264_crf;
|
|
2402
|
+
local_current_h264_paintover_crf = h264_paintover_crf;
|
|
2403
|
+
local_current_h264_paintover_burst_frames = h264_paintover_burst_frames;
|
|
2279
2404
|
local_current_h264_fullcolor = h264_fullcolor;
|
|
2280
2405
|
local_current_h264_fullframe = h264_fullframe;
|
|
2281
2406
|
local_current_h264_streaming_mode = h264_streaming_mode;
|
|
@@ -2284,6 +2409,7 @@ private:
|
|
|
2284
2409
|
local_watermark_path_setting = watermark_path_internal;
|
|
2285
2410
|
local_watermark_location_setting = watermark_location_internal;
|
|
2286
2411
|
local_use_cpu = use_cpu;
|
|
2412
|
+
local_debug_logging = debug_logging;
|
|
2287
2413
|
}
|
|
2288
2414
|
|
|
2289
2415
|
bool current_watermark_is_actually_loaded_in_loop;
|
|
@@ -2757,7 +2883,7 @@ private:
|
|
|
2757
2883
|
int crf_for_encode = local_current_h264_crf;
|
|
2758
2884
|
if (local_current_output_mode == OutputMode::H264 && h264_paintover_burst_frames_remaining[i] > 0) {
|
|
2759
2885
|
send_this_stripe = true;
|
|
2760
|
-
crf_for_encode =
|
|
2886
|
+
crf_for_encode = local_current_h264_paintover_crf;
|
|
2761
2887
|
h264_paintover_burst_frames_remaining[i]--;
|
|
2762
2888
|
current_hash = calculate_current_hash();
|
|
2763
2889
|
hash_calculated_this_iteration = true;
|
|
@@ -2808,17 +2934,27 @@ private:
|
|
|
2808
2934
|
consecutive_stripe_changes[i] = 0;
|
|
2809
2935
|
no_motion_frame_counts[i]++;
|
|
2810
2936
|
if (no_motion_frame_counts[i] >= local_current_paint_over_trigger_frames && !paint_over_sent[i]) {
|
|
2811
|
-
if (local_current_output_mode == OutputMode::JPEG &&
|
|
2937
|
+
if (local_current_output_mode == OutputMode::JPEG &&
|
|
2938
|
+
local_current_use_paint_over_quality &&
|
|
2939
|
+
local_current_paint_over_jpeg_quality > local_current_jpeg_quality) {
|
|
2812
2940
|
send_this_stripe = true;
|
|
2813
2941
|
current_jpeg_qualities[i] = local_current_paint_over_jpeg_quality;
|
|
2814
2942
|
paint_over_sent[i] = true;
|
|
2815
2943
|
} else if (local_current_output_mode == OutputMode::H264) {
|
|
2816
|
-
if (
|
|
2944
|
+
if (local_current_use_paint_over_quality && local_current_h264_paintover_crf < local_current_h264_crf) {
|
|
2817
2945
|
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
2946
|
paint_over_sent[i] = true;
|
|
2947
|
+
if (this->nvenc_operational) {
|
|
2948
|
+
g_nvenc_force_next_idr_global = true;
|
|
2949
|
+
h264_paintover_burst_frames_remaining[i] = local_current_h264_paintover_burst_frames - 1;
|
|
2950
|
+
} else if (this->vaapi_operational) {
|
|
2951
|
+
g_vaapi_force_next_idr_global = true;
|
|
2952
|
+
h264_paintover_burst_frames_remaining[i] = 0;
|
|
2953
|
+
} else {
|
|
2954
|
+
force_idr_for_paintover = true;
|
|
2955
|
+
crf_for_encode = local_current_h264_paintover_crf;
|
|
2956
|
+
h264_paintover_burst_frames_remaining[i] = local_current_h264_paintover_burst_frames - 1;
|
|
2957
|
+
}
|
|
2822
2958
|
}
|
|
2823
2959
|
}
|
|
2824
2960
|
}
|
|
@@ -2865,6 +3001,16 @@ private:
|
|
|
2865
3001
|
futures.push_back(task.get_future());
|
|
2866
3002
|
threads.push_back(std::thread(std::move(task)));
|
|
2867
3003
|
} else if (this->nvenc_operational) {
|
|
3004
|
+
int target_qp_for_frame = crf_for_encode;
|
|
3005
|
+
if (local_current_use_paint_over_quality && g_nvenc_force_next_idr_global) {
|
|
3006
|
+
target_qp_for_frame = local_current_h264_paintover_crf;
|
|
3007
|
+
}
|
|
3008
|
+
if (!initialize_nvenc_encoder(local_capture_width_actual, local_capture_height_actual, target_qp_for_frame, local_current_target_fps, local_current_h264_fullcolor)) {
|
|
3009
|
+
std::cerr << "NVENC: Re-initialization for QP change failed. Disabling NVENC." << std::endl;
|
|
3010
|
+
this->nvenc_operational = false;
|
|
3011
|
+
reset_nvenc_encoder();
|
|
3012
|
+
continue;
|
|
3013
|
+
}
|
|
2868
3014
|
std::packaged_task<StripeEncodeResult()> task([=]() {
|
|
2869
3015
|
bool force_idr = g_nvenc_force_next_idr_global.exchange(false);
|
|
2870
3016
|
return encode_fullframe_nvenc(
|
|
@@ -2877,7 +3023,7 @@ private:
|
|
|
2877
3023
|
);
|
|
2878
3024
|
});
|
|
2879
3025
|
futures.push_back(task.get_future());
|
|
2880
|
-
threads.push_back(std::thread(std::move(task)));
|
|
3026
|
+
threads.push_back(std::thread(std::move(task)));
|
|
2881
3027
|
} else {
|
|
2882
3028
|
if (force_idr_for_paintover) {
|
|
2883
3029
|
std::lock_guard<std::mutex> lock(g_h264_minimal_store.store_mutex);
|
|
@@ -2982,7 +3128,7 @@ private:
|
|
|
2982
3128
|
std::chrono::duration_cast<std::chrono::seconds>(
|
|
2983
3129
|
current_output_time_log - last_output_time);
|
|
2984
3130
|
|
|
2985
|
-
if (output_elapsed_time_log.count() >= 1) {
|
|
3131
|
+
if (local_debug_logging && output_elapsed_time_log.count() >= 1) {
|
|
2986
3132
|
double actual_fps_val =
|
|
2987
3133
|
(encoded_frame_count > 0 && output_elapsed_time_log.count() > 0)
|
|
2988
3134
|
? static_cast<double>(encoded_frame_count) / output_elapsed_time_log.count()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pixelflux
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.3
|
|
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
|
|
@@ -87,15 +87,20 @@ settings.output_mode = 1
|
|
|
87
87
|
# Force CPU encoding and ignore hardware encoders
|
|
88
88
|
capture_settings.use_cpu = False
|
|
89
89
|
|
|
90
|
+
# --- Debugging ---
|
|
91
|
+
settings.debug_logging = False # Enable/disable the continuous FPS and settings log to the console.
|
|
92
|
+
|
|
90
93
|
# --- JPEG Settings ---
|
|
91
94
|
settings.jpeg_quality = 75 # Quality for changed stripes (0-100)
|
|
92
95
|
settings.paint_over_jpeg_quality = 90 # Quality for static "paint-over" stripes (0-100)
|
|
93
96
|
|
|
94
97
|
# --- H.264 Settings ---
|
|
95
|
-
settings.h264_crf =
|
|
96
|
-
settings.
|
|
97
|
-
settings.
|
|
98
|
-
settings.
|
|
98
|
+
settings.h264_crf = 25 # CRF value (0-51, lower is better quality/higher bitrate)
|
|
99
|
+
settings.h264_paintover_crf = 18 # CRF for H.264 paintover on static content. Must be lower than h264_crf to activate.
|
|
100
|
+
settings.h264_paintover_burst_frames = 5 # Number of high-quality frames to send in a burst when a paintover is triggered.
|
|
101
|
+
settings.h264_fullcolor = False # Use I444 (full color) instead of I420 for software encoding
|
|
102
|
+
settings.h264_fullframe = True # Encode full frames (required for HW accel) instead of just changed stripes
|
|
103
|
+
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
104
|
|
|
100
105
|
# --- Hardware Acceleration ---
|
|
101
106
|
# 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.
|
|
56
|
+
version="1.3.3",
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|