Skip to content

Commit

Permalink
fix Full vs Restricted color issue by conversion to sRGB
Browse files Browse the repository at this point in the history
thanks to @PancakeTAS for this discovery
  • Loading branch information
fduncanh committed Dec 20, 2024
1 parent 47783de commit b1fb510
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 12 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ if ( ( UNIX AND NOT APPLE ) OR USE_X11 )
endif()

if( UNIX AND NOT APPLE )
add_definitions( -DSUPPRESS_AVAHI_COMPAT_WARNING )
add_definitions( -DSUPPRESS_AVAHI_COMPAT_WARNING )
# convert AirPlay colormap 1:3:7:1 to sRGB (1:1:7:1), needed on Linux and BSD
add_definitions( -DFULL_RANGE_RGB_FIX )
else()
set( CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE )
endif()
Expand Down
14 changes: 12 additions & 2 deletions README.html
Original file line number Diff line number Diff line change
Expand Up @@ -1107,8 +1107,18 @@ <h1 id="usage">Usage</h1>
<p><strong>-bt709</strong> A workaround for the failure of the older
Video4Linux2 plugin to recognize Apple’s use of an uncommon (but
permitted) “full-range color” variant of the bt709 color standard for
digital TV. This is no longer needed by GStreamer-1.20.4 and backports
from it.</p>
digital TV. This was no longer needed by GStreamer-1.20.4 and backports
from it, but appears to again be required in GStreamer-1.22 and
later.</p>
<p><strong>-srgb</strong> A workaround for a failure to display
full-range 8-bit color [0-255], and instead restrict to limited range
[16-235] “legal BT709” HDTV format. The workaround works on x86_64
desktop systems, but does not yet work on Raspberry Pi. The issue may be
fixed in a future GStreamer release: it only occurs in Linux and
*BSD.</p>
<p><strong>-srbg no</strong>. Disables the -srgb option, which is
enabled by default in Linux and *BSD, but may be useless on Raspberry
Pi, and may be unwanted, as it adds extra processing load.</p>
<p><strong>-rpi</strong> Equivalent to “-v4l2” (Not valid for Raspberry
Pi model 5, and removed in UxPlay 1.67)</p>
<p><strong>-rpigl</strong> Equivalent to “-rpi -vs glimagesink”.
Expand Down
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1121,8 +1121,19 @@ Video4Linux2. Equivalent to `-vd v4l2h264dec -vc v4l2convert`.

**-bt709** A workaround for the failure of the older Video4Linux2 plugin
to recognize Apple's use of an uncommon (but permitted) "full-range
color" variant of the bt709 color standard for digital TV. This is no
longer needed by GStreamer-1.20.4 and backports from it.
color" variant of the bt709 color standard for digital TV. This was no
longer needed by GStreamer-1.20.4 and backports from it, but appears to
again be required in GStreamer-1.22 and later.

**-srgb** A workaround for a failure to display full-range 8-bit color
[0-255], and instead restrict to limited range [16-235] "legal BT709"
HDTV format. The workaround works on x86_64 desktop systems, but
does not yet work on Raspberry Pi. The issue may be fixed in a future GStreamer
release: it only occurs in Linux and \*BSD.

**-srbg no**. Disables the -srgb option, which is enabled by default in
Linux and *BSD, but may be useless on Raspberry Pi, and may be unwanted,
as it adds extra processing load.

**-rpi** Equivalent to "-v4l2" (Not valid for Raspberry Pi model 5, and
removed in UxPlay 1.67)
Expand Down
15 changes: 13 additions & 2 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1122,8 +1122,19 @@ Video4Linux2. Equivalent to `-vd v4l2h264dec -vc v4l2convert`.

**-bt709** A workaround for the failure of the older Video4Linux2 plugin
to recognize Apple's use of an uncommon (but permitted) "full-range
color" variant of the bt709 color standard for digital TV. This is no
longer needed by GStreamer-1.20.4 and backports from it.
color" variant of the bt709 color standard for digital TV. This was no
longer needed by GStreamer-1.20.4 and backports from it, but appears to
again be required in GStreamer-1.22 and later.

**-srgb** A workaround for a failure to display full-range 8-bit color
\[0-255\], and instead restrict to limited range \[16-235\] "legal
BT709" HDTV format. The workaround works on x86_64 desktop systems, but
does not yet work on Raspberry Pi. The issue may be fixed in a future
GStreamer release: it only occurs in Linux and \*BSD.

**-srbg no**. Disables the -srgb option, which is enabled by default in
Linux and \*BSD, but may be useless on Raspberry Pi, and may be
unwanted, as it adds extra processing load.

**-rpi** Equivalent to "-v4l2" (Not valid for Raspberry Pi model 5, and
removed in UxPlay 1.67)
Expand Down
6 changes: 3 additions & 3 deletions renderers/video_renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,14 @@ static void append_videoflip (GString *launch, const videoflip_t *flip, const vi
}
}

