Multimedia/GStreamer

GStreamer pwg ch 7 ~ 9

Roien 2021. 12. 22.
반응형

 

7.     The query function

query function으로

    Ÿ   element queries를 받을 수 있음

    Ÿ   query types

        n  position

        n  duration

        n  supported formats

        n  scheduling modes

    Ÿ   travel

        n  upstream downstream 둘 다 이동 가능

        n  sink pads source pads에서 다 받을 수 있음

 

 

static gboolean gst_my_filter_src_query (GstPad    *pad,
                                         GstObject *parent,
                                         GstQuery  *query);
 
[..]
 
static void
gst_my_filter_init (GstMyFilter * filter) {
[..]
  /* configure event function on the pad before adding
   * the pad to the element */
  gst_pad_set_query_function (filter->srcpad,
      gst_my_filter_src_query);
[..]
}
 
static gboolean
gst_my_filter_src_query (GstPad    *pad,
                 GstObject *parent,
                 GstQuery  *query) {
  gboolean ret;
  GstMyFilter *filter = GST_MY_FILTER (parent);
 
  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
      /* we should report the current position */
      [...]
      break;
    case GST_QUERY_DURATION:
      /* we should report the duration here */
      [...]
      break;
    case GST_QUERY_CAPS:
      /* we should report the supported caps here */
      [...]
      break;
    default:
      /* just call the default handler */
      ret = gst_pad_query_default (pad, parent, query);
      break;
  }
  return ret;
}
 

 

모르는 query에 대해서는 default query handler gst_pad_query_default()를 호출하는 것이 좋음

이는 query를 전달하던가 혹은 unref 

 

 

8.     What are states?

Ÿ   state는 상태를 설명함

Ÿ   상태 종류 (4가지)

    n  GST_STATE_NULL

        s   자원이 할당되지 않은 상태

    n  GST_STATE_READY

        s   기본 자원들 (lib들 포함)이 할당된 상태

        s   stream-specific한 것은 할당되지 않은 상태

        s   GST_STATE_CHANGE_NULL_TO_READY

            -       NULL에서 READY로 전환하는 상태

            -       non-stream-specific 자원을 할당해야 함 (lib loading 포함)

        s   GST_STATE_CHANGE_READY_TO_NULL

            -       할당 한 것들을 unload

                n  ex. hardware device 

                n  file stream 자원임 (stream-specific resource)

    n  GST_STATE_PAUSED

        s   data를 받아들일 상태가 되었음

        s   보통의 element에서 이는 PLAYING과 동일한 상태

            -       차이는 sink에만 있음

            -       sink element는 하나의 버퍼만 받아들이고 block

            -       이 시점이 pipeline 'prerolled'이며

    n  이는 data를 즉각 render할 준비가 된 상태임

    n  GST_STATE_PLAYING

        s   PAUSED와 거의 동일

        s   차이는

            -       buffer data를 처리한다는 점

            -       sink element paused playing 상태를 구분함

    n  sink element data rendering 수행

 

 

8.1.     managing filter state

Pre-made base class들을 사용할 경우 state 처리에 대해 별로 할 것은 없다.

할 것은 class

    Ÿ   start stop override

        n  base class에 의해서 호출됨

 

ready-made class derived하지 않을 경우

    Ÿ   GstElement나 다른 class base class 위에 만들어지지 않은 경우

    Ÿ   state change function을 직접 구현해야 함

        n  stage change의 변경을 notify 받기 위한 함수를 구현해야 함

        n  demuxer muxer인 경우 필요함

            s   demuxer, muxer base class가 없음

 

모든 element state change virtual function pointer를 통해서 noti 받음

이 함수 내에서 element는 필요한 초기화를 수행해야 함

 

다뤄지지 않은 state change GstElement base class가 처리함

 

static GstStateChangeReturn
gst_my_filter_change_state (GstElement *element, GstStateChange transition);
 
static void
gst_my_filter_class_init (GstMyFilterClass *klass) {
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
  element_class->change_state = gst_my_filter_change_state;
}
 
 
static GstStateChangeReturn
gst_my_filter_change_state (GstElement *element, GstStateChange transition) {
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstMyFilter *filter = GST_MY_FILTER (element);
 
  switch (transition) {
        case GST_STATE_CHANGE_NULL_TO_READY:
          if (!gst_my_filter_allocate_memory (filter))
               return GST_STATE_CHANGE_FAILURE;
          break;
        default:
          break;
  }
 
  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
        return ret;
 
  switch (transition) {
        case GST_STATE_CHANGE_READY_TO_NULL:
          gst_my_filter_free_memory (filter);
          break;
        default:
          break;
  }
 
  return ret;
}

 

Ÿ   upwards

    n  NULL à READY

    n  READY à PAUSED

    n  PAUSED à PLAYING

 

Ÿ   downwards

    n  PLAYING à PAUSED

    n  PAUSED à READY

    n  READY à NULL

 

