internal delegate void VideoFrameDecodedCallback(IntPtr packetHandle, IntPtr userData);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void AudioFrameDecodedCallback(IntPtr packetHandle, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void SubtitleUpdatedCallback(uint duration, string text, IntPtr userData);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[DllImport(Libraries.Player, EntryPoint = "player_unset_media_packet_video_frame_decoded_cb")]
internal static extern PlayerErrorCode UnsetVideoFrameDecodedCb(IntPtr player);
+ [DllImport(Libraries.Player, EntryPoint = "player_set_media_packet_audio_frame_decoded_cb")]
+ internal static extern PlayerErrorCode SetAudioFrameDecodedCb(IntPtr player, IntPtr format, PlayerAudioExtractOption opt,
+ AudioFrameDecodedCallback callback, IntPtr userData = default(IntPtr));
+
+ [DllImport(Libraries.Player, EntryPoint = "player_unset_media_packet_audio_frame_decoded_cb")]
+ internal static extern PlayerErrorCode UnsetAudioFrameDecodedCb(IntPtr player);
+
[DllImport(Libraries.Player, EntryPoint = "player_set_streaming_cookie")]
internal static extern PlayerErrorCode SetStreamingCookie(IntPtr player, string cookie, int size);
--- /dev/null
+/*
+ * Copyright (c) 2019 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;
+
+namespace Tizen.Multimedia
+{
+ /// <summary>
+ /// Provides data for the <see cref="Player.AudioDataDecoded"/> event.
+ /// </summary>
+ /// <since_tizen> 6 </since_tizen>
+ public class AudioDataDecodedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the AudioFrameDecodedEventArgs class.
+ /// </summary>
+ internal AudioDataDecodedEventArgs(MediaPacket packet)
+ {
+ Packet = packet;
+ }
+
+ /// <summary>
+ /// Gets the packet containing the decoded frame.
+ /// </summary>
+ /// <since_tizen> 6 </since_tizen>
+ public MediaPacket Packet { get; }
+
+ }
+}
}
#region VideoFrameDecoded event
-
private EventHandler<VideoFrameDecodedEventArgs> _videoFrameDecoded;
private NativePlayer.VideoFrameDecodedCallback _videoFrameDecodedCallback;
}
#endregion
+ #region AudioFrameDecoded event
+ /// <summary>
+ /// Occurs when a audio frame is decoded.
+ /// </summary>
+ /// <remarks>
+ /// <para>The event handler will be executed on an internal thread.</para>
+ /// <para>The <see cref="AudioDataDecodedEventArgs.Packet"/> in event args should be disposed after use.</para>
+ /// </remarks>
+ /// <seealso cref="AudioDataDecodedEventArgs.Packet"/>
+ /// <since_tizen> 6 </since_tizen>
+ public event EventHandler<AudioDataDecodedEventArgs> AudioDataDecoded;
+
+ private NativePlayer.AudioFrameDecodedCallback _audioFrameDecodedCallback;
+ #endregion
+
private void RegisterVideoStreamChangedCallback()
{
_videoStreamChangedCallback = (width, height, fps, bitrate, _) =>
{
Interlocked.Exchange(ref _isPreparing, 0);
}
-
#endregion
+
+ /// <summary>
+ /// Enable to decode an audio data for exporting PCM from a data.
+ /// </summary>
+ /// <param name="format">The media format handle about required audio PCM specification.
+ /// The format has to include <see cref="AudioMediaFormat.MimeType"/>,
+ /// <see cref="AudioMediaFormat.Channel"/> and <see cref="AudioMediaFormat.SampleRate"/>.
+ /// If the format is NULL, the original PCM format or platform default PCM format will be applied.</param>
+ /// <param name="option">The audio extract option.</param>
+ /// <remarks><para>The player must be in the <see cref="PlayerState.Idle"/> state.</para>
+ /// <para>A <see cref="AudioDataDecoded"/> event is called in a separate thread(not in the main loop).</para>
+ /// <para>The audio PCM data can be retrieved using a <see cref="AudioDataDecoded"/> event as a media packet
+ /// and it is available until it's destroyed by <see cref="MediaPacket.Dispose()"/>.
+ /// The packet has to be destroyed as quickly as possible after rendering the data
+ /// and all the packets have to be destroyed before <see cref="Unprepare"/> is called.</para></remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="ArgumentException">The value is not valid.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// Operation failed; internal error.
+ /// -or-<br/>
+ /// The player is not in the valid state.
+ /// </exception>
+ /// <seealso cref="PlayerAudioExtractOption"/>
+ /// <seealso cref="DisableExportingAudioData"/>
+ /// <since_tizen> 6 </since_tizen>
+ public void EnableExportingAudioData(AudioMediaFormat format, PlayerAudioExtractOption option)
+ {
+ ValidatePlayerState(PlayerState.Idle);
+ ValidationUtil.ValidateEnum(typeof(PlayerAudioExtractOption), option, nameof(option));
+
+ IntPtr formatHandle = IntPtr.Zero;
+
+ _audioFrameDecodedCallback = (IntPtr packetHandle, IntPtr userData) =>
+ {
+ var handler = AudioDataDecoded;
+ if (handler != null)
+ {
+ Log.Debug(PlayerLog.Tag, "packet : " + packetHandle.ToString());
+ handler.Invoke(this,
+ new AudioDataDecodedEventArgs(MediaPacket.From(packetHandle)));
+ }
+ else
+ {
+ MediaPacket.From(packetHandle).Dispose();
+ }
+ };
+
+ formatHandle = format.AsNativeHandle();
+
+ NativePlayer.SetAudioFrameDecodedCb(Handle, formatHandle, option, _audioFrameDecodedCallback, IntPtr.Zero).
+ ThrowIfFailed(this, "Failed to register the _audioFrameDecoded");
+ }
+
+ /// <summary>
+ /// Disable to decode an audio data.
+ /// </summary>
+ /// <remarks>The player must be in the <see cref="PlayerState.Idle"/> or <see cref="PlayerState.Ready"/>
+ /// state.</remarks>
+ /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
+ /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
+ /// <seealso cref="EnableExportingAudioData"/>
+ /// <since_tizen> 6 </since_tizen>
+ public void DisableExportingAudioData()
+ {
+ ValidatePlayerState(PlayerState.Idle, PlayerState.Ready);
+
+ NativePlayer.UnsetAudioFrameDecodedCb(Handle).
+ ThrowIfFailed(this, "Failed to unset the AudioFrameDecoded");
+
+ _audioFrameDecodedCallback = null;
+ }
}
}
/// </summary>
Year
}
+
+ /// <summary>
+ /// Enumeration of audio extract option.
+ /// </summary>
+ /// <seealso cref="Player.EnableExportingAudioData"/>
+ /// <since_tizen> 6 </since_tizen>
+ public enum PlayerAudioExtractOption
+ {
+ /// <summary>
+ /// Sync with the playback clock and multichannel audio stream
+ /// </summary>
+ Default = 0x00,
+
+ /// <summary>
+ /// No sync with the playback clock
+ /// </summary>
+ NoSyncWithClock = 0x01,
+
+ /// <summary>
+ /// Splits one interleaved multichannel audio stream into many mono audio streams
+ /// </summary>
+ Deinterleave = 0x02,
+
+ /// <summary>
+ /// No sync with clock and splits into mono streams
+ /// </summary>
+ NoSyncAndDeinterleave = 0x03,
+ }
}