@@ -82,6 +82,9 @@ private set
8282
8383 public RTCRtpSender VideoSender { get ; private set ; }
8484
85+ // Full: 704×576 -> half: 352×288 -> quarter: 176×144 <- We want the smallest resolution to be above 96x96
86+ public static VideoResolution MinimumSafeTargetResolution => new VideoResolution ( 704 , 576 ) ;
87+
8588 public StreamPeerConnection ( ILogs logs , StreamPeerType peerType , IEnumerable < ICEServer > iceServers ,
8689 IMediaInputProvider mediaInputProvider , IStreamAudioConfig audioConfig ,
8790 PublisherVideoSettings publisherVideoSettings , Tracer tracer )
@@ -223,6 +226,18 @@ public void Update()
223226 }
224227
225228 public Task < RTCStatsReport > GetStatsReportAsync ( ) => _peerConnection . GetStatsAsync ( ) ;
229+
230+ public PublisherVideoSettings GetLatestVideoSettings ( )
231+ {
232+ if ( _publisherVideoSettings == null )
233+ {
234+ throw new ArgumentNullException ( $ "{ nameof ( _publisherVideoSettings ) } is null in { nameof ( GetLatestVideoSettings ) } ") ;
235+ }
236+
237+ _publisherVideoSettings . MaxResolution = PublisherTargetResolution ;
238+ _publisherVideoSettings . FrameRate = PublisherTargetFrameRate ;
239+ return _publisherVideoSettings ;
240+ }
226241
227242 public void Dispose ( )
228243 {
@@ -275,14 +290,53 @@ public void Dispose()
275290 private const string VideoCodecKeyH264 = "h264" ;
276291 private const string VideoCodecKeyVP8 = "vp8" ;
277292 private const string AudioCodecKeyRed = "red" ;
293+
294+ private VideoResolution PublisherTargetResolution
295+ {
296+ get
297+ {
298+ if ( _mediaInputProvider . VideoInput != null )
299+ {
300+ var preferred = new VideoResolution ( _mediaInputProvider . VideoInput . width ,
301+ _mediaInputProvider . VideoInput . height ) ;
302+
303+ // Requesting too small resolution can cause crashes in the Android video encoder
304+ // The target resolution is used to calculate 3 layers of video encoding (full, half, quarter)
305+ // For very small values of quarter resolution (not sure exact but ~100x100) the encoder crashes
306+
307+ if ( preferred . Width < MinimumSafeTargetResolution . Width ||
308+ preferred . Height < MinimumSafeTargetResolution . Height )
309+ {
310+ return MinimumSafeTargetResolution ;
311+ }
312+ }
313+
314+ return _publisherVideoSettings . MaxResolution ;
315+ }
316+ }
317+
318+ private uint PublisherTargetFrameRate
319+ {
320+ get
321+ {
322+ if ( _mediaInputProvider . VideoInput != null )
323+ {
324+ return ( uint ) _mediaInputProvider . VideoInput . requestedFPS ;
325+ }
326+
327+ return 30 ;
328+ }
329+ }
278330
279331 private readonly RTCPeerConnection _peerConnection ;
280332
281333 private readonly ILogs _logs ;
282334 private readonly StreamPeerType _peerType ;
283335 private readonly IMediaInputProvider _mediaInputProvider ;
284336 private readonly IStreamAudioConfig _audioConfig ;
285- private readonly PublisherVideoSettings _publisherVideoSettings ;
337+
338+ //StreamTOdo: Finish implementation. This currently is not exposed to the user + it doesn't take into account VideoInput resolution. We need publisher resolution to match with WebCamTexture size
339+ private readonly PublisherVideoSettings _publisherVideoSettings ;
286340 private readonly Tracer _tracer ;
287341
288342 private readonly List < RTCIceCandidate > _pendingIceCandidates = new List < RTCIceCandidate > ( ) ;
@@ -360,6 +414,7 @@ private void OnTrack(RTCTrackEvent trackEvent)
360414 var streamIds = trackEvent . Streams != null && trackEvent . Streams . Any ( )
361415 ? string . Join ( "," , trackEvent . Streams . Select ( s => s . Id ) )
362416 : "" ;
417+ var isEnabled = trackEvent . Track . Enabled ;
363418
364419 if ( ! string . IsNullOrEmpty ( streamIds ) )
365420 {
@@ -587,6 +642,10 @@ private static IEnumerable<RTCRtpEncodingParameters> GetVideoEncodingParameters(
587642
588643 break ;
589644 case TrackKind . Video :
645+
646+ //StreamTodo: construct fewer layer when the target resolution is small. Android video encoder crashes when requesting very small resolution
647+ // We're currently forcing the smallest safe resolution that the user can request so that the quarter layer doesn't reach too small resolution
648+ // But we should allow setting small resolution and just produce fewer layers in that case
590649
591650 var fullQuality = new RTCRtpEncodingParameters
592651 {
@@ -631,17 +690,6 @@ private static IEnumerable<RTCRtpEncodingParameters> GetVideoEncodingParameters(
631690 }
632691 }
633692
634- private VideoResolution GetPublisherResolution ( )
635- {
636- if ( _mediaInputProvider . VideoInput != null )
637- {
638- var maxResolution = _publisherVideoSettings . MaxResolution ;
639- return new VideoResolution ( maxResolution . Width , maxResolution . Height ) ;
640- }
641-
642- return VideoResolution . Res_1080p ;
643- }
644-
645693 private VideoStreamTrack CreatePublisherVideoTrack ( )
646694 {
647695 if ( _mediaInputProvider . VideoInput == null )
@@ -653,7 +701,7 @@ private VideoStreamTrack CreatePublisherVideoTrack()
653701 var gfxType = SystemInfo . graphicsDeviceType ;
654702 var format = WebRTC . GetSupportedRenderTextureFormat ( gfxType ) ;
655703
656- var res = GetPublisherResolution ( ) ;
704+ var res = PublisherTargetResolution ;
657705 _publisherVideoTrackTexture = new RenderTexture ( ( int ) res . Width , ( int ) res . Height , 0 , format ) ;
658706
659707#if STREAM_DEBUG_ENABLED
0 commit comments