ijkplayer使用案例,摆脱render.c

作者: 睡后3k | 来源:发表于2017-03-15 23:55 被阅读774次

有人说我写的都是水文,所以这篇这是毫无逻辑的水文

这里 提到过ijkplayer在Android可以通过surface来进行自定义OpenGL渲染,其中的原理就是利用OpenGL的extension来获取纹理

可惜的是像魅族这种机器,明明说支持GL_OES_EGL_image_external然后死活编译不通过, 看来还是要通过手动的方式来操作

在贴大段的代码前先要搞明白状况

  1. ijk在哪里回传解码数据
  2. 回传过来的是i420, nv12, rbg565,rgba8888的哪一种
  3. JNI怎么交给Java,用什么类型打包

答日:

  1. ffplay.cvideo_image_display2方法, 参数中的overlay就包含我们想要pixcels

  2. 这个格式可以通过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" },
  1. 回传的话我这里采用笨办法
  • 在FFplayer中添加void * 指向我们的Interface;
  • 在video_image_display2中执行interface方法
  • 使用byte[]打包数据并附带width,height等重要信息

接下来就可以贴代码了

  1. Java层配置
player.native_setDisplayInterface(this);
        player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", "fcc-i420");

native_setDisplayInterface是自定义添加回调的方法

  1. 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;
}
  1. 最后在 video_image_display2中执行display_interface的Java方法顺利yuv420P的具体数据这就不用经过'render.c'和NativeWindow

最后小坑jclass要手动释放···

3.18在数据回传时不应该使用java对象。这个操作会引发虚拟机频繁GC。STW的过于频繁会使应用卡成狗,最后将指针强转为long

相关文章

网友评论

    本文标题:ijkplayer使用案例,摆脱render.c

    本文链接:https://www.haomeiwen.com/subject/nmtdnttx.html