Ÿ   upward downward state change는 각각 다른 block에서 처리됨

    n  parent state change function chain up 한 이후에야 downward state change handle

        s   여러thread에 의한 동시 접속에 안전을 기하기 위함

 

Ÿ   downwards state change의 경우

    n  plugin chain 함수가 여전히 다른 thread에 의해 access 될 때 할당된 resource의 해제를 원치 않을 수 있음

    n  chain 함수가 plugin pad 상태에 의존하여 동작하던 아니던, pad들이 element의 상태에 밀접하게 열결 되었던

        s   pad state GstElement class state change 함수에서 처리됨

            -       적절한 locking을 포함

        s   이것이 자원 해제 전에 chain up 해야 하는 1이유임

 

 

9.     Adding Properties

element의 동작은

Ÿ   GObject property 설정에 따라 달라짐

Ÿ   _class_init에서 GObject property가 정의되며 아래 함수들을 구현할 수 있음

    n  _get_property

    n  _set_property

 

Ÿ   이 함수들은 application property 값에 변경 및 read 요청을 하면 호출 됨

    n  이 함수 내에서 값을 채우던가 적절한 value 변경을 수행함

 

default value

    Ÿ   GOjbect는 자동으로 default value를 설정하지 않음

    Ÿ   _init에서 명시적으로 설정 해 줘야 함

 

/* properties */
enum {
  PROP_0,
  PROP_SILENT
  /* FILL ME */
};
 
static void gst_my_filter_set_property  (GObject      *object,
                         guint         prop_id,
                         const GValue *value,
                         GParamSpec   *pspec);
static void gst_my_filter_get_property  (GObject      *object,
                         guint         prop_id,
                         GValue       *value,
                         GParamSpec   *pspec);
 
static void
gst_my_filter_class_init (GstMyFilterClass *klass) {
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
  /* define virtual function pointers */
  object_class->set_property = gst_my_filter_set_property;
  object_class->get_property = gst_my_filter_get_property;
 
  /* define properties */
  g_object_class_install_property (object_class, PROP_SILENT,
    g_param_spec_boolean ("silent", "Silent",
              "Whether to be very verbose or not",
              FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
 
static void
gst_my_filter_set_property (GObject      *object,
                guint         prop_id,
                const GValue *value,
                GParamSpec   *pspec) {
  GstMyFilter *filter = GST_MY_FILTER (object);
 
  switch (prop_id) {
    case PROP_SILENT:
      filter->silent = g_value_get_boolean (value);
      g_print ("Silent argument was changed to %s\n",
           filter->silent ? "true" : "false");
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
 
static void
gst_my_filter_get_property (GObject    *object,
                guint       prop_id,
                GValue     *value,
                GParamSpec *pspec) {
  GstMyFilter *filter = GST_MY_FILTER (object);
 
  switch (prop_id) {
    case PROP_SILENT:
      g_value_set_boolean (value, filter->silent);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

 

property 추가 시,

    Ÿ   값의 range valid 여부 처리

    Ÿ   descriptive string 추가

    Ÿ   상수값 대신 enum 등의 값 사용

 

 

property가 유용하게 사용되는 example (from videotestsrc)

 

typedef enum {
  GST_VIDEOTESTSRC_SMPTE,
  GST_VIDEOTESTSRC_SNOW,
  GST_VIDEOTESTSRC_BLACK
} GstVideotestsrcPattern;
 
[..]
 
#define GST_TYPE_VIDEOTESTSRC_PATTERN (gst_videotestsrc_pattern_get_type ())
 
static GType
gst_videotestsrc_pattern_get_type (void) {
  static GType videotestsrc_pattern_type = 0;
 
  if (!videotestsrc_pattern_type) {
    static GEnumValue pattern_types[] = {
      { GST_VIDEOTESTSRC_SMPTE, "SMPTE 100% color bars",    "smpte" },
      { GST_VIDEOTESTSRC_SNOW,  "Random (television snow)", "snow"  },
      { GST_VIDEOTESTSRC_BLACK, "0% Black",                 "black" },
      { 0, NULL, NULL },
    };
 
    videotestsrc_pattern_type =
    g_enum_register_static ("GstVideotestsrcPattern",
                pattern_types);
  }
 
  return videotestsrc_pattern_type;
}
 
[..]
 
static void
gst_videotestsrc_class_init (GstvideotestsrcClass *klass) {
[..]
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PATTERN,
    g_param_spec_enum ("pattern", "Pattern",
               "Type of test pattern to generate",
                       GST_TYPE_VIDEOTESTSRC_PATTERN, GST_VIDEOTESTSRC_SMPTE,
                       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
[..]
}

 

반응형

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

GStreamer pwg ch. 3  (0) 2021.12.22
GStreamer pwg ch 4~6  (0) 2021.12.22
GStreamer pwg ch 11  (0) 2021.12.22
GStreamer pwg: ch 12  (0) 2021.12.22
GStreamer pwg: ch 13  (0) 2021.12.22

댓글