[WebRTC] Add new APIs for WebRTC transceiver codec (#4509)
authorHaesu Gwon <haesu.gwon@samsung.com>
Wed, 7 Sep 2022 06:18:49 +0000 (15:18 +0900)
committerGitHub <noreply@github.com>
Wed, 7 Sep 2022 06:18:49 +0000 (15:18 +0900)
* [WebRTC] Add new APIs for WebRTC transceiver codec

src/Tizen.Multimedia.Remoting/Interop/Interop.WebRTC.cs
src/Tizen.Multimedia.Remoting/WebRTC/MediaSource.cs
src/Tizen.Multimedia.Remoting/WebRTC/WebRTCEnums.cs

index 614c6f2..fdd6022 100755 (executable)
@@ -65,6 +65,9 @@ internal static partial class Interop
         internal delegate bool RetrieveTurnServerCallback(string server, IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool RetrieveTransceiverCodecCallback(TransceiverCodec codec, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate void SdpCreatedCallback(IntPtr handle, string sdp, IntPtr userData);
 
 
@@ -125,6 +128,16 @@ internal static partial class Interop
         [DllImport(Libraries.WebRTC, EntryPoint = "webrtc_media_source_set_transceiver_direction")]
         internal static extern WebRTCErrorCode SetTransceiverDirection(IntPtr handle, uint sourceId, MediaType type, TransceiverDirection mode);
 
+        [DllImport(Libraries.WebRTC, EntryPoint = "webrtc_media_source_foreach_supported_transceiver_codec")]
+        internal static extern WebRTCErrorCode ForeachSupportedTransceiverCodec(IntPtr handle, MediaSourceType sourceType, MediaType mediaType,
+            RetrieveTransceiverCodecCallback callback, IntPtr userData = default);
+
+        [DllImport(Libraries.WebRTC, EntryPoint = "webrtc_media_source_set_transceiver_codec")]
+        internal static extern WebRTCErrorCode SetTransceiverCodec(IntPtr handle, uint sourceId, MediaType type, TransceiverCodec codec);
+
+        [DllImport(Libraries.WebRTC, EntryPoint = "webrtc_media_source_get_transceiver_codec")]
+        internal static extern WebRTCErrorCode GetTransceiverCodec(IntPtr handle, uint sourceId, MediaType type, out TransceiverCodec codec);
+
         [DllImport(Libraries.WebRTC, EntryPoint = "webrtc_media_source_set_pause")]
         internal static extern WebRTCErrorCode SetPause(IntPtr handle, uint sourceId, MediaType type, bool pause);
 
index d91c223..4e53ee0 100755 (executable)
@@ -16,6 +16,8 @@
 
 using ElmSharp;
 using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Diagnostics;
 using static Interop;
 
@@ -103,6 +105,148 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <summary>
+        /// Gets or sets the transceiver codec of current media source.
+        /// </summary>
+        /// <remarks>
+        /// This API is not supported in <see cref="MediaFileSource"/>, <see cref="MediaPacketSource"/>.<br/>
+        /// The WebRTC must be in the <see cref="WebRTCState.Idle"/> state when transceiver codec is set.
+        /// </remarks>
+        /// <value>The transceiver codec.</value>
+        /// <exception cref="InvalidOperationException">
+        ///     MediaSource is not attached yet.<br/>
+        /// -or-<br/>
+        ///     This MediaSource is not supported type of MediaSource.<br/>
+        /// -or-<br/>
+        /// The WebRTC is not in the valid state.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The WebRTC has already been disposed.</exception>
+        /// <since_tizen> 10 </since_tizen>
+        public TransceiverCodec TransceiverCodec
+        {
+            get
+            {
+                if (!SourceId.HasValue)
+                {
+                    throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first.");
+                }
+                if (this is MediaFileSource || this is MediaPacketSource)
+                {
+                    throw new InvalidOperationException($"This property is not supported in {this.GetType()}.");
+                }
+
+                NativeWebRTC.GetTransceiverCodec(WebRtc.Handle, SourceId.Value, MediaType, out TransceiverCodec codec).
+                    ThrowIfFailed("Failed to get transceiver codec");
+
+                return codec;
+            }
+            set
+            {
+                if (!SourceId.HasValue)
+                {
+                    throw new InvalidOperationException("MediaSource is not attached yet. Call AddSource() first.");
+                }
+                if (this is MediaFileSource || this is MediaPacketSource)
+                {
+                    throw new InvalidOperationException($"This property is not supported in {this.GetType()}.");
+                }
+
+                WebRtc.ValidateWebRTCState(WebRTCState.Idle);
+
+                NativeWebRTC.SetTransceiverCodec(WebRtc.Handle, SourceId.Value, MediaType, value).
+                    ThrowIfFailed("Failed to set transceiver codec");
+            }
+        }
+
+        /// <summary>
+        /// Retrieves the supported transceiver codecs.
+        /// </summary>
+        /// <remarks>
+        /// This API is not supported in <see cref="MediaFileSource"/>, <see cref="MediaPacketSource"/>.
+        /// </remarks>
+        /// <returns>The transceiver codecs.</returns>
+        /// <exception cref="InvalidOperationException">This MediaSource is not supported type of MediaSource.</exception>
+        /// <exception cref="ObjectDisposedException">The WebRTC has already been disposed.</exception>
+        /// <since_tizen> 10 </since_tizen>
+        public ReadOnlyCollection<TransceiverCodec> SupportedTransceiverCodecs
+        {
+            get
+            {
+                if (this is MediaFileSource || this is MediaPacketSource)
+                {
+                    throw new InvalidOperationException($"This property is not supported in {this.GetType()}.");
+                }
+
+                var codecs = new List<TransceiverCodec>();
+                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))
+                {
+                    NativeWebRTC.ForeachSupportedTransceiverCodec(WebRtc.Handle, GetMediaSourceType(), MediaType, cb).
+                        ThrowIfFailed("failed to retrieve stats");
+
+                    if (caught != null)
+                    {
+                        throw caught;
+                    }
+                }
+
+                return new ReadOnlyCollection<TransceiverCodec>(codecs);
+            }
+        }
+
+        private MediaSourceType GetMediaSourceType()
+        {
+            if (this is MediaTestSource)
+            {
+                if (MediaType == MediaType.Audio)
+                {
+                    return MediaSourceType.AudioTest;
+                }
+                else
+                {
+                    return MediaSourceType.VideoTest;
+                }
+            }
+            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 MediaSourceType.MediaPacket;
+            }
+
+            return MediaSourceType.Null;
+        }
+
+        /// <summary>
         /// Gets or sets the pause status of current media source.
         /// </summary>
         /// <value>A value that specifies the pause status.</value>
