VLC学习-2

      接到的新任务: 音视频同步, 而公司的视频播放已经由一位牛人做好,我必须把音频播放及同步两个功能加入到播放器中,因此在后面的流程学习中,在记录完程序初始化流程完成后,就先记录VLC音频播放流程了。

     

      不废话了,接前一章。

      先找到加载libplugin.dll的地方: 

       ->a. libvlc_new(vlc_argc, vlc_argv) 

       ->b. libvlc_init_threads()

       ->c.  libvlc_InteralCreate()

       ->d.  libvlc_InternalInit()  

                 ->d.1    module_InitBank()

                 ->d.2    module_LoadPlugins(p_libvlc )

                  ->d.3    AllocatePluginFile("libplugin.dll"),在文件module.c中.

     在软件使用中,可以将所有的插件都生成到统一个库中,比如libplugin.dll中,在程序中几经波折,总算是到了加载动态库的地方,那么我是反向回溯的方式,去学习组件的加载及调用过程的。我们进入到AllocatePluginFile这个接口中:

           ->s1: module_load(*libplugins.dll**): 加载动态库

           ->s2:sprintf(psz_name, "vlc_entry__%s", loopPszName[workFlag]); loopPszName是一个静态的变量

                     以其中的一个名称为例 loopPszName[74] = "aout_directx"

                     那么psz_name ="vlc_entry_aout_directx";

               ->s3: module_CallWithName(psz_name): 最终调用到

                         GetProcAddress( (HMODULE)handle, (char *)psz_function ). 这里就会产生一个问题,

                         这个psz_name = "vlc_entry_aout_directx"在动态库中是如何识别的?

              ->s4:  现在就到vlc的各个插件的定义的地方去了:

                          在下面的代码中 __VLC_SYMBOL(vlc_entry, symbol) 这个函数中调用:

                           vlc_module_set (p_module, VLC_MODULE_NAME,  (const char *)(MODULE_STRING))

                          这个MODULE_STRING 从哪儿冒出来的呢?那么我们设置预编译:

                               MODULE_NAME=aout_directx
                               MODULE_NAME_IS_directx
                               MODULE_STRING=\"aout_directx\"

vlc_module_begin(vout_directx)

vlc_module_end()


#define vlc_module_begin( symbol )                                            

    EXTERN_SYMBOL DLL_SYMBOL                                  \

    int CDECL_SYMBOL __VLC_SYMBOL(vlc_entry, symbol) ( module_t *p_module ); \
                                                                              \
    EXTERN_SYMBOL DLL_SYMBOL \

   int CDECL_SYMBOL  __VLC_SYMBOL(vlc_entry, symbol) ( module_t *p_module )   \

    {                                                                         \

        module_config_t *p_config = NULL;                                     \

        if (vlc_module_set (p_module, VLC_MODULE_NAME,                        \

                            (const char *)(MODULE_STRING)))                   \

            goto error;                                                       \

        {                                                                     \
            module_t *p_submodule = p_module;

#define vlc_module_end( )                                                     \

        }                                                                     \

        (void)p_config;                                                       \

        return VLC_SUCCESS;                                                   \
                                                                              \
    error:                                                                    \

        return VLC_EGENERIC;                                                  \

    }  

 看了以上的定义就是完整的实现了aout_directx的插件定义流程。那么在调用中是如何实现的呢?

--------------------------------------------------------------------------------------------------------

s1. 我们来看module.c中的module_need()接口:

  -> struct module_t
          {
             …….
             int ( * pf_activate ) ( vlc_object_t * );
             void ( * pf_deactivate ) ( vlc_object_t * );
         }

 在上面的vlc_module_begin(aout_directx)中就能看到的
set_callbacks( OpenAudio, CloseAudio ).

在module_need()的调用中
ret = p_cand->pf_activate( p_this ); 就将执行OpenAudio()接口

---->那么现在的问题继续来了,在vlc的如此多的插件中,是如何识别哪个插件是自己需要调用的呢?

-----------------------------------------------------------------------------------------------------------

   s1. 在audio_output/output.c中 aout_OutputNew() 中 /* Find the best output plug-in. */
           p_aout->output.p_module = module_need( p_aout, "audio output", "$aout", false );

   s2. 在module_need()接口中是如何找到最合适的plug-in的?

          module_need(vlc_object_t *p_this,const char *psz_capability,const char *psz_name, bool b_stric)

          参数中:psz_capability: 可以理解为该插件提供什么服务
   s3. 首先获取到所有的插件
         /* Sort the modules and test them */
         size_t count;
         module_t **p_all = (module_t **)module_list_get (&count); 
         p_list = (module_list_t *)malloc( count * sizeof( module_list_t ) );

  s4. 然后在这些所有的插件中找根据插件提供的服务进行匹配,如果插件能力跟调用时匹配就将该插件的指针

     (已经加载到内存中了的)放入的plist中).

      /* Test that this module can do what we need */

      if(!module_provides( p_module, psz_capability))

         continue;
  s5. 对pList进行排序: 执行qsort((), 然后执行找到第一个匹配的module 执行之
        怎么才叫找到了第一个匹配的module呢? 那就是pf_activate() 返回VLC_SUCESS



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值