搜尋此網誌

2011年1月30日 星期日

Gstreamer Pad

  • The relationship between pad and caps
                           |-name_template(eg:wavparse_src, wavparse_sink)
                           |
                           |-direction(src or sink)
      GstStaticPadTemplate-|
              |            |-presence(Sometimes, Always, request)
              |            |
              |            |                  |-GstCaps(String is stored in GstStruct)
              |            |-GstStaticCaps----|
              |                               |-String(support caps)
       gst_static_pad_template_get()
              |
              |           |-GstObject
              V           |
      GstPadTemplate------|-direction
              |           |
              |           |-presence
              |           |
              |           |-GstCaps
              |
       gst_pad_new_from_static_template()
              |
              |
              V    |-GstObject
      GstPad-------|-GstPadTemplate
                   |...
    
  • Add pad into element and set relation
    gst_element_add_pad(element, pad)
      {
          _set_parent(element, pad) {
              pad->parent = element
          }
      
          if(pad->direction == src)
              element->srcpads = pad
          else if(pad->direction == sink)
              element->sinkpads = pad
      
          element->pads = pad
      }
      
      +---------+         +------------+         +---------+
      |      parent------>|  element   |<------parent      |
      | Gstpad  |<-----sinkpad      srcpad------>|  GstPad |
      +---------+         +------------+         +---------+
      
    
  • Set pad active from srcpad to sinkpad
    1. element state change from READY to PAUSE, set pad active
      gst_element_pads_activate(element, TRUE)
        {
            //set srcpad
            activate_pads(element->srcpads, TRUE);
            //set sinkpad
            activate_pads(element->sinkpads, TRUE);
        }
      
    2. check pad current mode and call pad->activefunc
      gst_pad_set_active(pad)
        {
            mode = GST_PAD_ACTIVATE_MODE(pad);
            if(mode == GST_ACTIVATE_PUSH || mode == GST_ACTIVATE_PULL) {
                //pad already activation
                return TRUE;
            }
            else if (mode == GST_ACTIVATE_NONE)
                GST_PAD_ACTIVATEFUNC(pad) (pad);
        }
      
    3. call pad->activepushfunc or pad->activepullfunc, default is pushfunc
      gst_pad_activate_push(pad)
        {
            GST_PAD_ACTIVATE_MODE(pad) = GST_ACTIVATE_PUSH;
        
            GST_PAD_ACTIVATEPUSHFUNC(pad) (pad);
        }
        gst_pad_activate_pull(pad)
        {
            GST_PAD_ACTIVATE_MODE(pad) = GST_ACTIVATE_PULL;
        
            GST_PAD_ACTIVATEPULLFUNC(pad) (pad);
        }
      

2011年1月14日 星期五

Gstreamer State Change

  • Some concepts of States
    1. States defined in gstreamer
      • GST_STATE_VOID_PENDING: the state of an element is not set.
      • GST_STATE_NULL: initial state of an element.
      • GST_STATE_READY: all sources are ready and can go to pause.
      • GST_STATE_PAUSE: ready to accept and process data.
      • GST_STATE_PLAYING: the GstClock is running and the data is flowing.
    2. Variables in GstElement
      • current_state: the current state of an element.
      • next_state: the next state of an element.
      • pending_state: the final state the element should go to.
      • target_state: last state the element we set.
      • last_return: the last return value of an element state change.
    3. The states switch
  • Create a simple pipe to understand what are states
    $ gst-launch-0.10 alsasrc ! audiorate ! filesink location=test.wav
    
  • At the beginning, gstreamer core how to initialize each element
    1. Use funtion gst_element_factory_make("alsasrc", "sound") to create alsasrc element
    2. When create instance of alsasrc(sound), gst_element_init() will initial state of the element.
      GST_STATE_TARGET (element) = GST_STATE_NULL;            //target_state
      GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;      //next_state
      GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;   //pending_state
      GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;  //last_return 
      GST_STATE (element) = GST_STATE_NULL;                   //current_state 
  • Use function gst_bin_add_many to add elements to pipeline. Just add each element to GstBin->children, didn't change state of element
  • After link success I want to change state of pipeline from GST_STATE_NULL to GST_STATE_PLAYING
    1. Now the state of element is GST_STATE_NULL, first change the state to GST_STATE_READY. All elements are added in GstBin->cheldren, when we change the state of pipeline to GST_STATE_READY, pipeline will call gst_bin_change_state_func to find child elemnt to change state to GST_STATE_READY. each child element will call plugin->change_state which defined by ourselves.
    2. If state change to GST_STATE_READY successfully, update state of element, then try to change state of pipeline from GST_STATE_READY to GST_STATE_PAUSE. Alsa call gst_bin_change_state_func, the same as step 1.
    3. If state change to GST_STATE_PAUSE successfully, update state of element, then try to change state of pipeline from GST_STATE_PAUSE to GST_STATE_READY. Alsa call gst_bin_change_state_func, the same as step 1.
  • When accept message GST_MESSAGE_EOS, try to change the state of pipeline from GST_STATE_PLAYING to GST_STATE_NULL

