@@ -112,7 +112,8 @@ def add_bandwidth_limit(self, rate_kbps: int) -> None:
112112 idx ,
113113 root = True ,
114114 rate = f"{ rate_kbps } kbit" ,
115- burst = 32768 , # 32KB
115+ # 32KB
116+ burst = 32768 ,
116117 latency = "50ms" ,
117118 )
118119 self ._bandwidth_applied = True
@@ -276,9 +277,13 @@ def show_webrtc_stats(stats: list) -> None:
276277 print ("\n WebRTC 統計情報:" )
277278 for stat in stats :
278279 if stat .get ("type" ) == "outbound-rtp" :
279- print (" outbound-rtp:" )
280+ rid = stat .get ("rid" , "" )
281+ rid_label = f" (rid={ rid } )" if rid else ""
282+ print (f" outbound-rtp{ rid_label } :" )
280283 print (f" ssrc: { stat .get ('ssrc' )} " )
281284 print (f" kind: { stat .get ('kind' )} " )
285+ if rid :
286+ print (f" rid: { rid } " )
282287 print (f" bytesSent: { stat .get ('bytesSent' )} " )
283288 print (f" packetsSent: { stat .get ('packetsSent' )} " )
284289 if "targetBitrate" in stat :
@@ -324,28 +329,40 @@ def test_tc_egress_bandwidth_limit(settings):
324329 # 制限前の WebRTC 統計情報を確認
325330 print ("\n 制限前の WebRTC 統計情報:" )
326331 time .sleep (3 )
327- stats_before = sendonly .get_stats ()
328- show_webrtc_stats (stats_before )
329-
330- # 制限前の targetBitrate を確認 (video のみ)
331- outbound_rtp_before = next (
332- (
333- stat
334- for stat in stats_before
335- if stat .get ("type" ) == "outbound-rtp" and stat .get ("kind" ) == "video"
336- ),
337- None ,
332+ stats = sendonly .get_stats ()
333+ show_webrtc_stats (stats )
334+
335+ # 制限前の targetBitrate を確認 (video の全ての outbound-rtp を取得)
336+ simulcast_outbound_rtp_stats = [
337+ stat
338+ for stat in stats
339+ if stat .get ("type" ) == "outbound-rtp" and stat .get ("kind" ) == "video"
340+ ]
341+ assert len (simulcast_outbound_rtp_stats ) > 0 , "outbound-rtp (video) が取得できませんでした"
342+
343+ # rid でソート (r0, r1, r2 の順)
344+ simulcast_outbound_rtp_stats .sort (key = lambda x : x .get ("rid" , "" ))
345+
346+ # simulcast が有効な場合は 3 つのストリーム (r0, r1, r2) が存在するはず
347+ assert len (simulcast_outbound_rtp_stats ) == 3 , (
348+ f"simulcast のストリーム数が不正: { len (simulcast_outbound_rtp_stats )} (期待値: 3)"
338349 )
339- assert outbound_rtp_before is not None , "outbound-rtp (video) が取得できませんでした"
340- assert "targetBitrate" in outbound_rtp_before , "targetBitrate が存在しません"
341350
342- target_bitrate_before = outbound_rtp_before [ " targetBitrate" ]
351+ print ( " \n 制限前の targetBitrate:" )
343352 print (
344- f"\n 制限前の targetBitrate : { target_bitrate_before } bps ({ target_bitrate_before / 1000 } kbps)"
353+ f" rid= { simulcast_outbound_rtp_stats [ 0 ]. get ( 'rid' , 'none' ) } : { simulcast_outbound_rtp_stats [ 0 ][ 'targetBitrate' ] } bps ({ simulcast_outbound_rtp_stats [ 0 ][ 'targetBitrate' ] / 1000 } kbps)"
345354 )
346- # video_bit_rate を指定しているので、MIN_BITRATE_BEFORE_LIMIT_KBPS 以上あることを確認
347- assert target_bitrate_before >= MIN_BITRATE_BEFORE_LIMIT_KBPS * 1000 , (
348- f"制限前の targetBitrate が想定より低い: { target_bitrate_before } bps < { MIN_BITRATE_BEFORE_LIMIT_KBPS * 1000 } bps"
355+ print (
356+ f" rid={ simulcast_outbound_rtp_stats [1 ].get ('rid' , 'none' )} : { simulcast_outbound_rtp_stats [1 ]['targetBitrate' ]} bps ({ simulcast_outbound_rtp_stats [1 ]['targetBitrate' ] / 1000 } kbps)"
357+ )
358+ print (
359+ f" rid={ simulcast_outbound_rtp_stats [2 ].get ('rid' , 'none' )} : { simulcast_outbound_rtp_stats [2 ]['targetBitrate' ]} bps ({ simulcast_outbound_rtp_stats [2 ]['targetBitrate' ] / 1000 } kbps)"
360+ )
361+
362+ # r2 (最高画質) のビットレートが MIN_BITRATE_BEFORE_LIMIT_KBPS 以上あることを確認
363+ r2_bitrate = simulcast_outbound_rtp_stats [2 ]["targetBitrate" ]
364+ assert r2_bitrate >= MIN_BITRATE_BEFORE_LIMIT_KBPS * 1000 , (
365+ f"制限前の r2 targetBitrate が想定より低い: { r2_bitrate } bps < { MIN_BITRATE_BEFORE_LIMIT_KBPS * 1000 } bps"
349366 )
350367
351368 # tc egress で帯域制限を設定
@@ -376,28 +393,52 @@ def test_tc_egress_bandwidth_limit(settings):
376393
377394 # WebRTC 統計情報を表示
378395 print ("\n ステップ 4: 制限後の WebRTC 統計情報を確認" )
379- stats_after = sendonly .get_stats ()
380- show_webrtc_stats (stats_after )
381-
382- # targetBitrate を確認 (video のみ)
383- stats = stats_after
384- outbound_rtp = next (
385- (
386- stat
387- for stat in stats
388- if stat .get ("type" ) == "outbound-rtp" and stat .get ("kind" ) == "video"
389- ),
390- None ,
396+ stats = sendonly .get_stats ()
397+ show_webrtc_stats (stats )
398+
399+ # targetBitrate を確認 (video の全ての outbound-rtp を取得)
400+ simulcast_outbound_rtp_stats = [
401+ stat
402+ for stat in stats
403+ if stat .get ("type" ) == "outbound-rtp" and stat .get ("kind" ) == "video"
404+ ]
405+ assert len (simulcast_outbound_rtp_stats ) > 0 , (
406+ "outbound-rtp (video) が取得できませんでした"
391407 )
392- assert outbound_rtp is not None , "outbound-rtp (video) が取得できませんでした"
393- assert "targetBitrate" in outbound_rtp , "targetBitrate が存在しません"
394408
395- target_bitrate = outbound_rtp ["targetBitrate" ]
396- print (f"\n 確認: targetBitrate = { target_bitrate } bps ({ target_bitrate / 1000 } kbps)" )
409+ # rid でソート (r0, r1, r2 の順)
410+ simulcast_outbound_rtp_stats .sort (key = lambda x : x .get ("rid" , "" ))
411+
412+ # simulcast が有効な場合は 3 つのストリーム (r0, r1, r2) が存在するはず
413+ assert len (simulcast_outbound_rtp_stats ) == 3 , (
414+ f"simulcast のストリーム数が不正: { len (simulcast_outbound_rtp_stats )} (期待値: 3)"
415+ )
416+
417+ print ("\n 制限後の targetBitrate:" )
418+ print (
419+ f" rid={ simulcast_outbound_rtp_stats [0 ].get ('rid' , 'none' )} : { simulcast_outbound_rtp_stats [0 ]['targetBitrate' ]} bps ({ simulcast_outbound_rtp_stats [0 ]['targetBitrate' ] / 1000 } kbps)"
420+ )
421+ print (
422+ f" rid={ simulcast_outbound_rtp_stats [1 ].get ('rid' , 'none' )} : { simulcast_outbound_rtp_stats [1 ]['targetBitrate' ]} bps ({ simulcast_outbound_rtp_stats [1 ]['targetBitrate' ] / 1000 } kbps)"
423+ )
424+ print (
425+ f" rid={ simulcast_outbound_rtp_stats [2 ].get ('rid' , 'none' )} : { simulcast_outbound_rtp_stats [2 ]['targetBitrate' ]} bps ({ simulcast_outbound_rtp_stats [2 ]['targetBitrate' ] / 1000 } kbps)"
426+ )
427+
428+ # 全てのストリームの targetBitrate の合計を確認
429+ total_target_bitrate = (
430+ simulcast_outbound_rtp_stats [0 ]["targetBitrate" ]
431+ + simulcast_outbound_rtp_stats [1 ]["targetBitrate" ]
432+ + simulcast_outbound_rtp_stats [2 ]["targetBitrate" ]
433+ )
434+ print (
435+ f"\n 確認: 合計 targetBitrate = { total_target_bitrate } bps ({ total_target_bitrate / 1000 } kbps)"
436+ )
397437 print (f"期待値: { BANDWIDTH_LIMIT_KBPS } kbps 以下" )
438+
398439 # 帯域制限が効いているか確認(多少のオーバーヘッドを考慮)
399- assert target_bitrate <= BANDWIDTH_LIMIT_KBPS * 1000 * 1.2 , (
400- f"targetBitrate が帯域制限を超えています: { target_bitrate } bps > { BANDWIDTH_LIMIT_KBPS * 1000 } bps"
440+ assert total_target_bitrate <= BANDWIDTH_LIMIT_KBPS * 1000 * 1.2 , (
441+ f"合計 targetBitrate が帯域制限を超えています: { total_target_bitrate } bps > { BANDWIDTH_LIMIT_KBPS * 1000 } bps"
401442 )
402443
403444 print ("\n 帯域制限が有効な状態でテスト完了" )
0 commit comments