본문 바로가기
IT와 개발/GStreamer Study

Building a Test Application

by 도서 임보자 2024. 10. 11.

종종 가능한 한 작은 설정에서 새로 작성한 플러그인을 테스트하고 싶을 것입니다. 일반적으로 gst-launch-1.0은 플러그인을 테스트하는 데 좋은 첫 번째 단계입니다. GStreamer가 검색하는 디렉토리에 플러그인을 설치하지 않은 경우 플러그인 경로를 설정해야 합니다. GST_PLUGIN_PATH를 플러그인이 있는 디렉토리로 설정하거나 명령줄 옵션 --gst-plugin-path를 사용합니다. 플러그인을 gst-plugin 템플릿을 기반으로 한 경우 이는 gst-launch-1.0 --gst-plugin-path=$HOME/gst-template/gst-plugin/src/.libs TESTPIPELINE과 유사합니다. 그러나 gst-launch-1.0에서 제공할 수 있는 것보다 seeking, 이벤트, 상호 작용 등 더 많은 테스트 기능이 필요한 경우가 많습니다. 이를 달성하는 가장 쉬운 방법은 직접 작은 테스트 프로그램을 작성하는 것입니다. 이 섹션에서는 몇 마디로 그 방법을 설명합니다. 전체 애플리케이션 개발 가이드는 애플리케이션 개발 매뉴얼의 하위 섹션들을 참조하세요.

 

시작할 때 gst_init()을 호출하여 GStreamer 코어 라이브러리를 초기화해야 합니다. 또는 gst_init_get_option_group()을 호출할 수 있으며, 이는 GOptionGroup에 대한 포인터를 반환합니다. 그런 다음 GOption을 사용하여 초기화를 처리할 수 있으며, 이렇게 하면 GStreamer 초기화가 완료됩니다.

 

gst_element_factory_make()를 사용하여 element를 만들 수 있습니다. 여기서 첫 번째 인수는 만들려는 element 유형이고 두 번째 인수는 자유 형식 이름입니다. 아래의 예제에서는 간단한 filesource - decoder - soundcard 출력 파이프라인을 사용하지만 필요한 경우 특정 디버깅 element를 사용할 수 있습니다. 예를 들어, 파이프라인 중간에 identity element를 사용하여 date-to-application transmitter 역할을 할 수 있습니다. 이를 사용하여 테스트 애플리케이션에서 데이터의 오작동이나 정확성을 확인할 수 있습니다. 또한 파이프라인 끝에 fakesink element를 사용하여 데이터를 stdout에 덤프할 수 있습니다 (이렇게 하려면 dump 속성을 TRUE로 설정). 마지막으로 valgrind를 사용하여 메모리 오류를 확인할 수 있습니다.


파이프라인 연결 중에 테스트 애플리케이션은 filtered cap을 사용하여 특정 유형의 데이터를 element로 또는 element에서 가져올 수 있습니다. 이는 element에서 여러 유형의 입력 및 출력을 확인하는 매우 간단하고 효과적인 방법입니다.

 

실행하는 동안 bus 및/또는 플러그인/element에서 최소한 "error" 및 "eos" 메시지를 수신하여 이를 올바르게 처리하는지 확인해야 합니다. 또한 파이프라인에 이벤트를 추가하고 플러그인이 이를 올바르게 처리하는지 확인해야 합니다 (clocking, 내부 캐싱 등과 관련하여).


플러그인이나 테스트 애플리케이션에서 메모리를 정리하는 것을 잊지 마세요. NULL 상태로 전환되면 element는 할당된 메모리와 캐시를 정리해야 합니다. 또한 가능한 지원 라이브러리에 대한 모든 참조를 닫아야 합니다. 애플리케이션은 파이프라인을 unref() 하여 충돌하지 않도록 해야 합니다.

#include <gst/gst.h>

static gboolean
bus_call (GstBus     *bus,
      GstMessage *msg,
      gpointer    data)
{
  GMainLoop *loop = data;

  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_EOS:
      g_print ("End-of-stream\n");
      g_main_loop_quit (loop);
      break;
    case GST_MESSAGE_ERROR: {
      gchar *debug = NULL;
      GError *err = NULL;

      gst_message_parse_error (msg, &err, &debug);

      g_print ("Error: %s\n", err->message);
      g_error_free (err);

      if (debug) {
        g_print ("Debug details: %s\n", debug);
        g_free (debug);
      }

      g_main_loop_quit (loop);
      break;
    }
    default:
      break;
  }

  return TRUE;
}

