From 5a4d22b6938477b6e44a3a424d4ac50b2082498c Mon Sep 17 00:00:00 2001 From: Haesu Gwon Date: Thu, 22 Sep 2022 08:57:53 +0900 Subject: [PATCH] [WebRTC] Add new APIs for MediaNullSource and change MediaFileSource ctor (#4558) * [WebRTC] Add new APIs for MediaNullSource and change MediaFileSource ctor --- .../WebRTC/MediaCameraSource.cs | 2 + .../WebRTC/MediaFileSource.cs | 98 ++++++++++- .../WebRTC/MediaMicrophoneSource.cs | 2 + .../WebRTC/MediaNullSource.cs | 131 ++++++++++++++ .../WebRTC/MediaPacketSource.cs | 2 + .../WebRTC/MediaScreenSource.cs | 2 + .../WebRTC/MediaSource.cs | 196 ++++++++++++++------- .../WebRTC/MediaTestSource.cs | 8 +- 8 files changed, 375 insertions(+), 66 deletions(-) create mode 100755 src/Tizen.Multimedia.Remoting/WebRTC/MediaNullSource.cs diff --git a/src/Tizen.Multimedia.Remoting/WebRTC/MediaCameraSource.cs b/src/Tizen.Multimedia.Remoting/WebRTC/MediaCameraSource.cs index c6829b3..50a3411 100755 --- a/src/Tizen.Multimedia.Remoting/WebRTC/MediaCameraSource.cs +++ b/src/Tizen.Multimedia.Remoting/WebRTC/MediaCameraSource.cs @@ -91,5 +91,7 @@ namespace Tizen.Multimedia.Remoting WebRtc = null; } + + internal override MediaSourceType MediaSourceType => MediaSourceType.Camera; } } diff --git a/src/Tizen.Multimedia.Remoting/WebRTC/MediaFileSource.cs b/src/Tizen.Multimedia.Remoting/WebRTC/MediaFileSource.cs index 1c6ba9e..24c52ff 100755 --- a/src/Tizen.Multimedia.Remoting/WebRTC/MediaFileSource.cs +++ b/src/Tizen.Multimedia.Remoting/WebRTC/MediaFileSource.cs @@ -37,11 +37,10 @@ namespace Tizen.Multimedia.Remoting /// /// Initializes a new instance of the class. /// - /// The of file source. /// The file path. /// is null. /// 10 - public MediaFileSource(MediaType type, string path) : base(type) + public MediaFileSource(string path) : base() { _path = path ?? throw new ArgumentNullException(nameof(path), "path is null"); } @@ -82,6 +81,99 @@ namespace Tizen.Multimedia.Remoting } } + /// + /// Gets the transceiver direction for receiving media stream. + /// + /// The media type. + /// The transceiver direction. + /// MediaSource is not attached yet. + /// The WebRTC has already been disposed. + /// 10 + public TransceiverDirection GetTransceiverDirection(MediaType type) + { + if (!SourceId.HasValue) + { + throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); + } + + NativeWebRTC.GetTransceiverDirection(WebRtc.Handle, SourceId.Value, type, out TransceiverDirection direction). + ThrowIfFailed("Failed to get transceiver direction."); + + return direction; + } + + /// + /// Sets the transceiver direction for receiving media stream. + /// + /// + /// The WebRTC must be in the state when transceiver direction is set. + /// + /// The media type. + /// The transceiver direction. + /// + /// MediaSource is not attached yet.
+ /// -or-
+ /// The WebRTC is not in the valid state. + ///
+ /// The WebRTC has already been disposed. + /// 10 + public void SetTransceiverDirection(MediaType type, TransceiverDirection direction) + { + if (!SourceId.HasValue) + { + throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); + } + + WebRtc.ValidateWebRTCState(WebRTCState.Idle); + + NativeWebRTC.SetTransceiverDirection(WebRtc.Handle, SourceId.Value, type, direction). + ThrowIfFailed("Failed to set transceiver direction"); + } + + /// + /// Gets the pause status of media file source. + /// + /// The media type. + /// The pause status. + /// MediaSource is not attached yet. + /// The WebRTC has already been disposed. + /// 10 + public bool GetPause(MediaType type) + { + if (!SourceId.HasValue) + { + throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); + } + + WebRtc.ValidateWebRTCState(WebRTCState.Idle); + + NativeWebRTC.GetPause(WebRtc.Handle, SourceId.Value, MediaType, out bool isPaused). + ThrowIfFailed("Failed to get pause"); + + return isPaused; + } + + /// + /// Sets the pause status of media file source. + /// + /// The media type. + /// The pause status. + /// MediaSource is not attached yet. + /// The WebRTC has already been disposed. + /// 10 + public void SetPause(MediaType type, bool isPaused) + { + if (!SourceId.HasValue) + { + throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); + } + + WebRtc.ValidateWebRTCState(WebRTCState.Idle); + + NativeWebRTC.SetPause(WebRtc.Handle, SourceId.Value, type, isPaused). + ThrowIfFailed("Failed to set pause"); + } + internal override void OnAttached(WebRTC webRtc) { Debug.Assert(webRtc != null); @@ -108,5 +200,7 @@ namespace Tizen.Multimedia.Remoting WebRtc = null; } + + internal override MediaSourceType MediaSourceType => MediaSourceType.File; } } diff --git a/src/Tizen.Multimedia.Remoting/WebRTC/MediaMicrophoneSource.cs b/src/Tizen.Multimedia.Remoting/WebRTC/MediaMicrophoneSource.cs index e5adf91..d4cd5d0 100755 --- a/src/Tizen.Multimedia.Remoting/WebRTC/MediaMicrophoneSource.cs +++ b/src/Tizen.Multimedia.Remoting/WebRTC/MediaMicrophoneSource.cs @@ -59,6 +59,8 @@ namespace Tizen.Multimedia.Remoting WebRtc = (WebRTC)null; } + internal override MediaSourceType MediaSourceType => MediaSourceType.Microphone; + /// /// Applies the audio stream policy to . /// diff --git a/src/Tizen.Multimedia.Remoting/WebRTC/MediaNullSource.cs b/src/Tizen.Multimedia.Remoting/WebRTC/MediaNullSource.cs new file mode 100755 index 0000000..9100998 --- /dev/null +++ b/src/Tizen.Multimedia.Remoting/WebRTC/MediaNullSource.cs @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.ObjectModel; +using System.Diagnostics; +using NativeWebRTC = Interop.NativeWebRTC; + +namespace Tizen.Multimedia.Remoting +{ + /// Represents a null source. + /// + /// If you add this source, WebRTC only receives media stream.
+ /// is set by default. + ///
+ /// + /// 10 + public sealed class MediaNullSource : MediaSource + { + /// + /// Initializes a new instance of the class. + /// + /// TransceiverCodec should be set to receive audio, video stream. + /// + /// 10 + public MediaNullSource() : base() {} + + /// + /// Gets the transceiver codec for receiving media stream. + /// + /// The media type. + /// The transceiver codec. + /// MediaSource is not attached yet. + /// The WebRTC has already been disposed. + /// + /// 10 + public TransceiverCodec GetTransceiverCodec(MediaType type) + { + if (!SourceId.HasValue) + { + throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); + } + + NativeWebRTC.GetTransceiverCodec(WebRtc.Handle, SourceId.Value, type, out TransceiverCodec codec). + ThrowIfFailed("Failed to get transceiver codec"); + + return codec; + } + + /// + /// Sets the transceiver codec for receiving media stream. + /// + /// + /// The WebRTC must be in the state when transceiver codec is set.
+ /// + ///
+ /// The media type. + /// The transceiver codec. + /// + /// MediaSource is not attached yet.
+ /// -or-
+ /// The WebRTC is not in the valid state. + ///
+ /// The WebRTC has already been disposed. + /// + /// 10 + public void SetTransceiverCodec(MediaType type, TransceiverCodec codec) + { + if (!SourceId.HasValue) + { + throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); + } + + WebRtc.ValidateWebRTCState(WebRTCState.Idle); + + NativeWebRTC.SetTransceiverCodec(WebRtc.Handle, SourceId.Value, type, codec). + ThrowIfFailed("Failed to set transceiver codec"); + } + + /// + /// Retrieves the supported transceiver codecs. + /// + /// The media type. + /// The supported transceiver codecs. + /// This MediaSource is not supported type of MediaSource. + /// The WebRTC has already been disposed. + /// 10 + public ReadOnlyCollection GetSupportedTransceiverCodecs(MediaType type) + { + return new ReadOnlyCollection(ForeachSupportedTransceiverCodecs(type)); + } + + internal override void OnAttached(WebRTC webRtc) + { + Debug.Assert(webRtc != null); + + if (WebRtc != null) + { + throw new InvalidOperationException("The source is has already been assigned to another WebRTC."); + } + + NativeWebRTC.AddMediaSource(webRtc.Handle, MediaSourceType.Null, out uint sourceId). + ThrowIfFailed("Failed to add MediaNullSource."); + + WebRtc = webRtc; + SourceId = sourceId; + TransceiverDirection = TransceiverDirection.RecvOnly; + } + + internal override void OnDetached(WebRTC webRtc) + { + NativeWebRTC.RemoveMediaSource(webRtc.Handle, SourceId.Value). + ThrowIfFailed("Failed to remove MediaNullSource."); + + WebRtc = null; + } + } +} diff --git a/src/Tizen.Multimedia.Remoting/WebRTC/MediaPacketSource.cs b/src/Tizen.Multimedia.Remoting/WebRTC/MediaPacketSource.cs index 0f54275..6ead6c7 100755 --- a/src/Tizen.Multimedia.Remoting/WebRTC/MediaPacketSource.cs +++ b/src/Tizen.Multimedia.Remoting/WebRTC/MediaPacketSource.cs @@ -283,5 +283,7 @@ namespace Tizen.Multimedia.Remoting WebRtc = null; } + + internal override MediaSourceType MediaSourceType => MediaSourceType.MediaPacket; } } diff --git a/src/Tizen.Multimedia.Remoting/WebRTC/MediaScreenSource.cs b/src/Tizen.Multimedia.Remoting/WebRTC/MediaScreenSource.cs index 41d23fe2..f9af677 100755 --- a/src/Tizen.Multimedia.Remoting/WebRTC/MediaScreenSource.cs +++ b/src/Tizen.Multimedia.Remoting/WebRTC/MediaScreenSource.cs @@ -57,5 +57,7 @@ namespace Tizen.Multimedia.Remoting WebRtc = null; } + + internal override MediaSourceType MediaSourceType => MediaSourceType.Screen; } } diff --git a/src/Tizen.Multimedia.Remoting/WebRTC/MediaSource.cs b/src/Tizen.Multimedia.Remoting/WebRTC/MediaSource.cs index d843633..df3af92 100755 --- a/src/Tizen.Multimedia.Remoting/WebRTC/MediaSource.cs +++ b/src/Tizen.Multimedia.Remoting/WebRTC/MediaSource.cs @@ -50,6 +50,12 @@ namespace Tizen.Multimedia.Remoting MediaType = mediaType; } + /// + /// Initializes a new instance of the class. + /// + /// 10 + protected MediaSource() { } + internal void AttachTo(WebRTC webRtc) { if (IsDetached) @@ -70,12 +76,25 @@ namespace Tizen.Multimedia.Remoting internal abstract void OnDetached(WebRTC webRtc); + internal virtual MediaSourceType MediaSourceType => MediaSourceType.Null; + /// /// Gets or sets the transceiver direction of current media source. /// + /// + /// If user want to set each audio, video direction in , + /// please use . (Since API level 10)
+ /// In , only can be set.(Since API level 10) + ///
/// A that specifies the transceiver direction. - /// MediaSource is not attached yet. + /// + /// MediaSource is not attached yet.
+ /// -or-
+ /// or is set for MediaNullSource. (Since API level 10) + ///
/// The WebRTC has already been disposed. + /// + /// /// 9 public TransceiverDirection TransceiverDirection { @@ -85,6 +104,10 @@ namespace Tizen.Multimedia.Remoting { throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); } + if (this is MediaNullSource) + { + return TransceiverDirection.RecvOnly; + } NativeWebRTC.GetTransceiverDirection(WebRtc.Handle, SourceId.Value, MediaType, out TransceiverDirection mode). ThrowIfFailed("Failed to get transceiver direction."); @@ -97,9 +120,28 @@ namespace Tizen.Multimedia.Remoting { throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); } + if (this is MediaNullSource) + { + if (value != TransceiverDirection.RecvOnly) + { + throw new InvalidOperationException("Only RecvOnly is allowed for MediaNullSource."); + } - NativeWebRTC.SetTransceiverDirection(WebRtc.Handle, SourceId.Value, MediaType, value). - ThrowIfFailed("Failed to get transceiver direction."); + return; + } + + if (this is MediaNullSource || this is MediaFileSource) + { + NativeWebRTC.SetTransceiverDirection(WebRtc.Handle, SourceId.Value, MediaType.Audio, value). + ThrowIfFailed("Failed to set audio transceiver direction."); + NativeWebRTC.SetTransceiverDirection(WebRtc.Handle, SourceId.Value, MediaType.Video, value). + ThrowIfFailed("Failed to set video transceiver direction."); + } + else + { + NativeWebRTC.SetTransceiverDirection(WebRtc.Handle, SourceId.Value, MediaType, value). + ThrowIfFailed("Failed to set transceiver direction."); + } } } @@ -108,6 +150,8 @@ namespace Tizen.Multimedia.Remoting /// /// /// This API is not supported in , .
+ /// If , please use + /// or instead.
/// The WebRTC must be in the state when transceiver codec is set. ///
/// The transceiver codec. @@ -119,6 +163,8 @@ namespace Tizen.Multimedia.Remoting /// The WebRTC is not in the valid state. /// /// The WebRTC has already been disposed. + /// + /// /// 10 public TransceiverCodec TransceiverCodec { @@ -128,7 +174,7 @@ namespace Tizen.Multimedia.Remoting { throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); } - if (this is MediaFileSource || this is MediaPacketSource) + if (this is MediaFileSource || this is MediaPacketSource || this is MediaNullSource) { throw new InvalidOperationException($"This property is not supported in {this.GetType()}."); } @@ -144,7 +190,7 @@ namespace Tizen.Multimedia.Remoting { throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); } - if (this is MediaFileSource || this is MediaPacketSource) + if (this is MediaFileSource || this is MediaPacketSource || this is MediaNullSource) { throw new InvalidOperationException($"This property is not supported in {this.GetType()}."); } @@ -160,11 +206,14 @@ namespace Tizen.Multimedia.Remoting /// Retrieves the supported transceiver codecs. /// /// - /// This API is not supported in , . + /// This API is not supported in , .
+ /// If user want to get supported codecs for each audio or video in , + /// please use instead. ///
/// The transceiver codecs. /// This MediaSource is not supported type of MediaSource. /// The WebRTC has already been disposed. + /// /// 10 public ReadOnlyCollection SupportedTransceiverCodecs { @@ -174,83 +223,73 @@ namespace Tizen.Multimedia.Remoting { throw new InvalidOperationException($"This property is not supported in {this.GetType()}."); } - - var codecs = new List(); - Exception caught = null; - - NativeWebRTC.RetrieveTransceiverCodecCallback cb = (codec, _) => - { - try - { - codecs.Add(codec); - } - catch (Exception e) - { - caught = e; - return false; - } - - return true; - }; - - using (var cbKeeper = ObjectKeeper.Get(cb)) + if (this is MediaNullSource) { - NativeWebRTC.ForeachSupportedTransceiverCodec(WebRtc.Handle, GetMediaSourceType(), MediaType, cb). - ThrowIfFailed("failed to retrieve stats"); + var codecs = ForeachSupportedTransceiverCodecs(MediaType.Audio); + codecs.AddRange(ForeachSupportedTransceiverCodecs(MediaType.Video)); - if (caught != null) - { - throw caught; - } + return new ReadOnlyCollection(codecs); } - return new ReadOnlyCollection(codecs); + return new ReadOnlyCollection(ForeachSupportedTransceiverCodecs(MediaType)); } } - private MediaSourceType GetMediaSourceType() + internal List ForeachSupportedTransceiverCodecs(MediaType type) { - if (this is MediaTestSource) + var codecs = new List(); + Exception caught = null; + + NativeWebRTC.RetrieveTransceiverCodecCallback cb = (codec, _) => { - if (MediaType == MediaType.Audio) + try { - return MediaSourceType.AudioTest; + codecs.Add(codec); } - else + catch (Exception e) { - return MediaSourceType.VideoTest; + caught = e; + return false; } - } - else if (this is MediaMicrophoneSource) - { - return MediaSourceType.Microphone; - } - else if (this is MediaCameraSource) - { - return MediaSourceType.Camera; - } - else if (this is MediaScreenSource) - { - return MediaSourceType.Screen; - } - else if (this is MediaFileSource) - { - return MediaSourceType.File; - } - else if (this is MediaPacketSource) + + return true; + }; + + using (var cbKeeper = ObjectKeeper.Get(cb)) { - return MediaSourceType.MediaPacket; + try + { + NativeWebRTC.ForeachSupportedTransceiverCodec(WebRtc.Handle, MediaSourceType.Null, type, cb). + ThrowIfFailed("failed to retrieve stats"); + } + catch + { + Log.Info(WebRTCLog.Tag, "This is not error in csharp."); + } + + if (caught != null) + { + throw caught; + } } - return MediaSourceType.Null; + return codecs; } /// /// Gets or sets the pause status of current media source. /// + /// If , please use + /// or instead.
(Since API level 10) /// A value that specifies the pause status. - /// MediaSource is not attached yet. + /// + /// MediaSource is not attached yet.
+ /// -or-
+ /// This MediaSource is not supported type of MediaSource. (Since API level 10) + ///
/// The WebRTC has already been disposed. + /// + /// /// 9 public bool Pause { @@ -260,6 +299,10 @@ namespace Tizen.Multimedia.Remoting { throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); } + if (this is MediaFileSource || this is MediaNullSource) + { + throw new InvalidOperationException($"This property is not supported in {this.GetType()}."); + } NativeWebRTC.GetPause(WebRtc.Handle, SourceId.Value, MediaType, out bool isPaused). ThrowIfFailed("Failed to get pause"); @@ -272,6 +315,10 @@ namespace Tizen.Multimedia.Remoting { throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); } + if (this is MediaFileSource || this is MediaNullSource) + { + throw new InvalidOperationException($"This property is not supported in {this.GetType()}."); + } NativeWebRTC.SetPause(WebRtc.Handle, SourceId.Value, MediaType, value). ThrowIfFailed("Failed to set pause"); @@ -281,8 +328,15 @@ namespace Tizen.Multimedia.Remoting /// /// Gets or sets the mute status of the current media source. /// + /// + /// This API is not supported in , , . (Since API level 10) + /// /// A value that specifies the mute status. - /// MediaSource is not attached yet. + /// + /// MediaSource is not attached yet.
+ /// -or-
+ /// This MediaSource is not supported type of MediaSource. (Since API level 10) + ///
/// The WebRTC has already been disposed. /// 9 public bool Mute @@ -293,6 +347,10 @@ namespace Tizen.Multimedia.Remoting { throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); } + if (this is MediaFileSource || this is MediaPacketSource || this is MediaNullSource) + { + throw new InvalidOperationException($"This property is not supported in {this.GetType()}."); + } NativeWebRTC.GetMute(WebRtc.Handle, SourceId.Value, MediaType, out bool isMuted). ThrowIfFailed("Failed to get mute"); @@ -305,6 +363,10 @@ namespace Tizen.Multimedia.Remoting { throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first."); } + if (this is MediaFileSource || this is MediaPacketSource || this is MediaNullSource) + { + throw new InvalidOperationException($"This property is not supported in {this.GetType()}."); + } NativeWebRTC.SetMute(WebRtc.Handle, SourceId.Value, MediaType, value). ThrowIfFailed("Failed to set mute"); @@ -319,6 +381,8 @@ namespace Tizen.Multimedia.Remoting /// MediaSource is not attached yet.
/// -or-
/// This MediaSource is not Video. + /// -or-
+ /// This MediaSource is not supported type of MediaSource. /// /// The WebRTC has already been disposed. /// 9 @@ -334,6 +398,10 @@ namespace Tizen.Multimedia.Remoting { throw new InvalidOperationException("This property is only for video."); } + if (this is MediaFileSource || this is MediaPacketSource) + { + throw new InvalidOperationException($"This property is not supported in {this.GetType()}."); + } NativeWebRTC.GetVideoResolution(WebRtc.Handle, SourceId.Value, out int width, out int height). ThrowIfFailed("Failed to get video resolution"); @@ -350,6 +418,10 @@ namespace Tizen.Multimedia.Remoting { throw new InvalidOperationException("This property is only for video."); } + if (this is MediaFileSource || this is MediaPacketSource) + { + throw new InvalidOperationException($"This property is not supported in {this.GetType()}."); + } NativeWebRTC.SetVideoResolution(WebRtc.Handle, SourceId.Value, value.Width, value.Height). ThrowIfFailed("Failed to set video resolution"); @@ -424,7 +496,7 @@ namespace Tizen.Multimedia.Remoting /// Gets or sets the encoder bitrate of the current media source. /// /// - /// This API is not supported in , .
+ /// This API is not supported in , . ///
/// A value that specifies the encoder bitrate. /// EncoderBitrate is less than or equal to zero. diff --git a/src/Tizen.Multimedia.Remoting/WebRTC/MediaTestSource.cs b/src/Tizen.Multimedia.Remoting/WebRTC/MediaTestSource.cs index 84f38bd..d3226b8 100755 --- a/src/Tizen.Multimedia.Remoting/WebRTC/MediaTestSource.cs +++ b/src/Tizen.Multimedia.Remoting/WebRTC/MediaTestSource.cs @@ -28,6 +28,8 @@ namespace Tizen.Multimedia.Remoting /// 9 public sealed class MediaTestSource : MediaSource { + private MediaSourceType _mediaSourceType; + /// /// Initializes a new instance of the class. /// @@ -42,9 +44,9 @@ namespace Tizen.Multimedia.Remoting throw new InvalidOperationException("The source is has already been assigned to another WebRTC."); } - var type = MediaType == MediaType.Video ? MediaSourceType.VideoTest : MediaSourceType.AudioTest; + _mediaSourceType = MediaType == MediaType.Video ? MediaSourceType.VideoTest : MediaSourceType.AudioTest; - NativeWebRTC.AddMediaSource(webRtc.Handle, type, out uint sourceId). + NativeWebRTC.AddMediaSource(webRtc.Handle, _mediaSourceType, out uint sourceId). ThrowIfFailed($"Failed to add {MediaType.ToString()} MediaTestSource."); WebRtc = webRtc; @@ -58,5 +60,7 @@ namespace Tizen.Multimedia.Remoting WebRtc = null; } + + internal override MediaSourceType MediaSourceType => _mediaSourceType; } } -- 2.7.4