index dea0dee..a20d092 100755 (executable)
@@ -304,6 +304,43 @@ namespace Tizen.Multimedia.Remoting
     }
 
     /// <summary>
+    /// Specifies the transceiver codec type.
+    /// </summary>
+    /// <since_tizen> 10 </since_tizen>
+    public enum TransceiverCodec
+    {
+        /// <summary>
+        /// PCMU.
+        /// </summary>
+        Pcmu  = 0x00000100 | 0x01,
+
+        /// <summary>
+        /// PCMA.
+        /// </summary>
+        Pcma = 0x00000100 | 0x02,
+
+        /// <summary>
+        /// OPUS.
+        /// </summary>
+        Opus = 0x00000100 | 0x03,
+
+        /// <summary>
+        /// VP8.
+        /// </summary>
+        Vp8 = 0x00000200 | 0x01,
+
+        /// <summary>
+        /// VP9.
+        /// </summary>
+        Vp9 = 0x00000200 | 0x02,
+
+        /// <summary>
+        /// H264.
+        /// </summary>
+        H264 = 0x00000200 | 0x03
+    }
+
+    /// <summary>
     /// Specifies the policy of Ice transport.
     /// </summary>
     /// <remarks>
@@ -421,7 +458,9 @@ namespace Tizen.Multimedia.Remoting
 
         File,
 
-        MediaPacket
+        MediaPacket,
+
+        Null
     }
 
     internal enum CustomMediaSourceType