Native Protocol 命令扩展

任何stream试图连接到PA的时候,socket的callback会调用这个函数

pa_native_protocol_connect (pa_native_protocol *p, pa_iochannel *io, pa_native_options *o)

改函数,将建立一个S端stream对应这个io,同时注册这个stream的callback,在命令扩展中,关注的是如下这个cb

static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata)

注册如下

    pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c);

c[ pa_native_connection *c;]是userdata

同时,注意到:

c->pdispatch = pa_pdispatch_new(p->core->mainloop, TRUE, command_table, PA_COMMAND_MAX);

一般的命令将匹配到这个command_table的函数指针来处理。

如何调用到这些函数指针

1. pstream 的io_callback调用到do_read

2. pstream_packet_callback是之前注册的cb,在上述函数被调用

3. 看pstream_packet_callback这个函数,掉用了pa_pdispatch_run

4. 最后看看这个run函数

上面还只是一般命令的执行过程,下面看看,如何扩展命令,如何使用自己扩展的命令

发送扩展命令的时候,命令有两个部分,主命令,子命令。主命令是固定的

PA_COMMAND_EXTENSION

子命令即用户自定义命令,这个首先要定义好的。例如

enum
 {
    SUBCOMMAND_TEST,
    SUBCOMMAND_READ,
    SUBCOMMAND_WRITE,
    SUBCOMMAND_DELETE,
    SUBCOMMAND_SUBSCRIBE,
    SUBCOMMAND_EVENT
};  

然后建立扩展命令的入口函数,函数名任意,格式固定的

static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) 

 然后,通过如下函数,置函数指针。

 pa_native_protocol_install_ext(u->protocol, m, extension_cb);

再看通用扩展函数 command_extension

这样,就可以了解扩展命令的工作流程。

至于如何调用,参考如下这段代码

pa_operation *pa_ext_stream_restore_test(
        pa_context *c,
        pa_ext_stream_restore_test_cb_t cb,
        void *userdata) {

    uint32_t tag;
    pa_operation *o;
    pa_tagstruct *t;

    pa_assert(c);
    pa_assert(PA_REFCNT_VALUE(c) >= 1);

    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);

    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);

    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
    pa_tagstruct_puts(t, "module-stream-restore"
);
    pa_tagstruct_putu32(t, SUBCOMMAND_TEST);
    pa_pstream_send_tagstruct(c->pstream, t);
    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_stream_restore_test_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);

    return
 o;
}

对于 pa_pdispatch_register_reply 的双重callback,我的理解是,当前注册的cb为自己所用,pa_operation_new引入的cb为用户应用自定义callback

我的理解源于 Moblin Audio Manager的API

pa_operation* am_set_stream_volume(pa_context * c,  am_set_cb_t cb, uint32_t index, pa_volume_t v, void* userdata){
    uint32_t tag;
    pa_tagstruct *t;
    pa_operation* o;

    pa_assert(c);
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, NULL);
    t = am_tag_command(c, &tag, AM_COMMAND_SET_STREAM_VOLUME);

    pa_tagstruct_putu32(t,index) ;
    pa_tagstruct_putu32(t,v) ;
   
    pa_pstream_send_tagstruct(c->pstream, t);
    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, am_set_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);   
    return
 o;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值