pixelflux 1.4.3__tar.gz → 1.4.5__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.3
3
+ Version: 1.4.5
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
@@ -32,6 +32,7 @@ This module relies on a native C++ extension that is compiled during installatio
32
32
  sudo apt-get update && \
33
33
  sudo apt-get install -y \
34
34
  g++ \
35
+ libavcodec-dev \
35
36
  libdrm-dev \
36
37
  libjpeg-turbo8-dev \
37
38
  libva-dev \
@@ -18,6 +18,7 @@ This module relies on a native C++ extension that is compiled during installatio
18
18
  sudo apt-get update && \
19
19
  sudo apt-get install -y \
20
20
  g++ \
21
+ libavcodec-dev \
21
22
  libdrm-dev \
22
23
  libjpeg-turbo8-dev \
23
24
  libva-dev \
@@ -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
@@ -1577,37 +1590,39 @@ StripeEncodeResult ScreenCaptureModule::encode_fullframe_vaapi(int width, int he
1577
1590
  if (ret < 0) {
1578
1591
  throw std::runtime_error("VAAPI_ENCODE_ERROR: Failed to send frame to encoder: " + std::to_string(ret));
1579
1592
  }
1580
- ret = avcodec_receive_packet(vaapi_state_.codec_ctx, vaapi_state_.packet);
1581
- if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
1582
- return {};
1583
- } else if (ret < 0) {
1584
- throw std::runtime_error("VAAPI_ENCODE_ERROR: Failed to receive packet from encoder: " + std::to_string(ret));
1585
- }
1586
- StripeEncodeResult result;
1587
- result.type = StripeDataType::H264;
1588
- result.stripe_y_start = 0;
1589
- result.stripe_height = height;
1590
- result.frame_id = frame_counter;
1591
- if (vaapi_state_.packet->size > 0) {
1592
- const unsigned char TAG = 0x04;
1593
- unsigned char type_hdr = (vaapi_state_.packet->flags & AV_PKT_FLAG_KEY) ? 0x01 : 0x00;
1594
- int header_sz = 10;
1595
- result.data = new unsigned char[vaapi_state_.packet->size + header_sz];
1596
- result.size = vaapi_state_.packet->size + header_sz;
1597
- result.data[0] = TAG;
1598
- result.data[1] = type_hdr;
1599
- uint16_t net_val = htons(static_cast<uint16_t>(result.frame_id % 65536));
1600
- std::memcpy(result.data + 2, &net_val, 2);
1601
- net_val = htons(static_cast<uint16_t>(result.stripe_y_start));
1602
- std::memcpy(result.data + 4, &net_val, 2);
1603
- net_val = htons(static_cast<uint16_t>(width));
1604
- std::memcpy(result.data + 6, &net_val, 2);
1605
- net_val = htons(static_cast<uint16_t>(height));
1606
- std::memcpy(result.data + 8, &net_val, 2);
1607
- std::memcpy(result.data + header_sz, vaapi_state_.packet->data, vaapi_state_.packet->size);
1608
- }
1609
- av_packet_unref(vaapi_state_.packet);
1610
- return result;
1593
+ while (true) {
1594
+ ret = avcodec_receive_packet(vaapi_state_.codec_ctx, vaapi_state_.packet);
1595
+ if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
1596
+ return {};
1597
+ } else if (ret < 0) {
1598
+ throw std::runtime_error("VAAPI_ENCODE_ERROR: Failed to receive packet from encoder: " + std::to_string(ret));
1599
+ }
1600
+ StripeEncodeResult result;
1601
+ result.type = StripeDataType::H264;
1602
+ result.stripe_y_start = 0;
1603
+ result.stripe_height = height;
1604
+ result.frame_id = frame_counter;
1605
+ if (vaapi_state_.packet->size > 0) {
1606
+ const unsigned char TAG = 0x04;
1607
+ unsigned char type_hdr = (vaapi_state_.packet->flags & AV_PKT_FLAG_KEY) ? 0x01 : 0x00;
1608
+ int header_sz = 10;
1609
+ result.data = new unsigned char[vaapi_state_.packet->size + header_sz];
1610
+ result.size = vaapi_state_.packet->size + header_sz;
1611
+ result.data[0] = TAG;
1612
+ result.data[1] = type_hdr;
1613
+ uint16_t net_val = htons(static_cast<uint16_t>(result.frame_id % 65536));
1614
+ std::memcpy(result.data + 2, &net_val, 2);
1615
+ net_val = htons(static_cast<uint16_t>(result.stripe_y_start));
1616
+ std::memcpy(result.data + 4, &net_val, 2);
1617
+ net_val = htons(static_cast<uint16_t>(width));
1618
+ std::memcpy(result.data + 6, &net_val, 2);
1619
+ net_val = htons(static_cast<uint16_t>(height));
1620
+ std::memcpy(result.data + 8, &net_val, 2);
1621
+ std::memcpy(result.data + header_sz, vaapi_state_.packet->data, vaapi_state_.packet->size);
1622
+ }
1623
+ av_packet_unref(vaapi_state_.packet);
1624
+ return result;
1625
+ }
1611
1626
  }
