mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 14:41:25 +00:00
HACK: add 444 support and other hacks.
This commit is contained in:
parent
d561f81855
commit
c464464005
@ -2230,6 +2230,15 @@ DisplayChannel::DisplayChannel(RedsState *reds,
|
||||
set_cap(SPICE_DISPLAY_CAP_PREF_VIDEO_CODEC_TYPE);
|
||||
set_cap(SPICE_DISPLAY_CAP_STREAM_REPORT);
|
||||
|
||||
//TODO actualy check
|
||||
set_cap(SPICE_DISPLAY_CAP_CODEC_H264);
|
||||
set_cap(SPICE_DISPLAY_CAP_CODEC_VP9);
|
||||
set_cap(SPICE_DISPLAY_CAP_CODEC_H265);
|
||||
set_cap(SPICE_DISPLAY_CAP_CODEC_AV1);
|
||||
set_cap(SPICE_DISPLAY_CAP_CODEC_VP9_444);
|
||||
set_cap(SPICE_DISPLAY_CAP_CODEC_H265_444);
|
||||
// set_cap(SPICE_DISPLAY_CAP_CODEC_VP9_U);
|
||||
|
||||
reds_register_channel(reds, this);
|
||||
}
|
||||
|
||||
|
||||
@ -919,10 +919,17 @@ static const gchar* get_gst_codec_name(const SpiceGstEncoder *encoder)
|
||||
return "avenc_mjpeg";
|
||||
case SPICE_VIDEO_CODEC_TYPE_VP8:
|
||||
return "vp8enc";
|
||||
case SPICE_VIDEO_CODEC_TYPE_H264_444:
|
||||
case SPICE_VIDEO_CODEC_TYPE_H264:
|
||||
return "x264enc";
|
||||
case SPICE_VIDEO_CODEC_TYPE_VP9_444:
|
||||
case SPICE_VIDEO_CODEC_TYPE_VP9:
|
||||
return "vp9enc";
|
||||
case SPICE_VIDEO_CODEC_TYPE_H265_444:
|
||||
case SPICE_VIDEO_CODEC_TYPE_H265:
|
||||
return "x265enc";
|
||||
case SPICE_VIDEO_CODEC_TYPE_AV1:
|
||||
return "av1enc";
|
||||
default:
|
||||
/* gstreamer_encoder_new() should have rejected this codec type */
|
||||
spice_warning("unsupported codec type %d", encoder->base.codec_type);
|
||||
@ -937,6 +944,16 @@ static const char video_codecs[][8] = {
|
||||
{ "h264" },
|
||||
{ "vp9" },
|
||||
{ "h265" },
|
||||
{ "av1" },
|
||||
{ "h264" },
|
||||
{ "vp9" },
|
||||
{ "h265" },
|
||||
{ "av1" },
|
||||
{ "h264"},
|
||||
{ "vp9"},
|
||||
{ "h265"},
|
||||
{ "av1"},
|
||||
|
||||
};
|
||||
|
||||
static bool gst_features_lookup(const gchar *feature_name)
|
||||
@ -990,7 +1007,7 @@ static gchar *find_best_hw_plugin(const gchar *codec_name)
|
||||
}
|
||||
g_free(feature_name);
|
||||
if(i == 1 && codec_name){
|
||||
feature_name = g_strconcat(plugins[i], "lpenc", NULL);
|
||||
feature_name = g_strconcat(plugins[i], codec_name, "lpenc", NULL);
|
||||
if (gst_features_lookup(feature_name)) {
|
||||
return feature_name;
|
||||
}
|
||||
@ -1022,7 +1039,7 @@ static gchar *get_hw_gstenc_opts(const gchar *encoder, const gchar *codec_name)
|
||||
}
|
||||
} else {
|
||||
if (strcmp(codec_name, "vp9") == 0) {
|
||||
gstenc_opts = g_strdup("min-qp=15 max-qp=35 rate-control=16 ref-frames=0 target-usage=7");
|
||||
gstenc_opts = g_strdup("min-qp=15 max-qp=35 rate-control=16 target-usage=7 gf-group-size=1");
|
||||
} else {
|
||||
gstenc_opts = g_strdup("rate-control=16 b-frames=0 target-usage=7 min-qp=15 max-qp=35");
|
||||
}
|
||||
@ -1030,10 +1047,12 @@ static gchar *get_hw_gstenc_opts(const gchar *encoder, const gchar *codec_name)
|
||||
return gstenc_opts;
|
||||
}
|
||||
|
||||
static void try_intel_hw_plugins(const gchar *codec_name, gchar **converter,
|
||||
static void try_intel_hw_plugins(SpiceGstEncoder* spice_encoder, gchar **converter,
|
||||
gchar **gstenc_name, gchar **gstenc_opts)
|
||||
{
|
||||
gchar *encoder, *vpp;
|
||||
SpiceVideoCodecType codec_type = spice_encoder->base.codec_type;
|
||||
const char *codec_name = video_codecs[codec_type];
|
||||
|
||||
if (strcmp(codec_name, "vp8") == 0) {
|
||||
return;
|
||||
@ -1055,11 +1074,20 @@ static void try_intel_hw_plugins(const gchar *codec_name, gchar **converter,
|
||||
*gstenc_name = encoder;
|
||||
*gstenc_opts = get_hw_gstenc_opts(encoder, codec_name);
|
||||
|
||||
if (g_str_has_prefix(vpp, "vaapi")) {
|
||||
*converter = g_strconcat(vpp, " ! video/x-raw(memory:VASurface),format=NV12", NULL);
|
||||
} else {
|
||||
*converter = g_strconcat(vpp, " ! video/x-raw(memory:VAMemory),format=NV12", NULL);
|
||||
char format[5] = "NV12";
|
||||
if( codec_type == SPICE_VIDEO_CODEC_TYPE_AV1_444 ||
|
||||
codec_type == SPICE_VIDEO_CODEC_TYPE_H264_444 ||
|
||||
codec_type == SPICE_VIDEO_CODEC_TYPE_H265_444 ||
|
||||
codec_type == SPICE_VIDEO_CODEC_TYPE_VP9_444 ) {
|
||||
g_strlcpy(format,"VUYA",5);
|
||||
}
|
||||
|
||||
char memory[11] = "VASurface";
|
||||
if(!g_str_has_prefix(vpp, "vaapi")){
|
||||
g_strlcpy(memory,"VAMemory",11);
|
||||
}
|
||||
*converter = g_strdup_printf(" %s ! capsfilter name=vpp caps=\"video/x-raw(memory:%s),format=%s\"",
|
||||
vpp, memory,format);
|
||||
g_free(vpp);
|
||||
}
|
||||
|
||||
@ -1113,6 +1141,7 @@ static gboolean create_pipeline(SpiceGstEncoder *encoder)
|
||||
case SPICE_VIDEO_CODEC_TYPE_MJPEG:
|
||||
gstenc_opts = g_strdup("");
|
||||
break;
|
||||
case SPICE_VIDEO_CODEC_TYPE_VP9_444:
|
||||
case SPICE_VIDEO_CODEC_TYPE_VP9:
|
||||
case SPICE_VIDEO_CODEC_TYPE_VP8: {
|
||||
/* See http://www.webmproject.org/docs/encoder-parameters/
|
||||
@ -1134,6 +1163,7 @@ static gboolean create_pipeline(SpiceGstEncoder *encoder)
|
||||
gstenc_opts = g_strdup_printf("end-usage=cbr min-quantizer=10 error-resilient=default lag-in-frames=0 deadline=1 cpu-used=4");
|
||||
break;
|
||||
}
|
||||
case SPICE_VIDEO_CODEC_TYPE_H264_444:
|
||||
case SPICE_VIDEO_CODEC_TYPE_H264:
|
||||
/* - Set tune and sliced-threads to ensure a zero-frame latency
|
||||
* - qp-min ensures the bitrate does not get needlessly high.
|
||||
@ -1146,6 +1176,23 @@ static gboolean create_pipeline(SpiceGstEncoder *encoder)
|
||||
*/
|
||||
gstenc_opts = g_strdup("byte-stream=true aud=true qp-min=15 qp-max=35 tune=4 sliced-threads=true speed-preset=ultrafast intra-refresh=true");
|
||||
break;
|
||||
case SPICE_VIDEO_CODEC_TYPE_H265_444:
|
||||
case SPICE_VIDEO_CODEC_TYPE_H265:
|
||||
/* - Set tune and sliced-threads to ensure a zero-frame latency
|
||||
* - qp-min ensures the bitrate does not get needlessly high.
|
||||
* - qp-max ensures the compression does not go so high that the videoclear
|
||||
* is unrecognizable. When that threshold is reached it is better to
|
||||
* drop frames to lower the bit rate further.
|
||||
* - Set speed-preset to get realtime speed.
|
||||
* - Set intra-refresh to get more uniform compressed frame sizes,
|
||||
* thus helping with streaming.
|
||||
*/
|
||||
gstenc_opts = g_strdup("qp=15 tune=4 speed-preset=ultrafast ");
|
||||
break;
|
||||
case SPICE_VIDEO_CODEC_TYPE_AV1_444:
|
||||
case SPICE_VIDEO_CODEC_TYPE_AV1:
|
||||
gstenc_opts = g_strdup("");
|
||||
break;
|
||||
default:
|
||||
/* gstreamer_encoder_new() should have rejected this codec type */
|
||||
spice_warning("unsupported codec type %d", encoder->base.codec_type);
|
||||
@ -1154,10 +1201,9 @@ static gboolean create_pipeline(SpiceGstEncoder *encoder)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const char *codec_name = video_codecs[encoder->base.codec_type];
|
||||
GpuVendor vendor = spice_udev_detect_gpu(INTEL_VENDOR_ID);
|
||||
if (vendor == VENDOR_GPU_DETECTED) {
|
||||
try_intel_hw_plugins(codec_name, &converter, &gstenc_name,
|
||||
try_intel_hw_plugins(encoder, &converter, &gstenc_name,
|
||||
&gstenc_opts);
|
||||
}
|
||||
|
||||
@ -1673,9 +1719,9 @@ spice_gst_encoder_configure_pipeline(SpiceGstEncoder *encoder,
|
||||
return VIDEO_ENCODER_FRAME_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (width != encoder->width || height != encoder->height ||
|
||||
if ((width != encoder->width || height != encoder->height ||
|
||||
encoder->spice_format != spice_format ||
|
||||
encoder->drm_format != drm_format) {
|
||||
encoder->drm_format != drm_format) && (width > 0 && height > 0)) {
|
||||
spice_debug("video format change: width %d -> %d, height %d -> %d,"
|
||||
"spice format %d -> %d, drm format %u -> %u",
|
||||
encoder->width, width, encoder->height, height,
|
||||
@ -1716,7 +1762,7 @@ spice_gst_encoder_configure_pipeline(SpiceGstEncoder *encoder,
|
||||
if (handle_server_drops(encoder, frame_mm_time) ||
|
||||
frame_mm_time < encoder->next_frame_mm_time) {
|
||||
/* Drop the frame to limit the outgoing bit rate. */
|
||||
return VIDEO_ENCODER_FRAME_DROP;
|
||||
//return VIDEO_ENCODER_FRAME_DROP;
|
||||
}
|
||||
|
||||
if (!configure_pipeline(encoder)) {
|
||||
@ -2023,7 +2069,13 @@ VideoEncoder *gstreamer_encoder_new(SpiceVideoCodecType codec_type,
|
||||
spice_return_val_if_fail(codec_type == SPICE_VIDEO_CODEC_TYPE_MJPEG ||
|
||||
codec_type == SPICE_VIDEO_CODEC_TYPE_VP8 ||
|
||||
codec_type == SPICE_VIDEO_CODEC_TYPE_VP9 ||
|
||||
codec_type == SPICE_VIDEO_CODEC_TYPE_H264, NULL);
|
||||
codec_type == SPICE_VIDEO_CODEC_TYPE_H264||
|
||||
codec_type == SPICE_VIDEO_CODEC_TYPE_H264 ||
|
||||
codec_type == SPICE_VIDEO_CODEC_TYPE_H265 ||
|
||||
codec_type == SPICE_VIDEO_CODEC_TYPE_H264_444 ||
|
||||
codec_type == SPICE_VIDEO_CODEC_TYPE_H265_444 ||
|
||||
codec_type == SPICE_VIDEO_CODEC_TYPE_VP9_444 ||
|
||||
codec_type == SPICE_VIDEO_CODEC_TYPE_AV1, NULL);
|
||||
|
||||
GError *err = NULL;
|
||||
if (!gst_init_check(NULL, NULL, &err)) {
|
||||
|
||||
@ -3461,11 +3461,11 @@ err:
|
||||
|
||||
static const char default_renderer[] = "sw";
|
||||
#if defined(HAVE_GSTREAMER_1_0)
|
||||
#define GSTREAMER_CODECS "gstreamer:mjpeg;gstreamer:h264;gstreamer:vp8;gstreamer:vp9;"
|
||||
#define GSTREAMER_CODECS "gstreamer:h264;gstreamer:h265;gstreamer:vp8;gstreamer:vp9;gstreamer:av1;gstreamer:h265_444;gstreamer:vp9_444;gstreamer:mjpeg;"
|
||||
#else
|
||||
#define GSTREAMER_CODECS ""
|
||||
#endif
|
||||
static const char default_video_codecs[] = "spice:mjpeg;" GSTREAMER_CODECS;
|
||||
static const char default_video_codecs[] = GSTREAMER_CODECS "spice:mjpeg;";
|
||||
|
||||
/* new interface */
|
||||
SPICE_GNUC_VISIBLE SpiceServer *spice_server_new(void)
|
||||
@ -3583,6 +3583,13 @@ static const EnumNames video_codec_names[] = {
|
||||
{SPICE_VIDEO_CODEC_TYPE_VP8, "vp8"},
|
||||
{SPICE_VIDEO_CODEC_TYPE_H264, "h264"},
|
||||
{SPICE_VIDEO_CODEC_TYPE_VP9, "vp9"},
|
||||
{SPICE_VIDEO_CODEC_TYPE_H265, "h265"},
|
||||
{SPICE_VIDEO_CODEC_TYPE_AV1, "av1"},
|
||||
{SPICE_VIDEO_CODEC_TYPE_H264_444, "h264_444"},
|
||||
{SPICE_VIDEO_CODEC_TYPE_VP9_444, "vp9_444"},
|
||||
{SPICE_VIDEO_CODEC_TYPE_H265_444, "h265_444"},
|
||||
{SPICE_VIDEO_CODEC_TYPE_AV1_444, "av1_444"},
|
||||
|
||||
{0, nullptr},
|
||||
};
|
||||
|
||||
@ -3591,6 +3598,13 @@ static const int video_codec_caps[] = {
|
||||
SPICE_DISPLAY_CAP_CODEC_VP8,
|
||||
SPICE_DISPLAY_CAP_CODEC_H264,
|
||||
SPICE_DISPLAY_CAP_CODEC_VP9,
|
||||
SPICE_DISPLAY_CAP_CODEC_H265,
|
||||
SPICE_DISPLAY_CAP_CODEC_AV1,
|
||||
SPICE_DISPLAY_CAP_CODEC_H264_444,
|
||||
SPICE_DISPLAY_CAP_CODEC_VP9_444,
|
||||
SPICE_DISPLAY_CAP_CODEC_H265_444,
|
||||
SPICE_DISPLAY_CAP_CODEC_AV1_444,
|
||||
|
||||
};
|
||||
|
||||
char *reds_get_video_codec_fullname(RedVideoCodec *codec)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user