ijkplayer使用案例,摆脱render.c
2017-03-15 本文已影响774人
睡后3k
有人说我写的都是水文,所以这篇这是毫无逻辑的水文
这里 提到过ijkplayer在Android可以通过surface来进行自定义OpenGL渲染,其中的原理就是利用OpenGL的extension来获取纹理
可惜的是像魅族这种机器,明明说支持GL_OES_EGL_image_external
然后死活编译不通过, 看来还是要通过手动的方式来操作
在贴大段的代码前先要搞明白状况
- ijk在哪里回传解码数据
- 回传过来的是i420, nv12, rbg565,rgba8888的哪一种
- JNI怎么交给Java,用什么类型打包
答日:
-
在
ffplay.c
的video_image_display2
方法, 参数中的overlay
就包含我们想要pixcels -
这个格式可以通过options来配置, 具体在
ff_ffplay_options.h
的头文件中
{ "fcc-_es2", "", 0, OPTION_CONST(SDL_FCC__GLES2), .unit = "overlay-format" },
{ "fcc-i420", "", 0, OPTION_CONST(SDL_FCC_I420), .unit = "overlay-format" },
{ "fcc-yv12", "", 0, OPTION_CONST(SDL_FCC_YV12), .unit = "overlay-format" },
{ "fcc-rv16", "", 0, OPTION_CONST(SDL_FCC_RV16), .unit = "overlay-format" },
{ "fcc-rv24", "", 0, OPTION_CONST(SDL_FCC_RV24), .unit = "overlay-format" },
{ "fcc-rv32", "", 0, OPTION_CONST(SDL_FCC_RV32), .unit = "overlay-format" },
{ "fcc-custom", "", 0, OPTION_CONST(SDL_FCC_CUSTOM), .unit = "overlay-format" },
- 回传的话我这里采用笨办法
- 在FFplayer中添加void * 指向我们的Interface;
- 在video_image_display2中执行interface方法
- 使用byte[]打包数据并附带width,height等重要信息
接下来就可以贴代码了
- Java层配置
player.native_setDisplayInterface(this);
player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", "fcc-i420");
native_setDisplayInterface
是自定义添加回调的方法
-
native_setDisplayInterface
具体实现
在ijkplayer_jni.c
中
void Java_tv_danmaku_ijk_media_player_IjkMediaPlayer_native_1setDisplayInterface(JNIEnv *env, jobject thiz, jobject displayListener)
{
MPTRACE("%s\n", __func__);
IjkMediaPlayer *mp = jni_get_media_player(env, thiz);
jobject saveListener = (*env)->NewGlobalRef(env, displayListener);
ijkmp_set_display_interface(mp, (void *)saveListener);
ijkmp_dec_ref_p(&mp);
}
FFplay是个前置声明的struct在ijkplayer_jni.c
中的不能访问的
ijkmp_set_display_interface
扩展在ijkplayer.c
中
void ijkmp_set_display_interface(IjkMediaPlayer *mp, void *display)
{
mp->ffplayer->display_interface = display;
}
- 最后在
video_image_display2
中执行display_interface
的Java方法顺利yuv420P的具体数据这就不用经过'render.c'和NativeWindow
了
最后小坑jclass
要手动释放···
3.18在数据回传时不应该使用java对象。这个操作会引发虚拟机频繁GC。STW的过于频繁会使应用卡成狗,最后将指针强转为long