Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.MediaPlayer / Player / MediaStreamConfiguration.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 using System;
17 using System.Diagnostics;
18 using static Interop;
19
20 namespace Tizen.Multimedia
21 {
22     /// <summary>
23     /// Provides a means to configure properties and handle events for <see cref="MediaStreamSource"/>.
24     /// </summary>
25     /// <seealso cref="MediaStreamSource"/>
26     public class MediaStreamConfiguration
27     {
28         private const ulong DefaultBufferMaxSize = 200000;
29         private const uint DefaultBufferMinThreshold = 0;
30
31         private readonly MediaStreamSource _owner;
32         private readonly StreamType _streamType;
33
34         private ulong _bufferMaxSize = DefaultBufferMaxSize;
35         private uint _threshold = DefaultBufferMinThreshold;
36
37         internal MediaStreamConfiguration(MediaStreamSource owner, StreamType streamType)
38         {
39             _owner = owner;
40             _streamType = streamType;
41         }
42
43         /// <summary>
44         /// Occurs when the buffer underrun or overflow.
45         /// </summary>
46         /// <remarks>The event handler will be executed on an internal thread.</remarks>
47         /// <seealso cref="BufferMaxSize"/>
48         /// <seealso cref="BufferMinThreshold"/>
49         public event EventHandler<MediaStreamBufferStatusChangedEventArgs> BufferStatusChanged;
50
51         /// <summary>
52         /// Occurs when the seeking is requested.
53         /// </summary>
54         /// <remarks>The event handler will be executed on an internal thread.</remarks>
55         public event EventHandler<MediaStreamSeekingOccurredEventArgs> SeekingOccurred;
56
57         /// <summary>
58         /// Gets the max size of the buffer.
59         /// </summary>
60         /// <value>The max size of the buffer. The default is 200000.</value>
61         /// <remarks>If the buffer level over the max size, <see cref="BufferStatusChanged"/> will be raised with <see cref="MediaStreamBufferStatus.Overflow"/>.</remarks>
62         /// <exception cref="InvalidOperationException">The <see cref="MediaStreamSource"/> is not assigned to a player.</exception>
63         /// <exception cref="ArgumentOutOfRangeException">value is zero.</exception>
64         /// <seealso cref="BufferStatusChanged"/>
65         public ulong BufferMaxSize
66         {
67             get
68             {
69                 return _bufferMaxSize;
70             }
71             set
72             {
73                 if (_owner.Player == null)
74                 {
75                     throw new InvalidOperationException("The source is not assigned to a player yet.");
76                 }
77
78                 Debug.Assert(_owner.Player.IsDisposed == false);
79
80                 if (value == 0UL)
81                 {
82                     throw new ArgumentOutOfRangeException(nameof(value), value, "the buffer max size can't be zero.");
83                 }
84
85                 NativePlayer.SetMediaStreamBufferMaxSize(_owner.Player.Handle, _streamType, value).
86                     ThrowIfFailed("Failed to set the buffer max size");
87
88                 _bufferMaxSize = value;
89             }
90         }
91
92         /// <summary>
93         /// Gets the min threshold of the buffer or zero if the <see cref="MediaStreamSource"/> is not assigned to a player.
94         /// </summary>
95         /// <value>The minimum threshold of the buffer in percentage. The default is zero.</value>
96         /// <remarks>If the buffer level drops below the threshold value, <see cref="BufferStatusChanged"/> will be raised with <see cref="MediaStreamBufferStatus.Underrun"/>.</remarks>
97         /// <exception cref="InvalidOperationException">The <see cref="MediaStreamSource"/> is not assigned to a player.</exception>
98         /// <exception cref="ArgumentOutOfRangeException">value is greater than 100.</exception>
99         /// <seealso cref="BufferStatusChanged"/>
100         public uint BufferMinThreshold
101         {
102             get
103             {
104                 return _threshold;
105             }
106             set
107             {
108                 if (_owner.Player == null)
109                 {
110                     throw new InvalidOperationException("The source is not assigned to a player yet.");
111                 }
112
113                 Debug.Assert(_owner.Player.IsDisposed == false);
114
115                 if (100 < value)
116                 {
117                     throw new ArgumentOutOfRangeException(nameof(value), value,
118                         $"The threshold can't be greater than 100, but got { value }.");
119                 }
120
121                 NativePlayer.SetMediaStreamBufferMinThreshold(_owner.Player.Handle, _streamType, value).
122                     ThrowIfFailed("Failed to set the buffer minimum threshold");
123
124                 _threshold = value;
125             }
126         }
127
128         internal void OnPlayerSet(Player player)
129         {
130             if (_streamType == StreamType.Audio)
131             {
132                 player.MediaStreamAudioSeekingOccurred += MediaStreamSeekingOccurred;
133                 player.MediaStreamAudioBufferStatusChanged += MediaStreamBufferStatusChanged;
134             }
135             else
136             {
137                 player.MediaStreamVideoSeekingOccurred += MediaStreamSeekingOccurred;
138                 player.MediaStreamVideoBufferStatusChanged += MediaStreamBufferStatusChanged;
139             }
140
141             NativePlayer.SetMediaStreamBufferMaxSize(player.Handle, _streamType, _bufferMaxSize).
142                 ThrowIfFailed("Failed to initialize the media stream configuration");
143
144             NativePlayer.SetMediaStreamBufferMinThreshold(player.Handle, _streamType, _threshold).
145                 ThrowIfFailed("Failed to initialize the media stream configuration");
146         }
147
148         internal void OnPlayerUnset(Player player)
149         {
150             if (_streamType == StreamType.Audio)
151             {
152                 player.MediaStreamAudioSeekingOccurred -= MediaStreamSeekingOccurred;
153                 player.MediaStreamAudioBufferStatusChanged -= MediaStreamBufferStatusChanged;
154             }
155             else
156             {
157                 player.MediaStreamVideoSeekingOccurred -= MediaStreamSeekingOccurred;
158                 player.MediaStreamVideoBufferStatusChanged -= MediaStreamBufferStatusChanged;
159             }
160         }
161
162         private void MediaStreamBufferStatusChanged(object sender, MediaStreamBufferStatusChangedEventArgs e)
163         {
164             BufferStatusChanged?.Invoke(this, e);
165         }
166
167         private void MediaStreamSeekingOccurred(object sender, MediaStreamSeekingOccurredEventArgs e)
168         {
169             SeekingOccurred?.Invoke(this, e);
170         }
171     }
172 }