@@ -1308,6 +1308,11 @@ def on_stats(promise, abin, data):
1308
1308
try :
1309
1309
if self .aom :
1310
1310
client ['encoder' ].set_property ('target-bitrate' , int (bitrate )) # line not active due to 'elif " av1enc " in self.pipeline:' line
1311
+ elif " mpph265enc " in self .pipeline or client ['encoder' ].get_name ().startswith ('mpph265enc' ):
1312
+ # For mpph265enc, use bps instead of bitrate
1313
+ client ['encoder' ].set_property ('bps' , int (bitrate * 1000 ))
1314
+ elif " x265enc " in self .pipeline or client ['encoder' ].get_name ().startswith ('x265enc' ):
1315
+ client ['encoder' ].set_property ('bitrate' , int (bitrate ))
1311
1316
elif client ['encoder' ]:
1312
1317
client ['encoder' ].set_property ('bitrate' , int (bitrate * 1000 ))
1313
1318
elif client ['encoder1' ]:
@@ -1330,6 +1335,11 @@ def on_stats(promise, abin, data):
1330
1335
try :
1331
1336
if self .aom :
1332
1337
client ['encoder' ].set_property ('target-bitrate' , int (bitrate )) # line not active due to 'elif " av1enc " in self.pipeline:' line
1338
+ elif " mpph265enc " in self .pipeline or client ['encoder' ].get_name ().startswith ('mpph265enc' ):
1339
+ # For mpph265enc, use bps instead of bitrate
1340
+ client ['encoder' ].set_property ('bps' , int (bitrate * 1000 ))
1341
+ elif " x265enc " in self .pipeline or client ['encoder' ].get_name ().startswith ('x265enc' ):
1342
+ client ['encoder' ].set_property ('bitrate' , int (bitrate ))
1333
1343
elif client ['encoder' ]:
1334
1344
client ['encoder' ].set_property ('bitrate' , int (bitrate * 1000 ))
1335
1345
elif client ['encoder1' ]:
@@ -1975,6 +1985,9 @@ async def main():
1975
1985
parser .add_argument ('--stun-server' , type = str , help = 'STUN server URL (stun://hostname:port)' )
1976
1986
parser .add_argument ('--turn-server' , type = str , help = 'TURN server URL (turn(s)://username:password@host:port)' )
1977
1987
parser .add_argument ('--ice-transport-policy' , type = str , choices = ['all' , 'relay' ], default = 'all' , help = 'ICE transport policy (all or relay)' )
1988
+ parser .add_argument ('--h265' , action = 'store_true' , help = 'Prioritize h265/hevc encoding over h264' )
1989
+ parser .add_argument ('--hevc' , action = 'store_true' , help = 'Prioritize h265/hevc encoding over h264 (same as --h265)' )
1990
+ parser .add_argument ('--x265' , action = 'store_true' , help = 'Prioritizes x265 software encoder over hardware encoders' )
1978
1991
1979
1992
1980
1993
args = parser .parse_args ()
@@ -2224,6 +2237,12 @@ async def main():
2224
2237
2225
2238
if args .rtmp and not args .h264 :
2226
2239
args .h264 = True
2240
+
2241
+ if args .hevc :
2242
+ args .h265 = True
2243
+
2244
+ if args .x265 :
2245
+ args .h265 = True
2227
2246
2228
2247
h264 = None
2229
2248
if args .omx and check_plugins ('omxh264enc' ):
@@ -2256,8 +2275,22 @@ async def main():
2256
2275
2257
2276
if h264 :
2258
2277
print ("H264 encoder that we will try to use: " + h264 )
2259
-
2260
-
2278
+
2279
+ h265 = None
2280
+ if args .h265 :
2281
+ if args .x265 and check_plugins ('x265enc' ):
2282
+ h265 = 'x265enc'
2283
+ elif check_plugins ('mpph265enc' ):
2284
+ h265 = 'mpph265enc'
2285
+ elif check_plugins ('x265enc' ):
2286
+ h265 = 'x265enc'
2287
+ else :
2288
+ print ("Couldn't find an h265 encoder, falling back to h264" )
2289
+ args .h264 = True # Fallback to h264 if no h265 encoder found
2290
+
2291
+ if h265 :
2292
+ print ("H265 encoder that we will try to use: " + h265 )
2293
+
2261
2294
if args .hdmi :
2262
2295
args .v4l2 = '/dev/v4l/by-id/usb-MACROSILICON_*'
2263
2296
args .alsa = 'hw:MS2109'
@@ -2490,7 +2523,19 @@ async def main():
2490
2523
pipeline_video_input += f' ! videoconvert{ timestampOverlay } ! rav1enc bitrate={ args .bitrate } 000 name="encoder" low-latency=true error-resilient=true speed-preset=10 qos=true ! av1parse ! rtpav1pay'
2491
2524
elif args .qsv :
2492
2525
pipeline_video_input += f' ! videoconvert{ timestampOverlay } ! qsvav1enc gop-size=60 bitrate={ args .bitrate } name="encoder1" ! av1parse ! rtpav1pay'
2493
-
2526
+ elif args .h265 and h265 :
2527
+ if h265 == "mpph265enc" :
2528
+ # mpph265enc uses bps (bits per second) instead of bitrate
2529
+ # bps takes value in bits per second, so multiply bitrate (kbps) by 1000
2530
+ pipeline_video_input += f' ! videoconvert{ timestampOverlay } ! video/x-raw,format=NV12 ! { h265 } name="encoder" bps={ args .bitrate * 1000 } qos=true qp-init=35 qp-max=45 qp-min=20 qp-max-i=40 qp-min-i=20 rc-mode=1 ! video/x-h265,stream-format=(string)byte-stream'
2531
+ elif h265 == "x265enc" :
2532
+ # x265enc uses bitrate in kbps
2533
+ pipeline_video_input += f' ! videoconvert{ timestampOverlay } ! queue max-size-buffers=10 ! { h265 } bitrate={ args .bitrate } speed-preset=superfast tune=zerolatency key-int-max=30 name="encoder" ! video/x-h265,profile=main,stream-format=byte-stream'
2534
+
2535
+ if args .rtmp :
2536
+ pipeline_video_input += f' ! queue ! h265parse'
2537
+ else :
2538
+ pipeline_video_input += f' ! queue max-size-time=1000000000 max-size-bytes=10000000000 max-size-buffers=1000000 ! h265parse { saveVideo } ! rtph265pay config-interval=-1 ! application/x-rtp,media=video,encoding-name=H265,payload=96'
2494
2539
else :
2495
2540
if args .nvidia :
2496
2541
pipeline_video_input += f' ! nvvidconv ! video/x-raw(memory:NVMM) ! omxvp8enc bitrate={ args .bitrate } 000 control-rate="constant" name="encoder" qos=true ! rtpvp8pay ! application/x-rtp,media=video,encoding-name=VP8,payload=96'
0 commit comments