gint
main (gint   argc,
      gchar *argv[])
{
  GstStateChangeReturn ret;
  GstElement *pipeline, *filesrc, *decoder, *filter, *sink;
  GstElement *convert1, *convert2, *resample;
  GMainLoop *loop;
  GstBus *bus;
  guint watch_id;

  /* initialization */
  gst_init (&argc, &argv);
  loop = g_main_loop_new (NULL, FALSE);
  if (argc != 2) {
    g_print ("Usage: %s <mp3 filename>\n", argv[0]);
    return 01;
  }

  /* create elements */
  pipeline = gst_pipeline_new ("my_pipeline");

  /* watch for messages on the pipeline's bus (note that this will only
   * work like this when a GLib main loop is running) */
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  watch_id = gst_bus_add_watch (bus, bus_call, loop);
  gst_object_unref (bus);

  filesrc  = gst_element_factory_make ("filesrc", "my_filesource");
  decoder  = gst_element_factory_make ("mad", "my_decoder");

  /* putting an audioconvert element here to convert the output of the
   * decoder into a format that my_filter can handle (we are assuming it
   * will handle any sample rate here though) */
  convert1 = gst_element_factory_make ("audioconvert", "audioconvert1");

  /* use "identity" here for a filter that does nothing */
  filter   = gst_element_factory_make ("my_filter", "my_filter");

  /* there should always be audioconvert and audioresample elements before
   * the audio sink, since the capabilities of the audio sink usually vary
   * depending on the environment (output used, sound card, driver etc.) */
  convert2 = gst_element_factory_make ("audioconvert", "audioconvert2");
  resample = gst_element_factory_make ("audioresample", "audioresample");
  sink     = gst_element_factory_make ("pulsesink", "audiosink");

  if (!sink || !decoder) {
    g_print ("Decoder or output could not be found - check your install\n");
    return -1;
  } else if (!convert1 || !convert2 || !resample) {
    g_print ("Could not create audioconvert or audioresample element, "
             "check your installation\n");
    return -1;
  } else if (!filter) {
    g_print ("Your self-written filter could not be found. Make sure it "
             "is installed correctly in $(libdir)/gstreamer-1.0/ or "
             "~/.gstreamer-1.0/plugins/ and that gst-inspect-1.0 lists it. "
             "If it doesn't, check with 'GST_DEBUG=*:2 gst-inspect-1.0' for "
             "the reason why it is not being loaded.");
    return -1;
  }

  g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);

  gst_bin_add_many (GST_BIN (pipeline), filesrc, decoder, convert1, filter,
                    convert2, resample, sink, NULL);

  /* link everything together */
  if (!gst_element_link_many (filesrc, decoder, convert1, filter, convert2,
                              resample, sink, NULL)) {
    g_print ("Failed to link one or more elements!\n");
    return -1;
  }

  /* run */
  ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
  if (ret == GST_STATE_CHANGE_FAILURE) {
    GstMessage *msg;

    g_print ("Failed to start up pipeline!\n");

    /* check if there is an error message with details on the bus */
    msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
    if (msg) {
      GError *err = NULL;

      gst_message_parse_error (msg, &err, NULL);
      g_print ("ERROR: %s\n", err->message);
      g_error_free (err);
      gst_message_unref (msg);
    }
    return -1;
  }

  g_main_loop_run (loop);

  /* clean up */
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
  g_source_remove (watch_id);
  g_main_loop_unref (loop);

  return 0;
}

 

 

원문: Building a Test Application (gstreamer.freedesktop.org)

 

Building a Test Application

Building a Test Application Often, you will want to test your newly written plugin in as small a setting as possible. Usually, gst-launch-1.0 is a good first step at testing a plugin. If you have not installed your plugin in a directory that GStreamer sear

gstreamer.freedesktop.org

반응형

'IT와 개발 > GStreamer Study' 카테고리의 다른 글

Request and Sometimes pads  (6) 2024.10.18
Signals  (1) 2024.10.11
Adding Properties  (1) 2024.10.04
What are states?  (4) 2024.09.27
The query function  (3) 2024.09.20