SDL 2的Android启动流程与音频播放前的处理

最近在移植一个音频特效功能,因项目老代码使用SDL 2.0实现了简单的视频播放器。新增功能是根据音频变化改变视频渲染结果,音频处理算法由Java实现,为了快速验证效果,故在Java中进行音频相关计算。

SDL 2.0的启动流程

以继承SDLActivity为例。

1、实现SurfaceView回调

onCreate(Bundle savedInstanceState)
|- addVideoView();
   |- mSurface = new SDLSurface(getApplication());
      |- getHolder().addCallback(this);

2、在回调中继续执行初始化

surfaceChanged(SurfaceHolder holder, int format, int width, int height)
|- SDLActivity.playMovieVideo();
    |- SDLActivity.mSingleton.OnPlayMovieVideo();
       |- SDLActivity.mSingleton.OnPlayMovieVideo(); // 子类覆盖
          |- super.startPlayThread()
             |- startSDLThread();
                |- SDLActivity.mSDLThread = new Thread(new SDLMain(ffmpegString), "SDLThread");
                   |- SDLActivity.mSDLThread.start();
                      |- SDLActivity.nativeInit(); // 开始JNI调用
JNI——————————————————————————
[SDL_android_main.c]void Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv *, jclass, jobject)
|- [SDL_android.c]void SDL_Android_Init(JNIEnv *, jclass)
   |- [SDL_android.c]int Android_JNI_SetupThread()
      |- [SDL_android.c]JNIEnv *Android_JNI_GetEnv()
         |- pthread_setspecific(mThreadKey, (void*) env); // 保存env到SDL线程,方便后续调用Java方法
|- SDL_SetMainReady();
// 预编译后实际方法名为void SDL_SetMainReady_REAL(),对于Android,具体实现为SDL.c文件的void SDL_SetMainReady(void)
|- int SDL_main(int, char **)
// 具体实现为main.cpp文件的int main(int argc, char *argv[]),在此启动SDL消息处理线程开始不断的SDL_PollEvent(&event),类似Win32开发中的WndProc。

音频播放前的处理

为了在音频播放前进行声音的计算,可在SDL 2.0传递数据到AudioTrack前处理。

从SDL的C代码上看,最后会调用SDLActivity类中的方法,比如音频初始化public static int audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames),所以Java相关的处理可放在此函数中进行。

当配置成16位整数PCM时,最终调用public static void audioWriteShortBuffer(short[] buffer),故对PCM数据的计算可在此进行。

你可能感兴趣的:(SDL 2的Android启动流程与音频播放前的处理)