From 1cf8238c8a38b17bb05ec9a54015f49f49f44eb9 Mon Sep 17 00:00:00 2001 From: ian_minett Date: Fri, 16 Aug 2019 17:53:07 -0700 Subject: [PATCH] Change: Add basic audio data callback framework to the API In order to allow DSP (digital signal processing) to operate on the original multi-channel audio stream, allow an optional callback function to be registered with the player. The callback function passes the audio data back to the client layer which can then process the audio as desired. --- ijkmedia/ijkplayer/ff_ffplay.c | 15 +++++++++ ijkmedia/ijkplayer/ff_ffplay_def.h | 5 +++ ijkmedia/ijkplayer/ijkaudiocallback.h | 33 +++++++++++++++++++ ijkmedia/ijkplayer/ijkplayer.c | 8 +++++ ijkmedia/ijkplayer/ijkplayer.h | 2 ++ ijkmedia/ijkplayer/ijkplayer_internal.h | 4 +++ .../IJKMediaPlayer.xcodeproj/project.pbxproj | 2 ++ .../IJKFFMoviePlayerController.m | 8 +++++ .../IJKMediaPlayer/IJKMediaPlayback.h | 7 ++++ 9 files changed, 84 insertions(+) create mode 100755 ijkmedia/ijkplayer/ijkaudiocallback.h diff --git a/ijkmedia/ijkplayer/ff_ffplay.c b/ijkmedia/ijkplayer/ff_ffplay.c index 52aba31f41..d9a6051977 100755 --- a/ijkmedia/ijkplayer/ff_ffplay.c +++ b/ijkmedia/ijkplayer/ff_ffplay.c @@ -2544,6 +2544,21 @@ static int audio_decode_frame(FFPlayer *ffp) is->audio_src.fmt = af->frame->format; } +#if NOMIT_AUDIO_DSP_CALLBACK_FN==1 + /** Digital Signal Processing, multi-channel signal *********************************/ + /* Run DSP callback function. In-place processing on playback audio data buffer. */ + if( ffp->pAudioDSPCbFn ) + { + unsigned int numSamples = af->frame->nb_samples; + unsigned int format = af->frame->format; + ffp->pAudioDSPCbFn( (void**) af->frame->extended_data, numSamples, + (void**) af->frame->extended_data, &numSamples, + af->frame->sample_rate, af->frame->channels, + format ); + + } +#endif + if (is->swr_ctx) { const uint8_t **in = (const uint8_t **)af->frame->extended_data; uint8_t **out = &is->audio_buf1; diff --git a/ijkmedia/ijkplayer/ff_ffplay_def.h b/ijkmedia/ijkplayer/ff_ffplay_def.h index 00f19f3c4d..41623fe266 100755 --- a/ijkmedia/ijkplayer/ff_ffplay_def.h +++ b/ijkmedia/ijkplayer/ff_ffplay_def.h @@ -65,6 +65,7 @@ #include "ff_ffmsg_queue.h" #include "ff_ffpipenode.h" #include "ijkmeta.h" +#include "ijkaudiocallback.h" #define DEFAULT_HIGH_WATER_MARK_IN_BYTES (256 * 1024) @@ -632,6 +633,10 @@ typedef struct FFPlayer { SDL_Surface *screen; #endif +#if NOMIT_AUDIO_DSP_CALLBACK_FN==1 + AUDIO_DSP_CBFN pAudioDSPCbFn; +#endif + /* extra fields */ SDL_Aout *aout; SDL_Vout *vout; diff --git a/ijkmedia/ijkplayer/ijkaudiocallback.h b/ijkmedia/ijkplayer/ijkaudiocallback.h new file mode 100755 index 0000000000..a5da023ba6 --- /dev/null +++ b/ijkmedia/ijkplayer/ijkaudiocallback.h @@ -0,0 +1,33 @@ +/* + * ijkaudiocallback.h + * + * This file is part of ijkPlayer. + * + * ijkPlayer is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * ijkPlayer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with ijkPlayer; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IJKPLAYER__IJKAUDIOCALLBACK_H +#define IJKPLAYER__IJKAUDIOCALLBACK_H + +/* Include support for DSP callback function in library build */ +#define NOMIT_AUDIO_DSP_CALLBACK_FN (0) + +/* Callback function prototype */ +typedef int (*AUDIO_DSP_CBFN) ( void **inData, unsigned int numInSamples, + void **outData, unsigned int *numOutSamples, + unsigned int sampleRate, unsigned int numChans, + unsigned int format); + +#endif//IJKPLAYER__IJKAUDIOCALLBACK_H diff --git a/ijkmedia/ijkplayer/ijkplayer.c b/ijkmedia/ijkplayer/ijkplayer.c index 8ea4d4748e..afc4118c8e 100755 --- a/ijkmedia/ijkplayer/ijkplayer.c +++ b/ijkmedia/ijkplayer/ijkplayer.c @@ -383,6 +383,14 @@ static int ijkmp_msg_loop(void *arg) return ret; } +void ijkmp_setAudioDSPCallbackFn( IjkMediaPlayer *mp, AUDIO_DSP_CBFN audioCbFn ) +{ +#if NOMIT_AUDIO_DSP_CALLBACK_FN==1 + mp->pAudioDSPCbFn = audioCbFn; + mp->ffplayer->pAudioDSPCbFn = audioCbFn; +#endif +} + static int ijkmp_prepare_async_l(IjkMediaPlayer *mp) { assert(mp); diff --git a/ijkmedia/ijkplayer/ijkplayer.h b/ijkmedia/ijkplayer/ijkplayer.h index 9e99883dea..0acdfae000 100644 --- a/ijkmedia/ijkplayer/ijkplayer.h +++ b/ijkmedia/ijkplayer/ijkplayer.h @@ -28,6 +28,7 @@ #include "ff_ffmsg_queue.h" #include "ijkmeta.h" +#include "ijkaudiocallback.h" #ifndef MPTRACE #define MPTRACE ALOGD @@ -197,6 +198,7 @@ void ijkmp_dec_ref(IjkMediaPlayer *mp); void ijkmp_dec_ref_p(IjkMediaPlayer **pmp); int ijkmp_set_data_source(IjkMediaPlayer *mp, const char *url); +void ijkmp_setAudioDSPCallbackFn( IjkMediaPlayer *mp, AUDIO_DSP_CBFN audioCbFn ); int ijkmp_prepare_async(IjkMediaPlayer *mp); int ijkmp_start(IjkMediaPlayer *mp); int ijkmp_pause(IjkMediaPlayer *mp); diff --git a/ijkmedia/ijkplayer/ijkplayer_internal.h b/ijkmedia/ijkplayer/ijkplayer_internal.h index 5e7935f2f0..4fb43bd013 100644 --- a/ijkmedia/ijkplayer/ijkplayer_internal.h +++ b/ijkmedia/ijkplayer/ijkplayer_internal.h @@ -47,6 +47,10 @@ struct IjkMediaPlayer { int restart_from_beginning; int seek_req; long seek_msec; + +#if NOMIT_AUDIO_DSP_CALLBACK_FN==1 + AUDIO_DSP_CBFN pAudioDSPCbFn; +#endif }; #endif diff --git a/ios/IJKMediaPlayer/IJKMediaPlayer.xcodeproj/project.pbxproj b/ios/IJKMediaPlayer/IJKMediaPlayer.xcodeproj/project.pbxproj index 0f023aecb6..f601d49eb8 100644 --- a/ios/IJKMediaPlayer/IJKMediaPlayer.xcodeproj/project.pbxproj +++ b/ios/IJKMediaPlayer/IJKMediaPlayer.xcodeproj/project.pbxproj @@ -271,6 +271,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 3CA61AE3230E25EF003CCA37 /* ijkaudiocallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ijkaudiocallback.h; sourceTree = ""; }; 454316201A66493700676070 /* ffpipeline_ios.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ffpipeline_ios.c; path = ijkmedia/ijkplayer/ios/pipeline/ffpipeline_ios.c; sourceTree = ""; }; 454316211A66493700676070 /* ffpipeline_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ffpipeline_ios.h; path = ijkmedia/ijkplayer/ios/pipeline/ffpipeline_ios.h; sourceTree = ""; }; 454316221A66493700676070 /* ffpipenode_ios_videotoolbox_vdec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ffpipenode_ios_videotoolbox_vdec.h; path = ijkmedia/ijkplayer/ios/pipeline/ffpipenode_ios_videotoolbox_vdec.h; sourceTree = ""; }; @@ -744,6 +745,7 @@ E6903FDC17EAFC6100CFD954 /* ff_ffplay.h */, E69BE5491B93FED300AFBA3F /* ijkavformat */, E69BE54E1B93FED300AFBA3F /* ijkavutil */, + 3CA61AE3230E25EF003CCA37 /* ijkaudiocallback.h */, E6FAD9551A515CE300725002 /* ijkmeta.c */, E6FAD9561A515CE300725002 /* ijkmeta.h */, E66F8DEE17EFEA9400354D80 /* ijkplayer_internal.h */, diff --git a/ios/IJKMediaPlayer/IJKMediaPlayer/IJKFFMoviePlayerController.m b/ios/IJKMediaPlayer/IJKMediaPlayer/IJKFFMoviePlayerController.m index 5263daae27..7b88e905d4 100644 --- a/ios/IJKMediaPlayer/IJKMediaPlayer/IJKFFMoviePlayerController.m +++ b/ios/IJKMediaPlayer/IJKMediaPlayer/IJKFFMoviePlayerController.m @@ -455,6 +455,14 @@ - (void)setPauseInBackground:(BOOL)pause _pauseInBackground = pause; } +- (void)setAudioDSPCallbackFn:(AUDIO_DSP_CBFN)pAudioDSPCbFn +{ + if (!_mediaPlayer) + return; + + ijkmp_setAudioDSPCallbackFn( _mediaPlayer, pAudioDSPCbFn ); +} + - (BOOL)isVideoToolboxOpen { if (!_mediaPlayer) diff --git a/ios/IJKMediaPlayer/IJKMediaPlayer/IJKMediaPlayback.h b/ios/IJKMediaPlayer/IJKMediaPlayer/IJKMediaPlayback.h index b5e50e07d6..ab807f2321 100644 --- a/ios/IJKMediaPlayer/IJKMediaPlayer/IJKMediaPlayback.h +++ b/ios/IJKMediaPlayer/IJKMediaPlayer/IJKMediaPlayback.h @@ -53,6 +53,12 @@ typedef NS_ENUM(NSInteger, IJKMPMovieFinishReason) { IJKMPMovieFinishReasonUserExited }; +/* Callback function prototype */ +typedef int (*AUDIO_DSP_CBFN) ( void **inData, unsigned int numInSamples, + void **outData, unsigned int *numOutSamples, + unsigned int sampleRate, unsigned int numChans, + unsigned int format ); + // ----------------------------------------------------------------------------- // Thumbnails @@ -74,6 +80,7 @@ typedef NS_ENUM(NSInteger, IJKMPMovieTimeOption) { - (BOOL)isPlaying; - (void)shutdown; - (void)setPauseInBackground:(BOOL)pause; +- (void)setAudioDSPCallbackFn:(AUDIO_DSP_CBFN)pAudioDSPCbFn; @property(nonatomic, readonly) UIView *view; @property(nonatomic) NSTimeInterval currentPlaybackTime;