VLC-Android消息机制介绍

本文深入探讨了VLC-Android的消息机制,包括接受外部控制事件如seek操作的处理,通过variables进行模块间通讯,以及如何向外部发送事件如buffering完成的通知。通过分析关键函数和变量,揭示了VLC事件从上层到下层的传递过程及其内部回调机制。
摘要由CSDN通过智能技术生成

VLC通过variables来接受外部控制事件和向外部发送事件,variables同时也可以作为modules之间简单通讯的载体。本文通过举例详细介绍下variables的功能。

接受外部控制事件

以seek为例,vlc-android在seek时可以调用MediaPlayer.java的setTime()方法。

/**

 * Sets the movie time (in ms), if any media is being played.

 * @param time: Time in ms.

 * @return the movie time (in ms), or -1 if there is no media.

 */

 public native long setTime(long time);

之后会调用libvlcjni-mediaplayer.c的Java_org_videolan_libvlc_MediaPlayer_setTime()

void

Java_org_videolan_libvlc_MediaPlayer_setTime(JNIEnv *env, jobject thiz,

                                             jlong time)

{

    vlcjni_object *p_obj = VLCJniObject_getInstance(env, thiz);

    if (!p_obj)

        return;

#if defined(LIBVLC_VERSION_MAJOR) && LIBVLC_VERSION_MAJOR < 4

    libvlc_media_player_set_time(p_obj->u.p_mp, time);

#else

    libvlc_media_player_set_time(p_obj->u.p_mp, time, false);

#endif

}

之后就是media_player.c的libvlc_media_player_set_time()

void libvlc_media_player_set_time( libvlc_media_player_t *p_mi,

                                   libvlc_time_t i_time )

{

    input_thread_t *p_input_thread;

    p_input_thread = libvlc_get_input_thread ( p_mi );

    if( !p_input_thread )

        return;

    var_SetInteger( p_input_thread, "time", to_mtime(i_time) );

    vlc_object_release( p_input_thread );

}

追到这里终于看到了本文的主角var了,这里给p_input_thread名为的"time"的var赋值,可以看出var应该类似ffmpeg的AVDictionaryEntry,保存的是键值对。p_input_thread的time一更新,就触发了seek逻辑,怎么看怎么像是设置了回调函数,追一下p_input_thread的init流程,果不其然:

//var callback注册流程

/*****************************************************************************

 * This function creates a new input, and returns a pointer

 * to its description. On error, it returns NULL.

 *

 * XXX Do not forget to update vlc_input.h if you add new variables.

 *****************************************************************************/

static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,

                               const char *psz_header, bool b_preparsing,

                               input_resource_t *p_resource,

                               vlc_renderer_item_t *p_renderer )

{

    ......

     

    //这里的var是vlc内部用的,建议不要set

    /* Create Object Variables for private use only */

    input_ConfigVarInit( p_input );

    //这些var是公开的,可以get和set,time变量就是在这里创建并注册的回调函数

    /* Create Objects variables for public Get and Set */

    input_ControlVarInit( p_input );

    ......

}

/*****************************************************************************

 * input_ControlVarInit:

 *  Create all control object variables with their callbacks

 *****************************************************************************/

void input_ControlVarInit ( input_thread_t *p_input )

{

    ......

    //创建time var

    /* Time */

    var_Create( p_input, "time", VLC_VAR_INTEGER );

    ......

    //注册回调函数,var一旦改变就会调用

    /* Add all callbacks

     * XXX we put callback only in non preparsing mode. We need to create the variable

     * unless someone want to check all var_Get/var_Change return value ... */

    if( !input_priv(p_input)->b_preparsing )

        InputAddCallbacks( p_input, p_input_callbacks );

}

/*****************************************************************************

 * Callbacks managements:

 *****************************************************************************/

static void InputAddCallbacks( input_thread_t *p_input,

                               const vlc_input_callback_t *p_callbacks )

{

    int i;

    for( i = 0; p_callbacks[i].psz_name != NULL; i++ )

        var_AddCallback( p_input,

                         p_callbacks[i].psz_name,

                         p_callbacks[i].callback, NULL );

}

//input添加的全部回调如下

/* List all callbacks added by input */

#define CALLBACK(name,cb) { name, cb }

static const vlc_input_callback_t p_input_callbacks[] =

{

    CALLBACK( "state", StateCallback ),

    CALLBACK( "rate", RateCallback ),

    CALLBACK( "position", PositionCallback ),

    CALLBACK( "time", TimeCallback ),

    CALLBACK( "time-offset", TimeOffsetCallback ),

    CALLBACK( "bookmark", BookmarkCallback ),

    CALLBACK( "program", ProgramCallback ),

    CALLBACK( "title", TitleCallback ),

    CALLBACK( "chapter", SeekpointCallback ),

    CALLBACK( "audio-delay", EsDelayCallback ),

    CALLBACK( "spu-delay", EsDelayCallback ),

    CALLBACK( "video-es", EsVideoCallback ),

    CALLBACK( "audio-es", EsAudioCallback ),

    CALLBACK( "spu-es", EsSpuCallback ),

    CALLBACK( "record", RecordCallback ),

    CALLBACK( "frame-next", FrameNextCallback ),

    CALLBACK( NULL, NULL )

};

time对应的回调函数是TimeCallback,一旦time被更新,就会调用TimeCallback

static int TimeCallback( vlc_object_t *p_this, char const *psz_cmd,

                         vlc_value_t oldval, vlc_value_t newval, void *p_data )

{

    input_thread_t *p_input = (input_thread_t*)p_this;

    VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_data);

    //这里更新了position变量,即MediaPlayer getCurrentPosition的返回值得到了更新

    //intf-event涉及到event的上报,我们在第二部分详细讲

    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值