Multimedia/GStreamer

GStreamer pwg ch 4~6

Roien 2021. 12. 22.
반응형

 

1.     Specifying the pads

 

  • Ÿ   _event() function
    • n  format 설정 함수
  • Ÿ   _init() 함수에서
    • n  _class_init에서 등록된 pad template에서 pad를 생성
  • Ÿ   _chain()
    • n  sinkpad에서 input dat를 받을 function pointer를 설정
  • Ÿ   _event() / _query()
    • n  선택적으로 설정 가능

 

pad의 동작

  • Ÿ   looping mode로 동작함
    • n  data를 스스로 pull 할 수 있음

 

static void
gst_my_filter_init (GstMyFilter *filter) {
  /* pad through which data comes in to the element */
filter->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
 
  /* pads are configured here with gst_pad_set_*_function () */
  gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
 
  /* pad through which data goes out of the element */
filter->srcpad = gst_pad_new_from_static_template (&src_template, "src");
 
  /* pads are configured here with gst_pad_set_*_function () */
  gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
 
  /* properties initial value */
  filter->silent = FALSE;
}
 

 

 

5.     The Chain function

chain function은 모든 data가 위치하게 되는 function

 

Ÿ   _chain()

  • n  아래 코드에서는 linear function
  • n  각 incoming buffer에 대해서 buffer 하나를 내보냄

 

static GstFlowReturn gst_my_filter_chain (GstPad    *pad,
                                          GstObject *parent,
                                          GstBuffer *buf);
 
[..]
 
static void
gst_my_filter_init (GstMyFilter * filter)
{
[..]
  /* configure chain function on the pad before adding
   * the pad to the element */
gst_pad_set_chain_function (filter->sinkpad, gst_my_filter_chain);
 
[..]
}
 
static GstFlowReturn
gst_my_filter_chain (GstPad    *pad,
                     GstObject *parent,
             GstBuffer *buf)
{
  GstMyFilter *filter = GST_MY_FILTER (parent);
 
  if (!filter->silent)
    g_print ("Have data of size %" G_GSIZE_FORMAT" bytes!\n",
        gst_buffer_get_size (buf));
 
  return gst_pad_push (filter->srcpad, buf);
} 

 

buffer read-only 일 수도 있음

 

event handling function을 추가 할 수도 있음

stream-event가 보내지면 호출됨

  • Ÿ   caps
  • Ÿ   EOS
  • Ÿ   newsegment
  • Ÿ   tags
  • Ÿ   …
static void
gst_my_filter_init (GstMyFilter * filter) {
[..]
  gst_pad_set_event_function (filter->sinkpad,
      gst_my_filter_sink_event);
[..]
}
 
 
static gboolean
gst_my_filter_sink_event (GstPad    *pad,
                  GstObject *parent,
                  GstEvent  *event) {
  GstMyFilter *filter = GST_MY_FILTER (parent);
 
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
      /* we should handle the format here */
      break;
    case GST_EVENT_EOS:
      /* end-of-stream, we should close down all stream leftovers here */
      gst_my_filter_stop_processing (filter);
      break;
    default:
      break;
  }
 
  return gst_pad_event_default (pad, parent, event);
}
 
 
static GstFlowReturn
gst_my_filter_chain (GstPad    *pad,
             GstObject *parent,
             GstBuffer *buf) {
  GstMyFilter *filter = GST_MY_FILTER (parent);
  GstBuffer *outbuf;
 
  outbuf = gst_my_filter_process_data (filter, buf);
  gst_buffer_unref (buf);
  if (!outbuf) {
    /* something went wrong - signal an error */
    GST_ELEMENT_ERROR (GST_ELEMENT (filter), STREAM, FAILED, (NULL), (NULL));
    return GST_FLOW_ERROR;
  }
 
  return gst_pad_push (filter->srcpad, outbuf);
}

 

 

6.     The event function

data stream 상에 event가 발생하면 호출됨

  • Ÿ   caps, EOS, netsegment, tags, etc.
  • Ÿ   event는 upstream과 downstream으로 둘 다 흐름
    • n  즉, sink pads와 source pads에서 event를 받을 수 있음

 

sink pad 상에 설치된 간단한 event function

static gboolean gst_my_filter_sink_event (GstPad    *pad,
                                          GstObject *parent,
                                          GstEvent  *event);
 
[..]
 
static void
gst_my_filter_init (GstMyFilter * filter) {
[..]
  /* configure event function on the pad before adding
   * the pad to the element */
  gst_pad_set_event_function (filter->sinkpad,
      gst_my_filter_sink_event);
[..]
}
 
static gboolean
gst_my_filter_sink_event (GstPad    *pad,
                  GstObject *parent,
                  GstEvent  *event) {
  gboolean ret;
  GstMyFilter *filter = GST_MY_FILTER (parent);
 
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
      /* we should handle the format here */
 
      /* push the event downstream */
      ret = gst_pad_push_event (filter->srcpad, event);
      break;
    case GST_EVENT_EOS:
      /* end-of-stream, we should close down all stream leftovers here */
      gst_my_filter_stop_processing (filter);
      ret = gst_pad_event_default (pad, parent, event);
      break;
    default:
      /* just call the default handler */
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }
  return ret;
} 

 

Ÿ   알려지지 않은 event에 대해서는 기본 event handler gst_pad_event_default()를 호출하는 것이 좋음

Ÿ   event type에 따라서, default handler event를 넘기던가 단순히 unref하기도 함

Ÿ   CAPS event

n  기본적으로 forward하지 않음

n  직접 처리해야 함

 

반응형

'Multimedia > GStreamer' 카테고리의 다른 글

GStreamer plugin writer's guide: part 1  (0) 2021.12.22
GStreamer pwg ch. 3  (0) 2021.12.22
GStreamer pwg ch 7 ~ 9  (0) 2021.12.22
GStreamer pwg ch 11  (0) 2021.12.22
GStreamer pwg: ch 12  (0) 2021.12.22

댓글