ijkplayer系列12:video_refresh_thread
Posted 有心好书
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ijkplayer系列12:video_refresh_thread相关的知识,希望对你有一定的参考价值。
video_refresh_thread
该线程负责图像的渲染,先来看下整体流程:
从上面的流程图可以得知,最终根据格式的差异分成了三个分支,我们先来看下func_display_overlay_l()的源码,然后再继续深入三个分支中。
static int func_display_overlay_l(SDL_Vout *vout, SDL_VoutOverlay *overlay)
SDL_Vout_Opaque *opaque = vout->opaque;
ANativeWindow *native_window = opaque->native_window;
if (!native_window)
if (!opaque->null_native_window_warned)
opaque->null_native_window_warned = 1;
ALOGW("func_display_overlay_l: NULL native_window");
return -1;
else
opaque->null_native_window_warned = 1;
if (!overlay)
ALOGE("func_display_overlay_l: NULL overlay");
return -1;
if (overlay->w <= 0 || overlay->h <= 0)
ALOGE("func_display_overlay_l: invalid overlay dimensions(%d, %d)", overlay->w, overlay->h);
return -1;
switch(overlay->format)
// android MediaCodec,渲染直接调用MediaCodec的Java API
case SDL_FCC__AMC:
// only ANativeWindow support
IJK_EGL_terminate(opaque->egl);
return SDL_VoutOverlayAMediaCodec_releaseFrame_l(overlay, NULL, true);
// OPENGL可以直接渲染以下三种格式的图像数据
case SDL_FCC_RV24:
case SDL_FCC_I420: //I420,即YUV420P,H.264使用的格式
case SDL_FCC_I444P10LE:
// only GLES support
if (opaque->egl)
return IJK_EGL_display(opaque->egl, native_window, overlay);
break;
// 这几个是Android中比较常见的格式,使用OPNENGL或ANativeWindow渲染即可
case SDL_FCC_YV12:
case SDL_FCC_RV16:
case SDL_FCC_RV32:
// both GLES & ANativeWindow support
if (vout->overlay_format == SDL_FCC__GLES2 && opaque->egl)
return IJK_EGL_display(opaque->egl, native_window, overlay);
break;
// fallback to ANativeWindow
IJK_EGL_terminate(opaque->egl);
return SDL_Android_NativeWindow_display_l(native_window, overlay);
硬解码渲染
J4AC_android_media_MediaCodec__releaseOutputBuffer()方法最终会调用到Java层的MediaCodec类的releaseOutputBuffer()方法,该方法的作用是根据索引释放对应的缓冲区,将缓冲区内的图像数据渲染到设置的Surface中。
OpenGL渲染
由于本人对opengl并不了解,因此不再过多叙述,有兴趣的同学自行进入ijksdl_egl.c中的IJK_EGL_display()方法中去查看源码。里面的逻辑很简单,主要是对一些opengl API的使用,相信熟悉opengl的同学看起来应该很轻松。
ANativeWindow渲染
源码就不帖出来了,里面也主要是对ANativeWindow一些相关API的使用,通过这些API将图像渲染出来。值得一提的是,其中有这么一句代码
voutDesc->render(&out_buffer, overlay);,
显然又是一个函数指针。根据像素空间不同,render有可能指向三个实现方法,分别为android_render_on_yv12()、android_render_on_rgb565()和android_render_on_rgb8888(),这三个方法均位于android_nativewindow.c中。显然,这三个方法分别代表着对YV12、RGB565和RGB32三种格式的图像的渲染。
以上是关于ijkplayer系列12:video_refresh_thread的主要内容,如果未能解决你的问题,请参考以下文章
ijkplayer系列13:video_refresh_thread