pixelflux 1.4.4__tar.gz → 1.4.6__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.4.4
3
+ Version: 1.4.6
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
@@ -148,6 +148,19 @@ struct VaapiEncoderState {
148
148
  unsigned int frame_count = 0;
149
149
  };
150
150
 
151
+
152
+ /**
153
+ * @brief Custom X11 error handler specifically for the XShmAttach call.
154
+ * This function is temporarily installed as the X11 error handler. It catches
155
+ * any error, sets the g_shm_attach_failed flag to true, and returns 0 to
156
+ * signal that the error has been "handled," preventing program termination.
157
+ */
158
+ static bool g_shm_attach_failed = false;
159
+ static int shm_attach_error_handler(Display* dpy, XErrorEvent* ev) {
160
+ g_shm_attach_failed = true;
161
+ return 0;
162
+ }
163
+
151
164
  /**
152
165
  * @brief Manages a pool of H.264 encoders and associated picture buffers.
153
166
  * This struct provides thread-safe storage and management for x264 encoder
@@ -1828,6 +1841,42 @@ void ScreenCaptureModule::capture_loop() {
1828
1841
  return;
1829
1842
  }
1830
1843
 
1844
+ this->vaapi_operational = false;
1845
+ this->nvenc_operational = false;
1846
+
1847
+ if (!local_use_cpu && local_vaapi_render_node_index >= 0 &&
1848
+ local_current_output_mode == OutputMode::H264 && local_current_h264_fullframe) {
1849
+ if (this->initialize_vaapi_encoder(local_vaapi_render_node_index, local_capture_width_actual,
1850
+ local_capture_height_actual, local_current_h264_crf, local_current_h264_fullcolor)) {
1851
+ this->vaapi_operational = true;
1852
+ this->vaapi_force_next_idr_ = true;
1853
+ std::cout << "VAAPI Encoder Initialized successfully." << std::endl;
1854
+ } else {
1855
+ std::cerr << "VAAPI Encoder initialization failed. Falling back to CPU." << std::endl;
1856
+ local_use_cpu = true;
1857
+ }
1858
+ } else {
1859
+ if (!local_use_cpu && this->is_nvidia_system_detected &&
1860
+ local_current_output_mode == OutputMode::H264 && local_current_h264_fullframe) {
1861
+ if (this->initialize_nvenc_encoder(local_capture_width_actual,
1862
+ local_capture_height_actual,
1863
+ local_current_h264_crf,
1864
+ local_current_target_fps,
1865
+ local_current_h264_fullcolor)) {
1866
+ this->nvenc_operational = true;
1867
+ this->nvenc_force_next_idr_ = true;
1868
+ std::cout << "NVENC Encoder Initialized successfully." << std::endl;
1869
+ } else {
1870
+ std::cerr << "NVENC Encoder initialization failed. Falling back to x264." << std::endl;
1871
+ local_use_cpu = true;
1872
+ }
1873
+ } else {
1874
+ if (!this->nvenc_operational && this->nvenc_state_.initialized) {
1875
+ this->reset_nvenc_encoder();
1876
+ }
1877
+ }
1878
+ }
1879
+
1831
1880
  this->yuv_planes_are_i444_ = local_current_h264_fullcolor;
1832
1881
  if (local_current_output_mode == OutputMode::H264) {
1833
1882
  bool use_nv12_planes = !local_use_cpu && local_current_h264_fullframe && !local_current_h264_fullcolor &&
@@ -1873,16 +1922,21 @@ void ScreenCaptureModule::capture_loop() {
1873
1922
  auto next_frame_time =
1874
1923
  std::chrono::high_resolution_clock::now() + target_frame_duration_seconds;
1875
1924
 
1925
+ const int MAX_ATTACH_ATTEMPTS = 5;
1926
+ const int RETRY_BACKOFF_MS = 500;
1876
1927
  char* display_env = std::getenv("DISPLAY");
1877
1928
  const char* display_name = display_env ? display_env : ":0";
1878
1929
  Display* display = XOpenDisplay(display_name);
1930
+
1879
1931
  if (!display) {
1880
1932
  std::cerr << "Error: Failed to open X display " << display_name << std::endl;
1881
1933
  return;
1882
1934
  }
1935
+
1883
1936
  Window root_window = DefaultRootWindow(display);
1884
1937
  int screen = DefaultScreen(display);
1885
1938
  XWindowAttributes attributes;
1939
+
1886
1940
  if (XGetWindowAttributes(display, root_window, &attributes)) {
1887
1941
  if (local_capture_width_actual > attributes.width) {
1888
1942
  local_capture_width_actual = attributes.width;
@@ -1907,6 +1961,7 @@ void ScreenCaptureModule::capture_loop() {
1907
1961
  XCloseDisplay(display);
1908
1962
  return;
1909
1963
  }
1964
+
1910
1965
  std::cout << "X Shared Memory Extension available." << std::endl;
1911
1966
 
1912
1967
  if (local_current_capture_cursor) {
@@ -1915,91 +1970,76 @@ void ScreenCaptureModule::capture_loop() {
1915
1970
  XCloseDisplay(display);
1916
1971
  return;
1917
1972
  }
1918
-
1919
1973
  std::cout << "XFixes Extension available." << std::endl;
1920
1974
  }
1921
1975
 
1922
1976
  XShmSegmentInfo shminfo;
1923
- memset(&shminfo, 0, sizeof(shminfo));
1924
1977
  XImage* shm_image = nullptr;
1978
+ bool shm_setup_complete = false;
1925
1979
 
1926
- shm_image = XShmCreateImage(
1927
- display, DefaultVisual(display, screen), DefaultDepth(display, screen),
1928
- ZPixmap, nullptr, &shminfo, local_capture_width_actual,
1929
- local_capture_height_actual);
1930
- if (!shm_image) {
1931
- std::cerr << "Error: XShmCreateImage failed for "
1932
- << local_capture_width_actual << "x"
1933
- << local_capture_height_actual << std::endl;
1934
- XCloseDisplay(display);
1935
- return;
1936
- }
1980
+ for (int attempt = 1; attempt <= MAX_ATTACH_ATTEMPTS; ++attempt) {
1981
+ memset(&shminfo, 0, sizeof(shminfo));
1982
+ shm_image = XShmCreateImage(display, DefaultVisual(display, screen), DefaultDepth(display, screen),
1983
+ ZPixmap, nullptr, &shminfo, local_capture_width_actual,
1984
+ local_capture_height_actual);
1985
+ if (!shm_image) {
1986
+ std::cerr << "Attempt " << attempt << ": XShmCreateImage failed." << std::endl;
1987
+ if (attempt < MAX_ATTACH_ATTEMPTS) std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_BACKOFF_MS));
1988
+ continue;
1989
+ }
1937
1990
 
1938
- shminfo.shmid = shmget(IPC_PRIVATE,
1939
- static_cast<size_t>(shm_image->bytes_per_line) * shm_image->height,
1940
- IPC_CREAT | 0600);
1941
- if (shminfo.shmid < 0) {
1942
- perror("shmget");
1943
- XDestroyImage(shm_image);
1944
- XCloseDisplay(display);
1945
- return;
1946
- }
1991
+ shminfo.shmid = shmget(IPC_PRIVATE, static_cast<size_t>(shm_image->bytes_per_line) * shm_image->height, IPC_CREAT | 0600);
1992
+ if (shminfo.shmid < 0) {
1993
+ perror("shmget");
1994
+ XDestroyImage(shm_image);
1995
+ if (attempt < MAX_ATTACH_ATTEMPTS) std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_BACKOFF_MS));
1996
+ continue;
1997
+ }
1947
1998
 
1948
- shminfo.shmaddr = (char*)shmat(shminfo.shmid, nullptr, 0);
1949
- if (shminfo.shmaddr == (char*)-1) {
1950
- perror("shmat");
1951
- shmctl(shminfo.shmid, IPC_RMID, 0);
1952
- XDestroyImage(shm_image);
1953
- XCloseDisplay(display);
1954
- return;
1999
+ shminfo.shmaddr = (char*)shmat(shminfo.shmid, nullptr, 0);
2000
+ if (shminfo.shmaddr == (char*)-1) {
2001
+ perror("shmat");
2002
+ shmctl(shminfo.shmid, IPC_RMID, 0);
2003
+ XDestroyImage(shm_image);
2004
+ if (attempt < MAX_ATTACH_ATTEMPTS) std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_BACKOFF_MS));
2005
+ continue;
2006
+ }
2007
+
2008
+ shminfo.readOnly = False;
2009
+ shm_image->data = shminfo.shmaddr;
2010
+ g_shm_attach_failed = false;
2011
+ XErrorHandler old_handler = XSetErrorHandler(shm_attach_error_handler);
2012
+ XShmAttach(display, &shminfo);
2013
+ XSync(display, False);
2014
+ XSetErrorHandler(old_handler);
2015
+
2016
+ if (g_shm_attach_failed) {
2017
+ std::cerr << "Attempt " << attempt << "/" << MAX_ATTACH_ATTEMPTS << ": XShmAttach failed with an X server error." << std::endl;
2018
+ shmdt(shminfo.shmaddr);
2019
+ shmctl(shminfo.shmid, IPC_RMID, 0);
2020
+ XDestroyImage(shm_image);
2021
+ if (attempt < MAX_ATTACH_ATTEMPTS) {
2022
+ std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_BACKOFF_MS));
2023
+ }
2024
+ continue;
2025
+ }
2026
+
2027
+ shm_setup_complete = true;
2028
+ break;
1955
2029
  }
1956
- shminfo.readOnly = False;
1957
- shm_image->data = shminfo.shmaddr;
1958
2030
 
1959
- if (!XShmAttach(display, &shminfo)) {
1960
- std::cerr << "Error: XShmAttach failed" << std::endl;
1961
- shmdt(shminfo.shmaddr);
1962
- shmctl(shminfo.shmid, IPC_RMID, 0);
1963
- XDestroyImage(shm_image);
1964
- XCloseDisplay(display);
1965
- return;
2031
+ if (!shm_setup_complete) {
2032
+ std::cerr << "ERROR: Failed to set up XShm after " << MAX_ATTACH_ATTEMPTS << " attempts. Exiting capture thread." << std::endl;
2033
+ if (display) {
2034
+ XCloseDisplay(display);
2035
+ display = nullptr;
2036
+ }
2037
+ return;
1966
2038
  }
2039
+
1967
2040
  std::cout << "XShm setup complete for " << local_capture_width_actual
1968
2041
  << "x" << local_capture_height_actual << "." << std::endl;
1969
2042
 
1970
- this->vaapi_operational = false;
1971
- this->nvenc_operational = false;
1972
-
1973
- if (!local_use_cpu && local_vaapi_render_node_index >= 0 &&
1974
- local_current_output_mode == OutputMode::H264 && local_current_h264_fullframe) {
1975
- if (this->initialize_vaapi_encoder(local_vaapi_render_node_index, local_capture_width_actual,
1976
- local_capture_height_actual, local_current_h264_crf, local_current_h264_fullcolor)) {
1977
- this->vaapi_operational = true;
1978
- this->vaapi_force_next_idr_ = true;
1979
- std::cout << "VAAPI Encoder Initialized successfully." << std::endl;
1980
- } else {
1981
- std::cerr << "VAAPI Encoder initialization failed. Falling back to CPU." << std::endl;
1982
- }
1983
- } else {
1984
- if (!local_use_cpu && this->is_nvidia_system_detected &&
1985
- local_current_output_mode == OutputMode::H264 && local_current_h264_fullframe) {
1986
- if (this->initialize_nvenc_encoder(local_capture_width_actual,
1987
- local_capture_height_actual,
1988
- local_current_h264_crf,
1989
- local_current_target_fps,
1990
- local_current_h264_fullcolor)) {
1991
- this->nvenc_operational = true;
1992
- this->nvenc_force_next_idr_ = true;
1993
- std::cout << "NVENC Encoder Initialized successfully." << std::endl;
1994
- } else {
1995
- std::cerr << "NVENC Encoder initialization failed. Falling back to x264." << std::endl;
1996
- }
1997
- } else {
1998
- if (!this->nvenc_operational && this->nvenc_state_.initialized) {
1999
- this->reset_nvenc_encoder();
2000
- }
2001
- }
2002
- }
2003
2043
  int num_cores = std::max(1, (int)std::thread::hardware_concurrency());
2004
2044
  std::cout << "CPU cores available: " << num_cores << std::endl;
2005
2045
  int num_stripes_config = num_cores;
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pixelflux
3
- Version: 1.4.4
3
+ Version: 1.4.6
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
@@ -48,7 +48,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
48
48
  long_description = fh.read()
49
49
  setup(
50
50
  name="pixelflux",
51
- version="1.4.4",
51
+ version="1.4.6",
52
52
  author="Linuxserver.io",
53
53
  author_email="pypi@linuxserver.io",
54
54
  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