From d38463ecb8859124318ce7539f0cc3d6f18317d9 Mon Sep 17 00:00:00 2001 From: nam <36914158+aferin@users.noreply.github.com> Date: Tue, 16 Jul 2019 16:58:24 +0900 Subject: [PATCH] [MediaPlayer] Add API to export audio PCM data (#930) * [MediaPlayer] Add API to export audio PCM data --- .../Interop/Interop.Player.cs | 10 +++ .../Player/AudioDataDecodedEventArgs.cs | 41 ++++++++++++ .../Player/Player.Events.cs | 16 ++++- src/Tizen.Multimedia.MediaPlayer/Player/Player.cs | 72 +++++++++++++++++++++- .../Player/PlayerEnums.cs | 28 +++++++++ 5 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 src/Tizen.Multimedia.MediaPlayer/Player/AudioDataDecodedEventArgs.cs diff --git a/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Player.cs b/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Player.cs index f40b77d..8c0cf7a 100644 --- a/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Player.cs +++ b/src/Tizen.Multimedia.MediaPlayer/Interop/Interop.Player.cs @@ -37,6 +37,9 @@ internal static partial class Interop 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)] @@ -172,6 +175,13 @@ internal static partial class Interop [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); diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/AudioDataDecodedEventArgs.cs b/src/Tizen.Multimedia.MediaPlayer/Player/AudioDataDecodedEventArgs.cs new file mode 100644 index 0000000..17a0085 --- /dev/null +++ b/src/Tizen.Multimedia.MediaPlayer/Player/AudioDataDecodedEventArgs.cs @@ -0,0 +1,41 @@ +/* + * 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 +{ + /// + /// Provides data for the event. + /// + /// 6 + public class AudioDataDecodedEventArgs : EventArgs + { + /// + /// Initializes a new instance of the AudioFrameDecodedEventArgs class. + /// + internal AudioDataDecodedEventArgs(MediaPacket packet) + { + Packet = packet; + } + + /// + /// Gets the packet containing the decoded frame. + /// + /// 6 + public MediaPacket Packet { get; } + + } +} diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/Player.Events.cs b/src/Tizen.Multimedia.MediaPlayer/Player/Player.Events.cs index 5d2f5f1..ed9f3dc 100644 --- a/src/Tizen.Multimedia.MediaPlayer/Player/Player.Events.cs +++ b/src/Tizen.Multimedia.MediaPlayer/Player/Player.Events.cs @@ -169,7 +169,6 @@ namespace Tizen.Multimedia } #region VideoFrameDecoded event - private EventHandler _videoFrameDecoded; private NativePlayer.VideoFrameDecodedCallback _videoFrameDecodedCallback; @@ -223,6 +222,21 @@ namespace Tizen.Multimedia } #endregion + #region AudioFrameDecoded event + /// + /// Occurs when a audio frame is decoded. + /// + /// + /// The event handler will be executed on an internal thread. + /// The in event args should be disposed after use. + /// + /// + /// 6 + public event EventHandler AudioDataDecoded; + + private NativePlayer.AudioFrameDecodedCallback _audioFrameDecodedCallback; + #endregion + private void RegisterVideoStreamChangedCallback() { _videoStreamChangedCallback = (width, height, fps, bitrate, _) => diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/Player.cs b/src/Tizen.Multimedia.MediaPlayer/Player/Player.cs index 6040449..10f939a 100644 --- a/src/Tizen.Multimedia.MediaPlayer/Player/Player.cs +++ b/src/Tizen.Multimedia.MediaPlayer/Player/Player.cs @@ -884,7 +884,77 @@ namespace Tizen.Multimedia { Interlocked.Exchange(ref _isPreparing, 0); } - #endregion + + /// + /// Enable to decode an audio data for exporting PCM from a data. + /// + /// The media format handle about required audio PCM specification. + /// The format has to include , + /// and . + /// If the format is NULL, the original PCM format or platform default PCM format will be applied. + /// The audio extract option. + /// The player must be in the state. + /// A event is called in a separate thread(not in the main loop). + /// The audio PCM data can be retrieved using a event as a media packet + /// and it is available until it's destroyed by . + /// The packet has to be destroyed as quickly as possible after rendering the data + /// and all the packets have to be destroyed before is called. + /// The player has already been disposed of. + /// The value is not valid. + /// + /// Operation failed; internal error. + /// -or-
+ /// The player is not in the valid state. + ///
+ /// + /// + /// 6 + 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"); + } + + /// + /// Disable to decode an audio data. + /// + /// The player must be in the or + /// state. + /// The player has already been disposed of. + /// The player is not in the valid state. + /// + /// 6 + public void DisableExportingAudioData() + { + ValidatePlayerState(PlayerState.Idle, PlayerState.Ready); + + NativePlayer.UnsetAudioFrameDecodedCb(Handle). + ThrowIfFailed(this, "Failed to unset the AudioFrameDecoded"); + + _audioFrameDecodedCallback = null; + } } } diff --git a/src/Tizen.Multimedia.MediaPlayer/Player/PlayerEnums.cs b/src/Tizen.Multimedia.MediaPlayer/Player/PlayerEnums.cs index 3a635ce..a611f18 100644 --- a/src/Tizen.Multimedia.MediaPlayer/Player/PlayerEnums.cs +++ b/src/Tizen.Multimedia.MediaPlayer/Player/PlayerEnums.cs @@ -295,4 +295,32 @@ namespace Tizen.Multimedia /// Year } + + /// + /// Enumeration of audio extract option. + /// + /// + /// 6 + public enum PlayerAudioExtractOption + { + /// + /// Sync with the playback clock and multichannel audio stream + /// + Default = 0x00, + + /// + /// No sync with the playback clock + /// + NoSyncWithClock = 0x01, + + /// + /// Splits one interleaved multichannel audio stream into many mono audio streams + /// + Deinterleave = 0x02, + + /// + /// No sync with clock and splits into mono streams + /// + NoSyncAndDeinterleave = 0x03, + } } -- 2.7.4