Skip to content

Commit 0b8181d

Browse files
feat(video): add support for legacy MPEG-2 and H.263+ encoders
1 parent f81a495 commit 0b8181d

12 files changed

Lines changed: 494 additions & 46 deletions

File tree

docs/configuration.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,6 +2124,85 @@ editing the `conf` file in a text editor. Use the examples as reference.
21242124
</tr>
21252125
</table>
21262126

2127+
### mpeg2_mode
2128+
2129+
<table>
2130+
<tr>
2131+
<td>Description</td>
2132+
<td colspan="2">
2133+
Allows compatibility clients to request MPEG-2/H.262 video streams. Automatic mode keeps this legacy codec
2134+
below H.264, HEVC, and AV1 by not advertising it unless explicitly forced. When forced, Sunshine may use a
2135+
legacy-capable fallback encoder for MPEG-2 streams without changing the encoder used for modern codecs.
2136+
@warning{MPEG-2 may be more CPU-intensive to encode than modern hardware-accelerated codecs when hardware
2137+
encoding is unavailable.}
2138+
</td>
2139+
</tr>
2140+
<tr>
2141+
<td>Default</td>
2142+
<td colspan="2">@code{}
2143+
0
2144+
@endcode</td>
2145+
</tr>
2146+
<tr>
2147+
<td>Example</td>
2148+
<td colspan="2">@code{}
2149+
mpeg2_mode = 2
2150+
@endcode</td>
2151+
</tr>
2152+
<tr>
2153+
<td rowspan="3">Choices</td>
2154+
<td>0</td>
2155+
<td>preserve modern codec automatic selection and keep MPEG-2 unadvertised</td>
2156+
</tr>
2157+
<tr>
2158+
<td>1</td>
2159+
<td>do not advertise support for MPEG-2</td>
2160+
</tr>
2161+
<tr>
2162+
<td>2</td>
2163+
<td>advertise support for MPEG-2/H.262 video</td>
2164+
</tr>
2165+
</table>
2166+
2167+
### h263p_mode
2168+
2169+
<table>
2170+
<tr>
2171+
<td>Description</td>
2172+
<td colspan="2">
2173+
Allows compatibility clients to request H.263+ video streams. Automatic mode keeps this legacy codec below
2174+
H.264, HEVC, and AV1 by not advertising it unless explicitly forced. When forced, Sunshine may use a
2175+
legacy-capable fallback encoder for H.263+ streams without changing the encoder used for modern codecs.
2176+
@warning{H.263+ uses software encoding in Sunshine and may reduce host performance.}
2177+
</td>
2178+
</tr>
2179+
<tr>
2180+
<td>Default</td>
2181+
<td colspan="2">@code{}
2182+
0
2183+
@endcode</td>
2184+
</tr>
2185+
<tr>
2186+
<td>Example</td>
2187+
<td colspan="2">@code{}
2188+
h263p_mode = 2
2189+
@endcode</td>
2190+
</tr>
2191+
<tr>
2192+
<td rowspan="3">Choices</td>
2193+
<td>0</td>
2194+
<td>preserve modern codec automatic selection and keep H.263+ unadvertised</td>
2195+
</tr>
2196+
<tr>
2197+
<td>1</td>
2198+
<td>do not advertise support for H.263+</td>
2199+
</tr>
2200+
<tr>
2201+
<td>2</td>
2202+
<td>advertise support for H.263+ video</td>
2203+
</tr>
2204+
</table>
2205+
21272206
### capture
21282207

21292208
<table>

