在ijkplayer 读线程中提到,stream_open()会创建读线程和视频渲染线程,甚至可以说视频渲染线程要先与读线程,该线程逻辑比较简单
static int video_refresh_thread(void *arg)
{
...
display:
/* display picture */
if (!ffp->display_disable && is->force_refresh && is->show_mode == SHOW_MODE_VIDEO && is->pictq.rindex_shown)
video_display2(ffp);
}
...
}
ff_ffplay.c/video_refresh()中调用了ff_ffplay.c/video_display2(),最终调用ff_ffplay.c/video_image_display2()
static void video_image_display2(FFPlayer *ffp)
{
...
vp = frame_queue_peek_last(&is->pictq);
...
SDL_VoutDisplayYUVOverlay(ffp->vout, vp->bmp);
...
}
ff_ffplay.c/video_image_display2()先调用 frame_queue_peek_last()将解码后的视频帧取出,然后调用SDL_VoutDisplayYUVOverlay()
SDL_VoutDisplayYUVOverlay()代码如下
int SDL_VoutDisplayYUVOverlay(SDL_Vout *vout, SDL_VoutOverlay *overlay)
{
if (vout && overlay && vout->display_overlay)
return vout->display_overlay(vout, overlay);
return -1;
}
里面调用了vout->display_overlay(vout, overlay),可以猜出这就是最终显示视频帧的函数,那它调用的是哪个函数?
在ijkplayer_jni.c/ijkmp_android_create()中调用了ijkplayer_android.c/SDL_VoutAndroid_CreateForAndroidSurface(),而ijkplayer_android.c/SDL_VoutAndroid_CreateForAndroidSurface()中又调用了ijksdl_vout_android_surface.c/SDL_VoutAndroid_CreateForANativeWindow(),在ijksdl_vout_android_surface.c/SDL_VoutAndroid_CreateForANativeWindow()中有一句话
vout->display_overlay = func_display_overlay;
上面vout->display_overlay中的display_overlay就是func_display_overlay,通过该函数渲染输出
到这里ijkplayer视频播放线程也就结束了