[MediaPlayer] Added ErrorHandler registration methods for internal use. (#33)
[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
17 using System;
18 using System.Diagnostics;
19 using static Interop;
20
21 namespace Tizen.Multimedia
22 {
23     /// <summary>
24     /// Provides a means to configure properties and handle events for <see cref="MediaStreamSource"/>.
25     /// </summary>
26     /// <seealso cref="MediaStreamSource"/>
27     /// <since_tizen> 3 </since_tizen>
28     public class MediaStreamConfiguration
29     {
30         private const ulong DefaultBufferMaxSize = 200000;
31         private const uint DefaultBufferMinThreshold = 0;
32
33         private readonly MediaStreamSource _owner;
34         private readonly StreamType _streamType;
35
36         private ulong _bufferMaxSize = DefaultBufferMaxSize;
37         private uint _threshold = DefaultBufferMinThreshold;
38
39         internal MediaStreamConfiguration(MediaStreamSource owner, StreamType streamType)
40         {
41             _owner = owner;
42             _streamType = streamType;
43         }
44
45         /// <summary>
46         /// Occurs when the buffer underruns or overflows.
47         /// </summary>
48         /// <remarks>The event handler will be executed on an internal thread.</remarks>
49         /// <seealso cref="BufferMaxSize"/>
50         /// <seealso cref="BufferMinThreshold"/>
51         /// <since_tizen> 3 </since_tizen>
52         public event EventHandler<MediaStreamBufferStatusChangedEventArgs> BufferStatusChanged;
53
54         /// <summary>
55         /// Occurs when the seeking is requested.
56         /// </summary>
57         /// <remarks>The event handler will be executed on an internal thread.</remarks>
58         /// <since_tizen> 3 </since_tizen>
59         public event EventHandler<MediaStreamSeekingOccurredEventArgs> SeekingOccurred;
60
61         /// <summary>
62         /// Gets or sets the max size of the buffer.
63         /// </summary>
64         /// <value>The max size of the buffer. The default is 200000.</value>
65         /// <remarks>If the buffer level overflows the max size, <see cref="BufferStatusChanged"/> will be raised with <see cref="MediaStreamBufferStatus.Overflow"/>.</remarks>
66         /// <exception cref="InvalidOperationException">The <see cref="MediaStreamSource"/> is not assigned to a player.</exception>
67         /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is zero.</exception>
68         /// <seealso cref="BufferStatusChanged"/>
69         /// <since_tizen> 3 </since_tizen>
70         public ulong BufferMaxSize
71         {
72             get
73             {
74                 return _bufferMaxSize;
75             }
76             set
77             {
78                 if (_owner.Player == null)
79                 {
80                     throw new InvalidOperationException("The source is not assigned to a player yet.");
81                 }
82
83                 Debug.Assert(_owner.Player.IsDisposed == false);
84
85                 if (value == 0UL)
86                 {
87                     throw new ArgumentOutOfRangeException(nameof(value), value, "the buffer max size can't be zero.");
88                 }
89
90                 NativePlayer.SetMediaStreamBufferMaxSize(_owner.Player.Handle, _streamType, value).
91                     ThrowIfFailed(_owner.Player, "Failed to set the buffer max size");
92
93                 _bufferMaxSize = value;
94             }
95         }
96
97         /// <summary>
98         /// Gets or sets the minimum threshold of the buffer.
99         /// </summary>
100         /// <value>The minimum threshold of the buffer in percentage. The default is zero.</value>
101         /// <remarks>If the buffer level drops below the threshold value, <see cref="BufferStatusChanged"/> will be raised with <see cref="MediaStreamBufferStatus.Underrun"/>.</remarks>
102         /// <exception cref="InvalidOperationException">The <see cref="MediaStreamSource"/> is not assigned to a player.</exception>
103         /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is greater than 100.</exception>
104         /// <seealso cref="BufferStatusChanged"/>
105         /// <since_tizen> 3 </since_tizen>
106         public uint BufferMinThreshold
107         {
108             get
109             {
110                 return _threshold;
111             }
112             set
113             {
114                 if (_owner.Player == null)
115                 {
116                     throw new InvalidOperationException("The source is not assigned to a player yet.");
117                 }
118
119                 Debug.Assert(_owner.Player.IsDisposed == false);
120
121                 if (100 < value)
122                 {
123                     throw new ArgumentOutOfRangeException(nameof(value), value,
124                         $"The threshold can't be greater than 100, but got { value }.");
125                 }
126
127                 NativePlayer.SetMediaStreamBufferMinThreshold(_owner.Player.Handle, _streamType, value).
128                     ThrowIfFailed(_owner.Player, "Failed to set the buffer minimum threshold");
129
130                 _threshold = value;
131             }
132         }
133
134         internal void OnPlayerSet(Player player)
135         {
136             if (_streamType == StreamType.Audio)
137             {
138                 player.MediaStreamAudioSeekingOccurred += MediaStreamSeekingOccurred;
139                 player.MediaStreamAudioBufferStatusChanged += MediaStreamBufferStatusChanged;
140             }
141             else
142             {
143                 player.MediaStreamVideoSeekingOccurred += MediaStreamSeekingOccurred;
144                 player.MediaStreamVideoBufferStatusChanged += MediaStreamBufferStatusChanged;
145             }
146
147             NativePlayer.SetMediaStreamBufferMaxSize(player.Handle, _streamType, _bufferMaxSize).
148                 ThrowIfFailed(player, "Failed to initialize the media stream configuration");
149
150             NativePlayer.SetMediaStreamBufferMinThreshold(player.Handle, _streamType, _threshold).
151                 ThrowIfFailed(player, "Failed to initialize the media stream configuration");
152         }
153
154         internal void OnPlayerUnset(Player player)
155         {
156             if (_streamType == StreamType.Audio)
157             {
158                 player.MediaStreamAudioSeekingOccurred -= MediaStreamSeekingOccurred;
159                 player.MediaStreamAudioBufferStatusChanged -= MediaStreamBufferStatusChanged;
160             }
161             else
162             {
163                 player.MediaStreamVideoSeekingOccurred -= MediaStreamSeekingOccurred;
164                 player.MediaStreamVideoBufferStatusChanged -= MediaStreamBufferStatusChanged;
165             }
166         }
167
168         private void MediaStreamBufferStatusChanged(object sender, MediaStreamBufferStatusChangedEventArgs e)
169         {
170             BufferStatusChanged?.Invoke(this, e);
171         }
172
173         private void MediaStreamSeekingOccurred(object sender, MediaStreamSeekingOccurredEventArgs e)
174         {
175             SeekingOccurred?.Invoke(this, e);
176         }
177     }
178 }