src/config.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,8 @@ namespace config {
454454

455455
0, // hevc_mode
456456
0, // av1_mode
457+
0, // mpeg2_mode
458+
0, // h263p_mode
457459

458460
2, // min_threads
459461
{
@@ -1101,6 +1103,8 @@ namespace config {
11011103
int_f(vars, "qp", video.qp);
11021104
int_between_f(vars, "hevc_mode", video.hevc_mode, {0, 3});
11031105
int_between_f(vars, "av1_mode", video.av1_mode, {0, 3});
1106+
int_between_f(vars, "mpeg2_mode", video.mpeg2_mode, {0, 2});
1107+
int_between_f(vars, "h263p_mode", video.h263p_mode, {0, 2});
11041108
int_f(vars, "min_threads", video.min_threads);
11051109
string_f(vars, "sw_preset", video.sw.sw_preset);
11061110
if (!video.sw.sw_preset.empty()) {

src/config.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ namespace config {
3636
// ffmpeg params
3737
int qp; // higher == more compression and less quality
3838

39-
int hevc_mode;
40-
int av1_mode;
39+
int hevc_mode; ///< HEVC codec advertisement mode.
40+
int av1_mode; ///< AV1 codec advertisement mode.
41+
int mpeg2_mode; ///< MPEG-2 codec advertisement mode.
42+
int h263p_mode; ///< H.263+ codec advertisement mode.
4143

4244
int min_threads; // Minimum number of threads/slices for CPU encoding
4345

src/nvhttp.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,12 @@ namespace nvhttp {
714714
if ((video::active_av1_mode == 4 || video::active_av1_mode == 5) && video::last_encoder_probe_supported_yuv444_for_codec[2]) {
715715
codec_mode_flags |= SCM_AV1_HIGH10_444;
716716
}
717+
if (video::active_mpeg2_mode >= 2) {
718+
codec_mode_flags |= SCM_MPEG2;
719+
}
720+
if (video::active_h263p_mode == 2) {
721+
codec_mode_flags |= SCM_H263P;
722+
}
717723
return codec_mode_flags;
718724
}
719725

src/rtsp.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,14 @@ namespace rtsp_stream {
815815
ss << "a=rtpmap:98 AV1/90000"sv << std::endl;
816816
}
817817

818+
if (video::active_mpeg2_mode >= 2) {
819+
ss << "a=rtpmap:98 MPV/90000"sv << std::endl;
820+
}
821+
822+
if (video::active_h263p_mode == 2) {
823+
ss << "a=rtpmap:98 H263-1998/90000"sv << std::endl;
824+
}
825+
818826
if (!session.surround_params.empty()) {
819827
// If we have our own surround parameters, advertise them twice first
820828
ss << "a=fmtp:97 surround-params="sv << session.surround_params << std::endl;
@@ -1115,20 +1123,34 @@ namespace rtsp_stream {
11151123
config.monitor.bitrate = (int) configuredBitrateKbps;
11161124
}
11171125

1118-
if (config.monitor.videoFormat == 1 && video::active_hevc_mode == 1) {
1126+
if (config.monitor.videoFormat == video::format_hevc && video::active_hevc_mode == 1) {
11191127
BOOST_LOG(warning) << "HEVC is disabled, yet the client requested HEVC"sv;
11201128

11211129
respond(sock, session, &option, 400, "BAD REQUEST", req->sequenceNumber, {});
11221130
return;
11231131
}
11241132

1125-
if (config.monitor.videoFormat == 2 && video::active_av1_mode == 1) {
1133+
if (config.monitor.videoFormat == video::format_av1 && video::active_av1_mode == 1) {
11261134
BOOST_LOG(warning) << "AV1 is disabled, yet the client requested AV1"sv;
11271135

11281136
respond(sock, session, &option, 400, "BAD REQUEST", req->sequenceNumber, {});
11291137
return;
11301138
}
11311139

1140+
if (config.monitor.videoFormat == video::format_mpeg2 && video::active_mpeg2_mode < 2) {
1141+
BOOST_LOG(warning) << "MPEG-2 is disabled, yet the client requested MPEG-2"sv;
1142+
1143+
respond(sock, session, &option, 400, "BAD REQUEST", req->sequenceNumber, {});
1144+
return;
1145+
}
1146+
1147+
if (config.monitor.videoFormat == video::format_h263p && video::active_h263p_mode != 2) {
1148+
BOOST_LOG(warning) << "H.263+ is disabled, yet the client requested H.263+"sv;
1149+
1150+
respond(sock, session, &option, 400, "BAD REQUEST", req->sequenceNumber, {});
1151+
return;
1152+
}
1153+
11321154
// Check that any required encryption is enabled
11331155
auto encryption_mode = net::encryption_mode_for_address(sock.remote_endpoint().address());
11341156
if (encryption_mode == config::ENCRYPTION_MODE_MANDATORY &&

0 commit comments

Comments
 (0)