/*
* 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 .
///
/// 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 => _display;
set
{
if (Type != MediaType.Video)
{
throw new InvalidOperationException("This property is only for video.");
}
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.
///
/// A that specifies the display mode.
/// Display mode type is incorrect.
/// is not set.
/// 9
public WebRTCDisplayMode DisplayMode
{
get
{
if (Type != MediaType.Video)
{
throw new InvalidOperationException("This property is only for video.");
}
NativeWebRTC.GetDisplayMode(_webRtc.Handle, _trackId, out var val).
ThrowIfFailed("Failed to get WebRTC display mode");
return val;
}
set
{
if (Type != MediaType.Video)
{
throw new InvalidOperationException("This property is only for video.");
}
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.
///
/// is not set.
/// 9
public bool DisplayVisible
{
get
{
if (Type != MediaType.Video)
{
throw new InvalidOperationException("This property is only for video.");
}
NativeWebRTC.GetDisplayVisible(_webRtc.Handle, _trackId, out bool val).
ThrowIfFailed("Failed to get visible status");
return val;
}
set
{
if (Type != MediaType.Video)
{
throw new InvalidOperationException("This property is only for video.");
}
NativeWebRTC.SetDisplayVisible(_webRtc.Handle, _trackId, value).
ThrowIfFailed("Failed to set display 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("Should be applied in Audio");
}
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");
}
}
}