From: Gaurang Khanwalkar Date: Wed, 26 Oct 2016 07:38:44 +0000 (+0530) Subject: [Multimedia-ScreenMirroring] Screen mirroring classes X-Git-Tag: submit/trunk/20170823.075128~94^2~178^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8a21971b54ed35a386ccef9af5e6fcb0640d22f2;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git [Multimedia-ScreenMirroring] Screen mirroring classes Added new Screen Mirroring classes to Tizen.Multimedia and modified Interop.Libraries.cs, Tizen.Multimedia.Net45.csproj and Tizen.Multimedia.csproj Change-Id: I0a3798d9823a3617e957bd1eadfffb19d55e2a26 Signed-off-by: Gaurang Khanwalkar --- diff --git a/src/Tizen.Multimedia/Interop/Interop.Libraries.cs b/src/Tizen.Multimedia/Interop/Interop.Libraries.cs index 861bb49..de88182 100755 --- a/src/Tizen.Multimedia/Interop/Interop.Libraries.cs +++ b/src/Tizen.Multimedia/Interop/Interop.Libraries.cs @@ -1,5 +1,18 @@ - -using System; +/* + * Copyright (c) 2016 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. + */ internal static partial class Interop { @@ -9,10 +22,13 @@ internal static partial class Interop public const string Recorder = "libcapi-media-recorder.so.0"; public const string SoundManager = "libcapi-media-sound-manager.so.0"; public const string AudioIO = "libcapi-media-audio-io.so.0"; + public const string ScreenMirroring = "libcapi-screen-mirroring-io.so.0"; public const string MetadataExtractor = "libcapi-media-metadata-extractor.so"; public const string MediaController = "libcapi-media-controller.so.0"; public const string MediaTool = "libcapi-media-tool.so.0"; public const string MediaCodec = "libcapi-media-codec.so.0"; + public const string MediaVision = "libcapi-media-vision.so.0"; public const string Libc = "libc.so.6"; + public const string Camera = "libcapi-media-camera.so.0"; } } diff --git a/src/Tizen.Multimedia/Interop/Interop.ScreenMirroring.cs b/src/Tizen.Multimedia/Interop/Interop.ScreenMirroring.cs new file mode 100755 index 0000000..87d862f --- /dev/null +++ b/src/Tizen.Multimedia/Interop/Interop.ScreenMirroring.cs @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016 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.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class ScreenMirroring + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void StateErrorCallback(IntPtr userData, int state, int error); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_create")] + internal static extern int Create(out IntPtr scmirroringSink); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_set_state_changed_cb")] + internal static extern int SetStateErrorCb(IntPtr scmirroringSink, StateErrorCallback cb, IntPtr userData); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_set_ip_and_port")] + internal static extern int SetIpAndPort(IntPtr scmirroringSink, string ip, string port); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_set_display")] + internal static extern int SetDisplay(IntPtr scmirroringSink, int type, IntPtr display); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_set_resolution")] + internal static extern int SetResolution(IntPtr scmirroringSink, int resolution); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_prepare")] + internal static extern int Prepare(IntPtr scmirroringSink); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_connect")] + internal static extern int ConnectAsync(IntPtr scmirroringSink); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_start")] + internal static extern int StartAsync(IntPtr scmirroringSink); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_pause")] + internal static extern int PauseAsync(IntPtr scmirroringSink); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_resume")] + internal static extern int ResumeAsync(IntPtr scmirroringSink); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_disconnect")] + internal static extern int Disconnect(IntPtr scmirroringSink); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_unprepare")] + internal static extern int Unprepare(IntPtr scmirroringSink); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_unset_state_changed_cb")] + internal static extern int UnsetStateErrorCb(IntPtr scmirroringSink); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_destroy")] + internal static extern int Destroy(IntPtr scmirroringSink); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_video_codec")] + internal static extern int GetNegotiatedVideoCodec(ref IntPtr scmirroringSink, out int codec); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_video_resolution")] + internal static extern int GetNegotiatedVideoResolution(ref IntPtr scmirroringSink, out int width, out int height); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_video_frame_rate")] + internal static extern int GetNegotiatedVideoFrameRate(ref IntPtr scmirroringSink, out int frameRate); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_audio_codec")] + internal static extern int GetNegotiatedAudioCodec(ref IntPtr scmirroringSink, out int codec); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_audio_channel")] + internal static extern int GetNegotiatedAudioChannel(ref IntPtr scmirroringSink, out int channel); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_audio_sample_rate")] + internal static extern int GetNegotiatedAudioSampleRate(ref IntPtr scmirroringSink, out int sampleRate); + + [DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_get_negotiated_audio_bitwidth")] + internal static extern int GetNegotiatedAudioBitwidth(ref IntPtr scmirroringSink, out int bitwidth); + } +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/ScreenMirroring/AudioInformation.cs b/src/Tizen.Multimedia/ScreenMirroring/AudioInformation.cs new file mode 100755 index 0000000..447febf --- /dev/null +++ b/src/Tizen.Multimedia/ScreenMirroring/AudioInformation.cs @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016 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.Runtime.InteropServices; + +namespace Tizen.Multimedia +{ + /// + /// Audio Information + /// + /// + /// This class provides properties and API that are required for setting + /// audio information of a player. + /// + public class AudioInformation + { + internal IntPtr _handle; + private int _codec; + private int _channel; + private int _sampleRate; + private int _bitWidth; + + internal AudioInformation() + { + } + + /// + /// Get Audio Codec. + /// + /// Audio Codec + public AudioCodec Codec + { + get + { + int ret; + ret = Interop.ScreenMirroring.GetNegotiatedAudioCodec(ref _handle, out _codec); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Failed to get audio codec" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "failed to get audio codec"); + } + + return (AudioCodec)_codec; + } + } + + /// + /// Get audio channel. + /// + /// AudioChannel + public int Channel + { + get + { + int ret; + ret = Interop.ScreenMirroring.GetNegotiatedAudioChannel(ref _handle, out _channel); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Failed to get audio channel" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "failed to get audio channel"); + } + + return _channel; + } + } + + /// + /// Get audio sample rate. + /// + /// AudioSampleRate + public int SampleRate + { + get + { + int ret; + ret = Interop.ScreenMirroring.GetNegotiatedAudioSampleRate(ref _handle, out _sampleRate); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Failed to get audio sample rate" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "failed to get audio sample rate"); + } + + return _sampleRate; + } + } + + /// + /// Get audio bitwidth. + /// + /// AudioBitwidth + public int BitWidth + { + get + { + int ret; + ret = Interop.ScreenMirroring.GetNegotiatedAudioBitwidth(ref _handle, out _bitWidth); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Failed to get audio bitwidth" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "failed to get audio bitwidth"); + } + + return _bitWidth; + } + } + } +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/ScreenMirroring/ErrorOccurredEventArgs.cs b/src/Tizen.Multimedia/ScreenMirroring/ErrorOccurredEventArgs.cs new file mode 100755 index 0000000..a24d9f2 --- /dev/null +++ b/src/Tizen.Multimedia/ScreenMirroring/ErrorOccurredEventArgs.cs @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016 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; + +namespace Tizen.Multimedia +{ + /// + /// ErrorOccurred event arguments + /// + /// + /// ErrorOccurred event arguments + /// + public class ErrorOccurredEventArgs : EventArgs + { + internal int _error; + + /// + /// Constructor. + /// + /// Error Occurred + internal ErrorOccurredEventArgs(int error) + { + _error = error; + } + + /// + /// Get the error code. + /// + /// error code + public SCMirroringError Error + { + get + { + return (SCMirroringError)_error; + } + } + } +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/ScreenMirroring/ScreenMirroring.cs b/src/Tizen.Multimedia/ScreenMirroring/ScreenMirroring.cs new file mode 100755 index 0000000..11b93b3 --- /dev/null +++ b/src/Tizen.Multimedia/ScreenMirroring/ScreenMirroring.cs @@ -0,0 +1,540 @@ +/* + * Copyright (c) 2016 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.Threading.Tasks; +using System.Runtime.InteropServices; + +namespace Tizen.Multimedia +{ + static internal class ScreenMirroringLog + { + internal const string LogTag = "Tizen.Multimedia.ScreenMirroring"; + } + + /// + /// Screen mirroring. + /// + public class ScreenMirroring : IDisposable + { + internal VideoInformation _videoInfo; + internal AudioInformation _audioInfo; + internal IntPtr _handle; + internal string _ip; + internal string _port; + internal SurfaceType _type; + internal MediaView _display; + + private bool _disposed = false; + private EventHandler _stateChanged; + private Interop.ScreenMirroring.StateErrorCallback _stateErrorCallback; + private EventHandler _errorOccurred; + + /// + /// Initializes a new instance of the ScreenMirroring class with parameters Ip, Port, Surface type and Display handle. + /// Object should be created only when Ip and Port are available. + /// Create api will create a new handle with the given parameters. + /// + /// Type. + /// Display. + /// Ip. + /// Port. + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + public ScreenMirroring(SurfaceType type, MediaView display, string ip, string port) + { + int ret = Interop.ScreenMirroring.Create(out _handle); + if (ret != (int)SCMirroringError.None) + { + ScreenMirroringErrorFactory.ThrowException(ret, "Failed to create Screen Mirroring Sink"); + } + + // initiate values + _ip = ip; + _port = port; + _type = type; + _display = display; + + // Set ip and port + int ret1 = Interop.ScreenMirroring.SetIpAndPort(_handle, _ip, _port); + if (ret1 != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Set ip and port failed" + (SCMirroringError)ret1); + ScreenMirroringErrorFactory.ThrowException(ret, "set ip and port failed"); + } + + // Set display + int ret2 = Interop.ScreenMirroring.SetDisplay(_handle, (int)_type, _display); + if (ret2 != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Set display failed" + (SCMirroringError)ret2); + ScreenMirroringErrorFactory.ThrowException(ret, "set display failed"); + } + + // AudioInfo + _audioInfo = new AudioInformation(); + _audioInfo._handle = _handle; + // VideoInfo + _videoInfo = new VideoInformation(); + _videoInfo._handle = _handle; + + Log.Debug(ScreenMirroringLog.LogTag, "screen mirroring sink created : " + _handle); + } + + /// + /// Screen Mirroring destructor. + /// + ~ScreenMirroring() + { + Dispose(false); + } + + /// + /// StateChanged event is raised when state change happens. + /// Must be called after Create() API. + /// + public event EventHandler StateChanged + { + add + { + if (_stateChanged == null) + { + RegisterStateChangedEvent(); + } + + _stateChanged += value; + } + + remove + { + _stateChanged -= value; + if (_stateChanged == null) + { + UnregisterStateChangedEvent(); + } + } + } + + /// + /// ErrorOccurred event is raised when error is occured in screen mirroring sink. + /// Must be called after Create() API. + /// + public event EventHandler ErrorOccurred + { + add + { + if (_errorOccurred == null) + { + RegisterErrorOccurredEvent(); + } + + _errorOccurred += value; + } + + remove + { + _errorOccurred -= value; + if (_errorOccurred == null) + { + UnregisterErrorOccurredEvent(); + } + } + } + + /// + /// Sets the server ip and port. + /// This must be called before connect() and after create(). + /// + /// If only one handle is used for toggling between more than two source devices, + /// then this API ahould be used to assign the parameters to the handle. + /// + /// Ip. + /// Port. + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + public void SetIpAndPort(string ip, string port) + { + int ret = Interop.ScreenMirroring.SetIpAndPort(_handle, ip, port); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Set ip and port failed" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "set ip and port failed"); + } + } + + /// + /// Set Resolution. + /// valid state: NULL.. + /// + /// example: (R1920x1080P30 | R1280x720P30) + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + public void SetResolution(int resolution) + { + int ret = Interop.ScreenMirroring.SetResolution(_handle, resolution); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Set resolution failed" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "set resolution failed"); + } + } + + /// + /// Sets the display. + /// This must be called before prepare() and after create(). + /// + /// If only one handle is used for toggling between more than two source devices, + /// then this API ahould be used to assign the parameters to the handle. + /// + /// Type. + /// Display. + /// Display Handle not clear + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + public void SetDisplay(SurfaceType type, MediaView display) + { + int ret = Interop.ScreenMirroring.SetDisplay(_handle, (int)type, display); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Set display failed" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "set display failed"); + } + } + + /// + /// Prepare this instance. + /// This must be called after Create(). + /// + public void Prepare() + { + int ret = Interop.ScreenMirroring.Prepare(_handle); + if (ret != (int)SCMirroringError.None) + { + ScreenMirroringErrorFactory.ThrowException(ret, "Failed to prepare sink for screen mirroring"); + } + } + + /// + /// Creates connection and prepare for receiving data from SCMIRRORING source. + /// This must be called after prepare(). + /// + /// It will not give the current state. Need to subscribe for event to get the current state + /// bool value + /// http://tizen.org/privilege/internet + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + public Task ConnectAsync() + { + int ret = Interop.ScreenMirroring.ConnectAsync(_handle); + var task = new TaskCompletionSource(); + + Task.Factory.StartNew(() => + { + if (ret == (int)SCMirroringError.None) + { + task.SetResult(true); + } + + else if (ret != (int)SCMirroringError.None) + { + task.SetResult(false); + ScreenMirroringErrorFactory.ThrowException(ret, "Failed to connect the screen mirroring source"); + } + }); + + return task.Task; + } + + /// + /// Get AudioInfo. + /// This must be called after connectasync(). + /// valid states: connected/playback/paused. + /// If audio file changes during playback again + /// then the current info should be retrieved from the audio information class. + /// + /// AudioInfo object + public AudioInformation AudioInfo + { + get + { + return _audioInfo; + } + } + + /// + /// Get VideoInfo. + /// This must be called after connectasync(). + /// valid states: connected/playback/paused. + /// If video file changes during playback again + /// then the current info should be retrieved from the video information class. + /// + /// VideoInfo object + public VideoInformation VideoInfo + { + get + { + return _videoInfo; + } + } + + /// + /// Start receiving data from the SCMIRRORING source and display it(Mirror). + /// This must be called after connectasync(). + /// + /// It will not give the current state. Need to subscribe for event to get the current state + /// bool value + /// http://tizen.org/privilege/internet + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + public Task StartAsync() + { + int ret = Interop.ScreenMirroring.StartAsync(_handle); + var task = new TaskCompletionSource(); + + Task.Factory.StartNew(() => + { + if (ret == (int)SCMirroringError.None) + { + task.SetResult(true); + } + + else if (ret != (int)SCMirroringError.None) + { + task.SetResult(false); + ScreenMirroringErrorFactory.ThrowException(ret, "Failed to start the screen mirroring"); + } + }); + + return task.Task; + } + + /// + /// Pauses receiving data from the SCMIRRORING source. + /// This must be called after startasync(). + /// + /// It will not give the current state. Need to subscribe for event to get the current state + /// bool value + /// http://tizen.org/privilege/internet + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + public Task PauseAsync() + { + int ret = Interop.ScreenMirroring.PauseAsync(_handle); + var task = new TaskCompletionSource(); + + Task.Factory.StartNew(() => + { + if (ret == (int)SCMirroringError.None) + { + task.SetResult(true); + } + + else if (ret != (int)SCMirroringError.None) + { + task.SetResult(false); + ScreenMirroringErrorFactory.ThrowException(ret, "Failed to pause the receiving data from screen mirroring source"); + } + }); + + return task.Task; + } + + /// + /// Resumes receiving data from the SCMIRRORING source. + /// This must be called after pauseasync(). + /// + /// It will not give the current state. Need to subscribe for event to get the current state + /// bool value + /// http://tizen.org/privilege/internet + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + public Task ResumeAsync() + { + int ret = Interop.ScreenMirroring.ResumeAsync(_handle); + var task = new TaskCompletionSource(); + + Task.Factory.StartNew(() => + { + if (ret == (int)SCMirroringError.None) + { + task.SetResult(true); + } + + else if (ret != (int)SCMirroringError.None) + { + task.SetResult(false); + ScreenMirroringErrorFactory.ThrowException(ret, "Failed to resume the receiving data from screen mirroring source"); + } + }); + + return task.Task; + } + + /// + /// Disconnect this instance. + /// valid states: connected/playing/paused + /// + /// http://tizen.org/privilege/internet + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + public void Disconnect() + { + int ret = Interop.ScreenMirroring.Disconnect(_handle); + if (ret != (int)SCMirroringError.None) + { + ScreenMirroringErrorFactory.ThrowException(ret, "Failed to disconnect sink for screen mirroring"); + } + } + + /// + /// Unprepare this instance. + /// valid states: prepared/disconnected. + /// + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + public void Unprepare() + { + int ret = Interop.ScreenMirroring.Unprepare(_handle); + if (ret != (int)SCMirroringError.None) + { + ScreenMirroringErrorFactory.ThrowException(ret, "Failed to reset the screen mirroring sink"); + } + } + + /// + /// Releases all resource used by the object. + /// + /// Call when you are finished using the . + /// The method leaves the in an unusable + /// state. After calling , you must release all references to the + /// so the garbage collector can reclaim the memory that the + /// was occupying. + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Dispose the specified handle. + /// + /// If set to true disposing. + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + // To be used if there are any other disposable objects + } + + if (_handle != IntPtr.Zero) + { + Interop.ScreenMirroring.Destroy(_handle); + _handle = IntPtr.Zero; + } + + _disposed = true; + } + } + + /// + /// Invoke the event for state or error. + /// + /// state + /// error + private void StateError(int state, int error) + { + ///if _stateChanged is subscribe, this will be invoke. + StateChangedEventArgs eventArgsState = new StateChangedEventArgs(state); + _stateChanged?.Invoke(this, eventArgsState); + + ///if _errorOccurred is subscribe, this will be invoke. + ErrorOccurredEventArgs eventArgsError = new ErrorOccurredEventArgs(error); + _errorOccurred?.Invoke(this, eventArgsError); + } + + /// + /// Registers the state changed event. + /// + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + private void RegisterStateChangedEvent() + { + _stateErrorCallback = (IntPtr userData, int state, int error) => + { + StateError(state, error); + }; + + int ret = Interop.ScreenMirroring.SetStateErrorCb(_handle, _stateErrorCallback, IntPtr.Zero); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Setting StateChanged callback failed" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "Setting StateChanged callback failed"); + } + } + + /// + /// Unregisters the state changed event. + /// + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + private void UnregisterStateChangedEvent() + { + int ret = Interop.ScreenMirroring.UnsetStateErrorCb(_handle); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Unsetting StateChnaged callback failed" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "Unsetting StateChanged callback failed"); + } + } + + /// + /// Registers the error occurred event. + /// + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + private void RegisterErrorOccurredEvent() + { + _stateErrorCallback = (IntPtr userData, int state, int error) => + { + StateError(state, error); + }; + + int ret = Interop.ScreenMirroring.SetStateErrorCb(_handle, _stateErrorCallback, IntPtr.Zero); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Setting ErrorOccurred callback failed" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "Setting ErrorOccurred callback failed"); + } + } + + /// + /// Unregisters the error occurred event. + /// + /// Thrown when method fail due to an invalid parameter + /// Thrown when method fail due to an internal error + private void UnregisterErrorOccurredEvent() + { + int ret = Interop.ScreenMirroring.UnsetStateErrorCb(_handle); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Unsetting ErrorOccurred callback failed" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "Unsetting ErrorOccurred callback failed"); + } + } + } +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/ScreenMirroring/ScreenMirroringEnumerations.cs b/src/Tizen.Multimedia/ScreenMirroring/ScreenMirroringEnumerations.cs new file mode 100755 index 0000000..90d9ac4 --- /dev/null +++ b/src/Tizen.Multimedia/ScreenMirroring/ScreenMirroringEnumerations.cs @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2016 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. + */ + +namespace Tizen.Multimedia +{ + /// + /// Enumeration for audio codec. + /// + public enum AudioCodec + { + /// + /// Screen mirroring is not negotiated yet + /// + None, + /// + /// AAC codec for audio + /// + Aac, + /// + /// AC3 codec for audio + /// + Ac3, + /// + /// LPCM codec for audio + /// + Lpcm + } + /// + /// Enumeration for video codec. + /// + public enum VideoCodec + { + /// + /// Screen mirroring is not negotiated yet + /// + None, + /// + /// H.264 codec for video + /// + H264 + } + /// + /// Enumeration for display surface type. + /// + public enum SurfaceType + { + /// + /// Use overlay surface to display streaming multimedia data + /// + Overlay, + /// + /// Use Evas pixmap surface to display streaming multimedia data + /// + Evas + } + + /// + /// Enumeration for screen mirroring resolution. + /// + public enum ResolutionType + { + /// + /// W-1920, H-1080, 30 fps + /// + R1920x1080P30 = (1 << 0), + /// + /// W-1280, H-720, 30 fps + /// + R1280x720P30 = (1 << 1), + /// + /// W-960, H-540, 30 fps + /// + R960x540P30 = (1 << 2), + /// + /// W-864, H-480, 30 fps + /// + R864x480P30 = (1 << 3), + /// + /// W-720, H-480, 60 fps + /// + R720x480P60 = (1 << 4), + /// + /// W-640, H-480, 60 fps + /// + R640x480P60 = (1 << 5), + /// + /// W-640, H-360, 30 fps + /// + R640x360P30 = (1 << 6) + } + + /// + /// Enumeration for screen mirroring sink state + /// + public enum SCMirroringSinkState + { + /// + /// Screen mirroring is not created yet + /// + None, + /// + /// Screen mirroring is created, but not prepared yet + /// + Null, + /// + /// Screen mirroring is prepared to play media + /// + Prepared, + /// + /// Screen mirroring is connected + /// + Connected, + /// + /// Screen mirroring is now playing media + /// + Playing, + /// + /// Screen mirroring is paused while playing media + /// + Paused, + /// + /// Screen mirroring is disconnected + /// + Disconnected + } + + /// + /// Enumeration for screen mirroring error. + /// + public enum SCMirroringError + { + /// + /// Successful + /// + None, + /// + /// Invalid parameter + /// + InvalidParameter, + /// + /// Out of memory + /// + OutOfMemory, + /// + /// Invalid operation + /// + InvalidOperation, + /// + /// Connection timeout + /// + ConnectionTimeOut, + /// + /// Permission denied + /// + PermissionDenied, + /// + /// Not supported + /// + NotSupported, + /// + /// Unknown error + /// + Unknown + } +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/ScreenMirroring/ScreenMirroringErrorFactory.cs b/src/Tizen.Multimedia/ScreenMirroring/ScreenMirroringErrorFactory.cs new file mode 100755 index 0000000..85af382 --- /dev/null +++ b/src/Tizen.Multimedia/ScreenMirroring/ScreenMirroringErrorFactory.cs @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016 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; + +namespace Tizen.Multimedia +{ + public class ScreenMirroringErrorFactory + { + internal static void ThrowException(int errorCode, string errorMessage = null, string paramName = null) + { + SCMirroringError err = (SCMirroringError)errorCode; + if (string.IsNullOrEmpty(errorMessage)) + { + errorMessage = err.ToString(); + } + + switch ((SCMirroringError)errorCode) + { + case SCMirroringError.InvalidParameter: + throw new ArgumentException(errorMessage, paramName); + + case SCMirroringError.OutOfMemory: + case SCMirroringError.InvalidOperation: + case SCMirroringError.ConnectionTimeOut: + case SCMirroringError.PermissionDenied: + case SCMirroringError.NotSupported: + case SCMirroringError.Unknown: + throw new InvalidOperationException(errorMessage); + } + } + } +} + diff --git a/src/Tizen.Multimedia/ScreenMirroring/StateChangedEventArgs.cs b/src/Tizen.Multimedia/ScreenMirroring/StateChangedEventArgs.cs new file mode 100755 index 0000000..fe4a2ff --- /dev/null +++ b/src/Tizen.Multimedia/ScreenMirroring/StateChangedEventArgs.cs @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016 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; + +namespace Tizen.Multimedia +{ + /// + /// StateChanged event arguments + /// + /// + /// StateChanged event arguments + /// + public class StateChangedEventArgs : EventArgs + { + internal int _state; + + /// + /// Constructor. + /// + /// State Changed + internal StateChangedEventArgs(int state) + { + _state = state; + } + + /// + /// Get the current state. + /// + /// current state + public SCMirroringSinkState State + { + get + { + return (SCMirroringSinkState)_state; + } + } + } +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/ScreenMirroring/VideoInformation.cs b/src/Tizen.Multimedia/ScreenMirroring/VideoInformation.cs new file mode 100755 index 0000000..d462cb7 --- /dev/null +++ b/src/Tizen.Multimedia/ScreenMirroring/VideoInformation.cs @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016 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.Runtime.InteropServices; + +namespace Tizen.Multimedia +{ + /// + /// Video Information + /// + /// + /// This class provides properties and API that are required for setting + /// video information of a player. + /// + public class VideoInformation + { + internal IntPtr _handle; + private int _codec; + private int _height; + private int _width; + private int _frameRate; + + internal VideoInformation() + { + } + + /// + /// Get video Codec. + /// + /// Video Codec + public VideoCodec Codec + { + get + { + int ret; + ret = Interop.ScreenMirroring.GetNegotiatedVideoCodec(ref _handle, out _codec); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Failed to get video codec" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "failed to get video codec"); + } + + return (VideoCodec)_codec; + } + } + + /// + /// Get height of video resolution. + /// + /// Video Resolution Height + public int Height + { + get + { + int ret; + ret = Interop.ScreenMirroring.GetNegotiatedVideoResolution(ref _handle, out _width, out _height); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Failed to get height" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "failed to get video height"); + } + + return _height; + } + } + + /// + /// Get width of video resolution. + /// + /// Video Resolution Width + public int Width + { + get + { + int ret; + ret = Interop.ScreenMirroring.GetNegotiatedVideoResolution(ref _handle, out _width, out _height); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Failed to get width" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "failed to get video width"); + } + + return _width; + } + } + + /// + /// Get width of video frame rate. + /// + /// Video FrameRate + public int FrameRate + { + get + { + int ret; + ret = Interop.ScreenMirroring.GetNegotiatedVideoFrameRate(ref _handle, out _frameRate); + if (ret != (int)SCMirroringError.None) + { + Log.Error(ScreenMirroringLog.LogTag, "Failed to get frame rate" + (SCMirroringError)ret); + ScreenMirroringErrorFactory.ThrowException(ret, "failed to get video frame rate"); + } + + return _frameRate; + } + } + } +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/Tizen.Multimedia.Net45.csproj b/src/Tizen.Multimedia/Tizen.Multimedia.Net45.csproj index bd71381..884e54c 100755 --- a/src/Tizen.Multimedia/Tizen.Multimedia.Net45.csproj +++ b/src/Tizen.Multimedia/Tizen.Multimedia.Net45.csproj @@ -52,11 +52,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -68,6 +114,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -100,7 +193,6 @@ - @@ -129,6 +221,14 @@ + + + + + + + + diff --git a/src/Tizen.Multimedia/Tizen.Multimedia.csproj b/src/Tizen.Multimedia/Tizen.Multimedia.csproj index a46db69..6b65b67 100755 --- a/src/Tizen.Multimedia/Tizen.Multimedia.csproj +++ b/src/Tizen.Multimedia/Tizen.Multimedia.csproj @@ -49,11 +49,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -64,6 +110,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -105,7 +198,6 @@ - @@ -151,6 +243,14 @@ + + + + + + + + @@ -177,4 +277,4 @@ <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory) true - \ No newline at end of file +