1612
1627
 
1613
1628
  /**
@@ -1871,16 +1886,21 @@ void ScreenCaptureModule::capture_loop() {
1871
1886
  auto next_frame_time =
1872
1887
  std::chrono::high_resolution_clock::now() + target_frame_duration_seconds;
1873
1888
 
1889
+ const int MAX_ATTACH_ATTEMPTS = 5;
1890
+ const int RETRY_BACKOFF_MS = 500;
1874
1891
  char* display_env = std::getenv("DISPLAY");
1875
1892
  const char* display_name = display_env ? display_env : ":0";
1876
1893
  Display* display = XOpenDisplay(display_name);
1894
+
1877
1895
  if (!display) {
1878
1896
  std::cerr << "Error: Failed to open X display " << display_name << std::endl;
1879
1897
  return;
1880
1898
  }
1899
+
1881
1900
  Window root_window = DefaultRootWindow(display);
1882
1901
  int screen = DefaultScreen(display);
1883
1902
  XWindowAttributes attributes;
1903
+
1884
1904
  if (XGetWindowAttributes(display, root_window, &attributes)) {
1885
1905
  if (local_capture_width_actual > attributes.width) {
1886
1906
  local_capture_width_actual = attributes.width;
@@ -1905,6 +1925,7 @@ void ScreenCaptureModule::capture_loop() {
1905
1925
  XCloseDisplay(display);
1906
1926
  return;
1907
1927
  }
1928
+
1908
1929
  std::cout << "X Shared Memory Extension available." << std::endl;
1909
1930
 
1910
1931
  if (local_current_capture_cursor) {
@@ -1913,55 +1934,73 @@ void ScreenCaptureModule::capture_loop() {
1913
1934
  XCloseDisplay(display);
1914
1935
  return;
1915
1936
  }
1916
-
1917
1937
  std::cout << "XFixes Extension available." << std::endl;
1918
1938
  }
1919
1939
 
1920
1940
  XShmSegmentInfo shminfo;
1921
- memset(&shminfo, 0, sizeof(shminfo));
1922
1941
  XImage* shm_image = nullptr;
1942
+ bool shm_setup_complete = false;
1923
1943
 
1924
- shm_image = XShmCreateImage(
1925
- display, DefaultVisual(display, screen), DefaultDepth(display, screen),
1926
- ZPixmap, nullptr, &shminfo, local_capture_width_actual,
1927
- local_capture_height_actual);
1928
- if (!shm_image) {
1929
- std::cerr << "Error: XShmCreateImage failed for "
1930
- << local_capture_width_actual << "x"
1931
- << local_capture_height_actual << std::endl;
1932
- XCloseDisplay(display);
1933
- return;
1934
- }
1944
+ for (int attempt = 1; attempt <= MAX_ATTACH_ATTEMPTS; ++attempt) {
1945
+ memset(&shminfo, 0, sizeof(shminfo));
1946
+ shm_image = XShmCreateImage(display, DefaultVisual(display, screen), DefaultDepth(display, screen),
1947
+ ZPixmap, nullptr, &shminfo, local_capture_width_actual,
1948
+ local_capture_height_actual);
1949
+ if (!shm_image) {
1950
+ std::cerr << "Attempt " << attempt << ": XShmCreateImage failed." << std::endl;
1951
+ if (attempt < MAX_ATTACH_ATTEMPTS) std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_BACKOFF_MS));
1952
+ continue;
1953
+ }
1935
1954
 
1936
- shminfo.shmid = shmget(IPC_PRIVATE,
1937
- static_cast<size_t>(shm_image->bytes_per_line) * shm_image->height,
1938
- IPC_CREAT | 0600);
1939
- if (shminfo.shmid < 0) {
1940
- perror("shmget");
1941
- XDestroyImage(shm_image);
1942
- XCloseDisplay(display);
1943
- return;
1944
- }
1955
+ shminfo.shmid = shmget(IPC_PRIVATE, static_cast<size_t>(shm_image->bytes_per_line) * shm_image->height, IPC_CREAT | 0600);
1956
+ if (shminfo.shmid < 0) {
1957
+ perror("shmget");
1958
+ XDestroyImage(shm_image);
1959
+ if (attempt < MAX_ATTACH_ATTEMPTS) std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_BACKOFF_MS));
1960
+ continue;
1961
+ }
1945
1962
 
1946
- shminfo.shmaddr = (char*)shmat(shminfo.shmid, nullptr, 0);
1947
- if (shminfo.shmaddr == (char*)-1) {
1948
- perror("shmat");
1949
- shmctl(shminfo.shmid, IPC_RMID, 0);
1950
- XDestroyImage(shm_image);
1951
- XCloseDisplay(display);
1952
- return;
1963
+ shminfo.shmaddr = (char*)shmat(shminfo.shmid, nullptr, 0);
1964
+ if (shminfo.shmaddr == (char*)-1) {
1965
+ perror("shmat");
1966
+ shmctl(shminfo.shmid, IPC_RMID, 0);
1967
+ XDestroyImage(shm_image);
1968
+ if (attempt < MAX_ATTACH_ATTEMPTS) std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_BACKOFF_MS));
1969
+ continue;
1970
+ }
1971
+
1972
+ shminfo.readOnly = False;
1973
+ shm_image->data = shminfo.shmaddr;
1974
+ g_shm_attach_failed = false;
1975
+ XErrorHandler old_handler = XSetErrorHandler(shm_attach_error_handler);
1976
+ XShmAttach(display, &shminfo);
1977
+ XSync(display, False);
1978
+ XSetErrorHandler(old_handler);
1979
+
1980
+ if (g_shm_attach_failed) {
1981
+ std::cerr << "Attempt " << attempt << "/" << MAX_ATTACH_ATTEMPTS << ": XShmAttach failed with an X server error." << std::endl;
1982
+ shmdt(shminfo.shmaddr);
1983
+ shmctl(shminfo.shmid, IPC_RMID, 0);
1984
+ XDestroyImage(shm_image);
1985
+ if (attempt < MAX_ATTACH_ATTEMPTS) {
1986
+ std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_BACKOFF_MS));
1987
+ }
1988
+ continue;
1989
+ }
1990
+
1991
+ shm_setup_complete = true;
1992
+ break;
1953
1993
  }
1954
- shminfo.readOnly = False;
1955
- shm_image->data = shminfo.shmaddr;
1956
1994
 
1957
- if (!XShmAttach(display, &shminfo)) {
1958
- std::cerr << "Error: XShmAttach failed" << std::endl;
1959
- shmdt(shminfo.shmaddr);
1960
- shmctl(shminfo.shmid, IPC_RMID, 0);
1961
- XDestroyImage(shm_image);
1962
- XCloseDisplay(display);
1963
- return;
1995
+ if (!shm_setup_complete) {
1996
+ std::cerr << "ERROR: Failed to set up XShm after " << MAX_ATTACH_ATTEMPTS << " attempts. Exiting capture thread." << std::endl;
1997
+ if (display) {
1998
+ XCloseDisplay(display);
1999
+ display = nullptr;
2000
+ }
2001
+ return;
1964
2002
  }
2003
+
1965
2004
  std::cout << "XShm setup complete for " << local_capture_width_actual
1966
2005
  << "x" << local_capture_height_actual << "." << std::endl;
1967
2006
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pixelflux
3
- Version: 1.4.3
3
+ Version: 1.4.5
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
@@ -32,6 +32,7 @@ This module relies on a native C++ extension that is compiled during installatio
32
32
  sudo apt-get update && \
33
33
  sudo apt-get install -y \
34
34
  g++ \
35
+ libavcodec-dev \
35
36
  libdrm-dev \
36
37
  libjpeg-turbo8-dev \
37
38
  libva-dev \
@@ -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.3",
51
+ version="1.4.5",
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