/* apple uses colorimetry=1:3:5:1 *
/* apple uses colorimetry that is detected as 1:3:7:1 * //previously 1:3:5:1 was seen
* (not recognized by v4l2 plugin in Gstreamer < 1.20.4) *
* See .../gst-libs/gst/video/video-color.h in gst-plugins-base *
* range = 1 -> GST_VIDEO_COLOR_RANGE_0_255 ("full RGB") *
* matrix = 3 -> GST_VIDEO_COLOR_MATRIX_BT709 *
* transfer = 5 -> GST_VIDEO_TRANSFER_BT709 *
* transfer = 7 -> GST_VIDEO_TRANSFER_SRGB * // previously GST_VIDEO_TRANSFER_BT709
* primaries = 1 -> GST_VIDEO_COLOR_PRIMARIES_BT709 *
* closest used by GStreamer < 1.20.4 is BT709, 2:3:5:1 with * *
* closest used by GStreamer < 1.20.4 is BT709, 2:3:5:1 with * // now use sRGB = 1:1:7:1
* range = 2 -> GST_VIDEO_COLOR_RANGE_16_235 ("limited RGB") */

static const char h264_caps[]="video/x-h264,stream-format=(string)byte-stream,alignment=(string)au";
Expand Down
6 changes: 6 additions & 0 deletions uxplay.1
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ UxPlay 1.71: An open\-source AirPlay mirroring (+ audio streaming) server:
.TP
\fB\-bt709\fR Sometimes needed for Raspberry Pi models using Video4Linux2.
.TP
\fB\-srgb\fR Display "Full range" [0-255] color, not "Limited Range"[16-235]
.IP
This is a workaround for a GStreamer problem, until it is fixed.
.PP
\fB\-srgb\fR no Disable srgb option (use when enabled by default: Linux, *BSD)
.TP
\fB\-as\fI sink\fR Choose the GStreamer audiosink; default "autoaudiosink"
.IP
choices:pulsesink,alsasink,pipewiresink,osssink,oss4sink,
Expand Down
29 changes: 27 additions & 2 deletions uxplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@
#define HIGHEST_PORT 65535
#define NTP_TIMEOUT_LIMIT 5
#define BT709_FIX "capssetter caps=\"video/x-h264, colorimetry=bt709\""
#define SRGB_FIX " ! video/x-raw,colorimetry=sRGB,format=RGB ! "
#ifdef FULL_RANGE_RGB_FIX
#define DEFAULT_SRGB_FIX true
#else
#define DEFAULT_SRGB_FIX false
#endif

static std::string server_name = DEFAULT_NAME;
static dnssd_t *dnssd = NULL;
Expand Down Expand Up @@ -122,6 +128,7 @@ static unsigned short display[5] = {0}, tcp[3] = {0}, udp[3] = {0};
static bool debug_log = DEFAULT_DEBUG_LOG;
static int log_level = LOGGER_INFO;
static bool bt709_fix = false;
static bool srgb_fix = DEFAULT_SRGB_FIX;
static int nohold = 0;
static bool nofreeze = false;
static unsigned short raop_port;
Expand Down Expand Up @@ -640,7 +647,10 @@ static void print_info (char *name) {
printf(" gtksink,waylandsink,osxvideosink,kmssink,d3d11videosink etc.\n");
printf("-vs 0 Streamed audio only, with no video display window\n");
printf("-v4l2 Use Video4Linux2 for GPU hardware h264 decoding\n");
printf("-bt709 Sometimes needed for Raspberry Pi models using Video4Linux2 \n");
printf("-bt709 Sometimes needed for Raspberry Pi models using Video4Linux2 \n");
printf("-srgb Display \"Full range\" [0-255] color, not \"Limited Range\"[16-235]\n");
printf(" This is a workaround for a GStreamer problem, until it is fixed\n");
printf("-srgb no Disable srgb option (use when enabled by default: Linux, *BSD)\n");
printf("-as ... Choose the GStreamer audiosink; default \"autoaudiosink\"\n");
printf(" some choices:pulsesink,alsasink,pipewiresink,jackaudiosink,\n");
printf(" osssink,oss4sink,osxaudiosink,wasapisink,directsoundsink.\n");
Expand Down Expand Up @@ -1003,7 +1013,7 @@ static void parse_arguments (int argc, char *argv[]) {
fprintf(stderr," -rpifb was equivalent to \"-v4l2 -vs kmssink\"\n");
fprintf(stderr," -rpigl was equivalent to \"-v4l2 -vs glimagesink\"\n");
fprintf(stderr," -rpiwl was equivalent to \"-v4l2 -vs waylandsink\"\n");
fprintf(stderr," for GStreamer < 1.22, \"-bt709\" may also be needed\n");
fprintf(stderr," Option \"-bt709\" may also be needed for R Pi model 4B and earlier\n");
exit(1);
} else if (arg == "-fs" ) {
fullscreen = true;
Expand Down Expand Up @@ -1078,6 +1088,15 @@ static void parse_arguments (int argc, char *argv[]) {
}
} else if (arg == "-bt709") {
bt709_fix = true;
} else if (arg == "-srgb") {
srgb_fix = true;
if (i < argc - 1) {
if (strlen(argv[i+1]) == 2 && strncmp(argv[i+1], "no", 2) == 0) {
srgb_fix = false;
i++;
continue;
}
}
} else if (arg == "-nohold") {
nohold = 1;
} else if (arg == "-al") {
Expand Down Expand Up @@ -2170,6 +2189,12 @@ int main (int argc, char *argv[]) {
video_parser.append(BT709_FIX);
}

if (srgb_fix && use_video) {
std::string option = video_converter;
video_converter.append(SRGB_FIX);
video_converter.append(option);
}

if (require_password && registration_list) {
if (pairing_register == "") {
const char * homedir = get_homedir();
Expand Down

0 comments on commit b1fb510

Please sign in to comment.