/*
* Copyright (c) 2021 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.Diagnostics;
using static Interop;
namespace Tizen.Multimedia.Remoting
{
///
/// Provides the ability to control audio/video track.
///
/// 9
public sealed class MediaStreamTrack : IDisplayable
{
private WebRTC _webRtc;
private uint _trackId;
private Display _display;
internal MediaStreamTrack(WebRTC webRtc, MediaType type, uint trackId)
{
_webRtc = webRtc;
_trackId = trackId;
Type = type;
}
///
/// Gets the the of media stream track.
///
///
/// 9
public MediaType Type { get; }
private WebRTCErrorCode SetDisplay(Display display)
=> display.ApplyTo(this);
private void ReplaceDisplay(Display newDisplay)
{
_display?.SetOwner(null);
_display = newDisplay;
_display?.SetOwner(this);
}
///
/// Gets or sets the display to show remote video.
///
/// A that specifies the display.
///
/// If user set video source with , must be set.
/// If not, the received video will fill entire screen.
/// If remote track, must be set in event.
/// The display is created with .
///
/// http://tizen.org/feature/display
/// The required feature is not supported.
/// The WebRTC has already been disposed of.
/// The value has already been assigned to another WebRTC.
///
/// The WebRTC is not called in event.
/// -or-
/// This MediaStreamTrack is not Video.
///
/// 9
public Display Display
{
get
{
if (!Features.IsSupported(WebRTCFeatures.Display))
{
throw new NotSupportedException("Display feature is not supported.");
}
return _display;
}
set
{
if (!Features.IsSupported(WebRTCFeatures.Display))
{
throw new NotSupportedException("Display feature is not supported.");
}
if (Type != MediaType.Video)
{
throw new InvalidOperationException("This property is only for video track.");
}
if (value == null)
{
throw new ArgumentNullException(nameof(value), "Display cannot be null.");
}
if (value?.Owner != null)
{
if (ReferenceEquals(this, value.Owner))
{
throw new ArgumentException("The display has already been assigned to another.");
}
}
else
{
SetDisplay(value).ThrowIfFailed("Failed to configure display of the MediaStreamTrack");
ReplaceDisplay(value);
}
}
}
WebRTCErrorCode IDisplayable.ApplyEvasDisplay(DisplayType type, ElmSharp.EvasObject evasObject)
{
Debug.Assert(Enum.IsDefined(typeof(DisplayType), type));
Debug.Assert(type != DisplayType.None);
return NativeWebRTC.SetDisplay(_webRtc.Handle, _trackId,
type == DisplayType.Overlay ? WebRTCDisplayType.Overlay : WebRTCDisplayType.Evas, evasObject);
}
WebRTCErrorCode IDisplayable.ApplyEcoreWindow(IntPtr windowHandle)
{
return NativeWebRTC.SetEcoreDisplay(_webRtc.Handle, _trackId, windowHandle);
}
///
/// Gets or sets the display mode.
///
///
/// This property is meaningful only in overlay or EVAS surface display type.
///
/// http://tizen.org/feature/display
/// The required feature is not supported.
/// A that specifies the display mode.
/// Display mode type is incorrect.
/// is not set.
/// 9
public WebRTCDisplayMode DisplayMode
{
get
{
if (!Features.IsSupported(WebRTCFeatures.Display))
{
throw new NotSupportedException("Display feature is not supported.");
}
if (Type != MediaType.Video)
{
throw new InvalidOperationException("This property is only for video track.");
}
NativeWebRTC.GetDisplayMode(_webRtc.Handle, _trackId, out var val).
ThrowIfFailed("Failed to get WebRTC display mode");
return val;
}
set
{
if (!Features.IsSupported(WebRTCFeatures.Display))
{
throw new NotSupportedException("Display feature is not supported.");
}
if (Type != MediaType.Video)
{
throw new InvalidOperationException("This property is only for video track.");
}
ValidationUtil.ValidateEnum(typeof(WebRTCDisplayMode), value, nameof(value));
NativeWebRTC.SetDisplayMode(_webRtc.Handle, _trackId, value).
ThrowIfFailed("Failed to set WebRTC display mode.");
}
}
///
/// Gets or sets the display visibility.
///
/// true if WebRTC display is visible, otherwise false.
///
/// This property is meaningful only in overlay or EVAS surface display type.
///
/// http://tizen.org/feature/display
/// The required feature is not supported.
/// is not set.
/// 9
public bool DisplayVisible
{
get
{
if (!Features.IsSupported(WebRTCFeatures.Display))
{
throw new NotSupportedException("Display feature is not supported.");
}
if (Type != MediaType.Video)
{
throw new InvalidOperationException("This property is only for video track.");
}
NativeWebRTC.GetDisplayVisible(_webRtc.Handle, _trackId, out bool val).
ThrowIfFailed("Failed to get visible status");
return val;
}
set
{
if (!Features.IsSupported(WebRTCFeatures.Display))
{
throw new NotSupportedException("Display feature is not supported.");
}
if (Type != MediaType.Video)
{
throw new InvalidOperationException("This property is only for video track.");
}
NativeWebRTC.SetDisplayVisible(_webRtc.Handle, _trackId, value).
ThrowIfFailed("Failed to set display status.");
}
}
///
/// Gets or sets the mute status of the audio track.
///
/// true if audio is muted, otherwise false. The default value is false.
/// The WebRTC has already been disposed.
/// This MediaStreamTrack is not Audio.
/// 11
public bool Mute
{
get
{
if (Type != MediaType.Audio)
{
throw new InvalidOperationException("This property is only for audio track.");
}
NativeWebRTC.GetAudioMute(_webRtc.Handle, _trackId, out bool val).
ThrowIfFailed("Failed to get audio mute status");
return val;
}
set
{
if (Type != MediaType.Audio)
{
throw new InvalidOperationException("This property is only for audio track.");
}
NativeWebRTC.SetAudioMute(_webRtc.Handle, _trackId, value).
ThrowIfFailed("Failed to set audio mute status.");
}
}
///
/// Applies the audio stream policy to remote track.
///
/// The to apply.
///
/// This must be called in event.
///
/// does not support all .
/// Supported types are , ,
/// .
///
/// is null.
///
/// was set.
/// -or-
/// This method was not called in event.
/// -or-
/// This MediaStreamTrack is not Audio.
///
///
/// of is not supported on the current platform.
///
///
/// The WebRTC has already been disposed.
/// -or-
/// has already been disposed.
///
///
///
/// 9
public void ApplyAudioStreamPolicy(AudioStreamPolicy policy)
{
if (policy == null)
{
throw new ArgumentNullException(nameof(policy));
}
if (Type != MediaType.Audio)
{
throw new InvalidOperationException("This method is only for audio track.");
}
var ret = NativeWebRTC.SetAudioStreamPolicy(_webRtc.Handle, _trackId, policy.Handle);
if (ret == WebRTCErrorCode.InvalidArgument)
{
throw new NotSupportedException("The specified policy is not supported on the current system.");
}
ret.ThrowIfFailed("Failed to set the audio stream policy to the WebRTC");
}
}
}