2011年1月7日 星期五

ubuntu samba server

  1. Installl samba
    $ sudo apt-get install samba4 
    (install samba, server can not start, i don't know why)
    $ sudo apt-get install smbclient
    
  2. Configure /etc/samba/smb.conf
    [global]
          security = share
    [share]
          comment = chenorui
          path = /home/chenorui/share
          public = yes
          guest ok = yes
          browsable = yes
          writable = no
    
  3. Restart samba server
    $ sudo /etc/init.d/samba4 restart
    
  4. Look at what services are available on a server
    $ smbclient -L //yourIP
      Domain=[WORKGROUP] OS=[Unix] Server=[Samba 3.5.4]
      
      Sharename       Type      Comment
      ---------       ----      -------
      IPC$            IPC       IPC Service (chenorui server (Samba, Ubuntu))
      share           Disk      chenorui
      HP-LaserJet-M1522 Printer   HP LaserJet M1522
      Domain=[WORKGROUP] OS=[Unix] Server=[Samba 3.5.4]
      
      Server               Comment
      ---------            -------
      
      Workgroup            Master
      ---------            -------
    
  5. Login share profile
    $ smbclient //yourIP/share
      smb: \>
    
  6. mount share profile
    $ sudo smbmount //yourIP/share /tmp/test
    

2011年1月5日 星期三

gstreamer caps negotiation

协商过程中主要函数:
gst_pad_get_caps/gst_pad_set_getcaps_function, gst_pad_set_caps/gst_pad_set_setcaps_function。

gst_pad_get_caps 函数用来返回该pad能接受的caps。首先检查getcaps函数指针是否为NULL,如果不是则调用getcaps函数,这是一个函数指针,我们可以通过gst_pad_set_getcaps_function来给这个函数指针赋值,从而实现自定义的get_caps函数的逻辑。完成后函数返回;如果getcaps函数指针为NULL,则gst_pad_get_caps函数从该pad的pad template中列出所有的caps,返回;如果该pad没有pad template,则gst_pad_get_caps函数检查该GstPad的caps成员是否为NULL,如果不为NULL,则返回这个 member;最后,如果前面的都不成立,则gst_pad_get_caps创建一个empty的GstCaps并返回,表示该pad目前没有caps。

get_pad_set_caps 函数用来设置指定pad的caps。该函数首先检查参数中给出的caps是否已经和目前该pad中的caps相同,如果是,则直接返回。如果不相同,则检查setcaps函数指针是否为NULL,如果不为NULL则调用setcaps函数。我们可以通过 gst_pad_set_setcaps_function函数来给setcaps这个函数指针赋值,这样就在gst_pad_set_caps函数中实现了自定义的逻辑。注意,gst_pad_set_caps函数会判断setcaps函数的返回值,如果是FALSE,则会直接报错return FALSE,这样的结果就是gst_pad_set_caps函数执行失败,caps negotiation失败。当setcaps函数执行完毕后,gst_pad_set_caps函数执行gst_caps_replace,将保存在该pad中的caps member替换成参数中指定的caps,然后函数结束。

PUSH MODE:   
              src              sink
              |                 |
              |  accepts?       |
  type A      |---------------->|
              |      yes        |
              |<----------------|
              |                 |
 get buffer   |  alloc_buf      |
 from pool    |---------------->| 
 with type A  |                 | Create buffer of type A.
              |                 |
 check type   |<----------------|
 and use A    |                 |
              |  push           |
 push buffer  |---------------->| Receive type A, reconfigure to
 with new type|                 | process type A.
              |                 |
PUSH MODE下,总是由src pad发起negotiation,为了让src pad和peer sink pad都能接受的caps来,src pad会将自己的caps和peer sink pad的caps做intersect,这时就会调用函数gst_pad_get_caps,参数就是peer sink pad(一般直接使用gst_pad_peer_get_caps函数一步完成)。如果 peer sink pad没有设置getcaps函数指针的话,那就会直接返回peer sink pad template中的所有caps。接下去就是src pad调用gst_pad_set_caps,把自己的caps确定下来,再然后就是申请并分配buffer

PULL MODE
src              sink
              |                 |
              |  accepts?       |
              |<----------------| type B
              |      yes        |
              |---------------->|
              |                 |
 get buffer   |  alloc_buf      |
 from pool    |---------------->| 
 with type A  |                 | Create buffer of new type B.
              |                 |
 check type   |<----------------|
 and          |                 |
 reconfigure  |                 |
              | pull            |
              |<----------------| Pull buffer from the peer src pad 
              |                 |
PULL MODE下,由于是sink element的sink pad来drive pipeline,所以,caps negotiation要在pull thread启动之前就完成。首先,sink pad将自己的caps和peer src pad的caps做intersect(需调用peer src pad上的gst_pad_get_caps),之后调用gst_pad_set_caps将sink pad caps确定下来。调用gst_pad_set_caps,设置peer src pad,如果成功,那么表示src pad和自己一样,都具备了相同的caps,这样negotiation就成功了。最后,可以使用gst_pad_pull_range来获取数据,这个函数会为我们检查buffer中的caps和当前sink pad中的caps是否一致,如果不一致,就会return GST_FLOW_NOT_NEGOTIATED。

gst_pad_set_caps 被调用的时机。当在_chain函数中收到一个buffer之后,一般需要检查该buffer中的caps是否和当前pad中的caps相同,以防止数据在运行过程中改变caps。如果这两个caps不相同,那么,_chain函数应该返回GST_FLOW_NOT_NEGOTIATED,这样,gstreamer core就会用buffer中这个新的caps,去调用gst_pad_set_caps,这样做的目的是gstreamer要知道pad能否接受这个 caps,如果函数返回TRUE,表示接受该caps,而且pad已经更新了自己的caps为目前这个,如果函数返回FALSE,表示caps negotiation failed,pipeline就无法正常运行了。

在 PUSH模式下,_chain函数返回GST_FLOW_NOT_NEGOTIATED,gstreamer core就会自动为我们调用gst_pad_set_caps;但是在PULL模式下,虽然gst_pad_pull_range也会返回 GST_FLOW_NOT_NEGOTIATED,但是gst_pad_set_caps并不会自动被调用,gstramer不支持在pull thread中做set caps的动作。所以,在PULL模式下,我们需要自己处理这种GST_FLOW_NOT_NEGOTIATED的情况。回想pull thread没有启动之前,为什么我们需要设置setcaps函数呢?这是因为我们需要在这个函数中,使用gst_pad_set_caps来给peer src pad设置caps来完成caps negotiation,而这个动作在PUSH模式下,只要peer element的_chain函数返回GST_FLOW_NOT_NEGOTIATED,gstreamer core就会自动为我们调用peer src pad上的gst_pad_set_caps,所以,PUSH模式下,我们不需要去设置setcaps函数指针。

不能上网了!!!!

adsl modern坏了,上不了网,狂晕:(
周末逛电脑城。。。