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