tinycompresssink: Add SampleApp for tinycompress test 89/201389/3
authorHyunil <hyunil46.park@samsung.com>
Wed, 13 Mar 2019 10:50:14 +0000 (19:50 +0900)
committerHyunil <hyunil46.park@samsung.com>
Thu, 14 Mar 2019 05:13:57 +0000 (14:13 +0900)
Change-Id: Id365ec89f002a24547299ae6e467d23dbc46acfe
Signed-off-by: Hyunil <hyunil46.park@samsung.com>
configure.ac
packaging/gst-plugins-tizen.spec
tinycompresssink/Makefile.am
tinycompresssink/test/Makefile.am [new file with mode: 0644]
tinycompresssink/test/tinycompress_test.c [new file with mode: 0644]

index 5f12472..8365cec 100644 (file)
@@ -467,6 +467,23 @@ AC_SUBST(TINYCOMPRESS_CFLAGS)
 AC_SUBST(TINYCOMPRESS_LIBS)
 fi
 
+dnl use tinycompress test--------------------------------------------------------------------------
+AC_ARG_ENABLE(tinycompress_test, AC_HELP_STRING([--enable-tinycompress_test], [using tinycompress_test]),
+[
+ case "${enableval}" in
+         yes) USE_TINYCOMPRESS_TEST=yes ;;
+         no)  USE_TINYCOMPRESS_TEST=no ;;
+         *)   AC_MSG_ERROR(bad value ${enableval} for --enable-tinycompress_test) ;;
+ esac
+ ],
+ [USE_TINYCOMPRESS_TEST=no])
+AM_CONDITIONAL(USE_TINYCOMPRESS_TEST, test "x$USE_TINYCOMPRESS_TEST" = "xyes")
+if test "x$USE_TINYCOMPRESS_TEST" = "xyes"; then
+PKG_CHECK_MODULES(SOUNDMANAGER, capi-media-sound-manager)
+AC_SUBST(SOUNDMANAGER_CFLAGS)
+AC_SUBST(SOUNDMANAGER_LIBS)
+fi
+
 AC_ARG_ENABLE(tests, AC_HELP_STRING([--enable-tests], [unittest build]),
      [
         case "${enableval}" in
@@ -521,4 +538,5 @@ tizencamerasrc/Makefile
 tizencamerasrc/src/Makefile
 tinycompresssink/Makefile
 tinycompresssink/src/Makefile
+tinycompresssink/test/Makefile
 )
index f22f177..a32892a 100644 (file)
@@ -48,6 +48,10 @@ BuildRequires:  pkgconfig(tizen-extension-client)
 %if 0%{?gtests:1}
 BuildRequires:  pkgconfig(gmock)
 %endif
+# for tinycompress test
+%if 0%{?tinycompresstest:1}
+BuildRequires:  pkgconfig(capi-media-sound-manager)
+%endif
 # for tizencamerasrc
 #BuildRequires:  pkgconfig(camera-hal-interface)
 
@@ -89,6 +93,9 @@ export CFLAGS="$CFLAGS_DEFAULT -DTIZEN_FEATURE_PRODUCT_TM1"
 %if 0%{?gtests:1}
        --enable-tests \
 %endif
+%if 0%{?tinycompresstest:1}
+       --enable-tinycompress_test\
+%endif
        --disable-drmdecryptor\
        --enable-ext-wfdtizenmanager\
        --enable-ext-alfec\
@@ -115,7 +122,10 @@ export CFLAGS="$CFLAGS_DEFAULT"
 ./autogen.sh --disable-static
 %configure \
 %if 0%{?gtests:1}
-       --enable-tests \
+i      --enable-tests \
+%endif
+%if 0%{?tinycompresstest:1}
+       --enable-tinycompress_test\
 %endif
        --disable-drmdecryptor\
        --enable-ext-wfdtizenmanager\
@@ -127,7 +137,6 @@ export CFLAGS="$CFLAGS_DEFAULT"
        --with-native-formats \
        --with-gles2
 
-
 make %{?jobs:-j%jobs}
 
 %install
@@ -196,4 +205,7 @@ esac
 %if 0%{?gtests:1}
 %{_bindir}/gtest*
 %endif
+%if "%{tinycompresstest}" == "1"
+%{_bindir}/tinycompress_test
+%endif
 
index af437a6..e1e6463 100644 (file)
@@ -1 +1,4 @@
 SUBDIRS = src
+if USE_TINYCOMPRESS_TEST
+SUBDIRS += test
+endif
diff --git a/tinycompresssink/test/Makefile.am b/tinycompresssink/test/Makefile.am
new file mode 100644 (file)
index 0000000..d2b7e36
--- /dev/null
@@ -0,0 +1,7 @@
+bin_PROGRAMS = tinycompress_test\r
+\r
+tinycompress_test_SOURCES = tinycompress_test.c\r
+\r
+tinycompress_test_CFLAGS = $(GST_CFLAGS) $(SOUNDMANAGER_CFLAGS)\r
+\r
+tinycompress_test_LDADD = $(GST_LIBS) $(SOUNDMANAGER_LIBS)\r
diff --git a/tinycompresssink/test/tinycompress_test.c b/tinycompresssink/test/tinycompress_test.c
new file mode 100644 (file)
index 0000000..7aa2d26
--- /dev/null
@@ -0,0 +1,416 @@
+#include <gst/gst.h>
+#include <glib.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <sound_manager.h>
+#include <sound_manager_internal.h>
+
+#define MAX_STRING_LEN 1024
+
+typedef struct _AppData {
+  GstElement *pipeline;
+  GstElement *source;
+  GstElement *queue;
+  GstElement *parser;
+  GstElement *compressed_sink;
+
+  GMainLoop *main_loop;
+  guint progress_timer_id;
+  gint64 duration;
+  gchar *file_path;
+
+  sound_stream_info_h stream_info_h;
+  virtual_sound_stream_h vstream_h;
+} AppData;
+
+
+enum {
+  CURRENT_STATUS_MAINMENU,
+  CURRENT_STATUS_POSITION
+};
+
+int sub_menu = CURRENT_STATUS_MAINMENU;
+static void print_menu (void)
+{
+  g_print ("=========================================\n");
+  g_print ("'s' - Start\n");
+  g_print ("'p' - Pause\n");
+  g_print ("'r' - Resume\n");
+  g_print ("'x' - Stop\n");
+  g_print ("'q' - Quit\n");
+  g_print ("'e' - Seek\n");
+  g_print ("=========================================\n");
+  g_print (">>> ");
+}
+
+#define GST_TIME_SHORT_FORMAT "u:%02u:%02u.%02u"
+
+gboolean _timeout_cb(gpointer user_data)
+{
+  AppData *adata = (AppData *)user_data;
+  gint64 current = -1;
+
+  /* Query the current position of the stream */
+  if (!gst_element_query_position (adata->pipeline, GST_FORMAT_TIME, &current)) {
+    g_printerr ("Could not query current position.\n");
+  }
+
+  /* If we didn't know it yet, query the stream duration */
+  if (!GST_CLOCK_TIME_IS_VALID (adata->duration)) {
+    g_print("query duration\n");
+    if (!gst_element_query_duration (adata->pipeline, GST_FORMAT_TIME, &adata->duration)) {
+      g_printerr ("Could not query current duration.\n");
+    }
+  }
+
+  /* Print current position and total duration */
+  g_print ("[%s] Position %" GST_TIME_SHORT_FORMAT " / %" GST_TIME_SHORT_FORMAT "\r",
+      adata->file_path, GST_TIME_ARGS (current), GST_TIME_ARGS (adata->duration));
+
+  return TRUE;
+}
+
+void _start_progress(AppData *adata)
+{
+  if (adata && adata->progress_timer_id > 0) {
+    g_printerr("already timer %d exists\n", adata->progress_timer_id);
+    return;
+  }
+
+  adata->progress_timer_id = g_timeout_add(100, _timeout_cb, adata);
+}
+
+void _stop_progress(AppData *adata)
+{
+  if (adata && adata->progress_timer_id > 0) {
+    if (!g_source_remove(adata->progress_timer_id))
+        g_printerr("failed to remove source %d\n", adata->progress_timer_id);
+
+    adata->progress_timer_id = 0;
+  }
+}
+
+static gboolean _bus_cb (GstBus *bus, GstMessage *message, gpointer data)
+{
+  AppData *adata = (AppData *) data;
+  //g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
+
+  switch (GST_MESSAGE_TYPE (message)) {
+    case GST_MESSAGE_ERROR: {
+      GError *err;
+      gchar *debug;
+
+      gst_message_parse_error (message, &err, &debug);
+      g_print ("Error: %s\n", err->message);
+      g_error_free (err);
+      g_free (debug);
+
+      g_main_loop_quit (adata->main_loop);
+      break;
+    }
+    case GST_MESSAGE_EOS:
+      /* end-of-stream */
+      g_print("EOS!!!\n");
+//      g_main_loop_quit (loop);
+      break;
+
+  default:
+      /* unhandled message */
+      break;
+  }
+
+  /* we want to be notified again the next time there is a message
+   * on the bus, so returning TRUE (FALSE means we want to stop watching
+   * for messages on the bus and our callback should not be called again)
+   */
+  return TRUE;
+}
+
+static void _focus_cb(sound_stream_info_h stream_info,
+    sound_stream_focus_mask_e focus_mask,
+    sound_stream_focus_state_e focus_state,
+    sound_stream_focus_change_reason_e reason,
+    int sound_behavior,
+    const char *extra_info,
+    void *user_data)
+{
+  int ret = SOUND_MANAGER_ERROR_NONE;
+
+  g_print("\n*** FOCUS callback is called, stream_info(%p) ***\n", stream_info);
+
+  g_print(" - changed focus: mask(%x), state(%d) (0:released, 1:acquired)\n", focus_mask, focus_state);
+  g_print(" - change_reason(%d), behavior(0x%x), extra_info(%s), user_data(%p)\n", reason, sound_behavior, extra_info, user_data);
+
+  g_print("*** FOCUS callback is ended, stream_info(%p) ****\n\n", stream_info);
+
+  return;
+}
+
+static void _prepare_stream(AppData *adata)
+{
+  int ret = 0;
+
+  ret = sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_MEDIA_COMPRESSED, _focus_cb, NULL, &adata->stream_info_h);
+  if (ret) {
+    g_printerr("failed to create stream information internal (MEDIA_COMPRESSED) : 0x%X\n", ret);
+    return;
+  }
+
+  ret = sound_manager_create_virtual_stream(adata->stream_info_h, &adata->vstream_h);
+  if (ret) {
+    g_printerr("failed to create virtual stream : 0x%X\n", ret);
+    return;
+  }
+}
+
+static void _unprepare_stream(AppData *adata)
+{
+  if (adata->vstream_h) {
+    sound_manager_destroy_virtual_stream(adata->vstream_h);
+    adata->vstream_h = NULL;
+  }
+
+  if (adata->stream_info_h) {
+    sound_manager_destroy_stream_information(adata->stream_info_h);
+    adata->stream_info_h = NULL;
+  }
+}
+
+static void _start_stream(AppData *adata)
+{
+  int ret = 0;
+
+  if (!adata->vstream_h) {
+    g_printerr("invalid vstream\n");
+    return;
+  }
+
+  ret = sound_manager_acquire_focus(adata->stream_info_h, SOUND_STREAM_FOCUS_FOR_BOTH,
+                                    SOUND_BEHAVIOR_NONE, "compress test(acquire_focus)");
+  if (ret)
+    g_printerr("fail to sound_manager_acquire_focus(), ret(0x%x)\n", ret);
+
+  ret = sound_manager_start_virtual_stream(adata->vstream_h);
+  if (ret)
+    g_print("fail to sound_manager_start_virtual_stream(), ret(0x%x)\n", ret);
+  else
+    g_print("success to sound_manager_start_virtual_stream(), ret(0x%x)\n", ret);
+
+}
+
+static void _stop_stream(AppData *adata)
+{
+  int ret = 0;
+
+  if (!adata->vstream_h) {
+    g_printerr("invalid vstream\n");
+    return;
+  }
+
+  ret = sound_manager_stop_virtual_stream(adata->vstream_h);
+  if (ret)
+    g_print("fail to sound_manager_stop_virtual_stream(), ret(0x%x)\n", ret);
+  else
+    g_print("success to sound_manager_stop_virtual_stream(), ret(0x%x)\n", ret);
+
+  ret = sound_manager_release_focus(adata->stream_info_h, SOUND_STREAM_FOCUS_FOR_BOTH,
+                                    SOUND_BEHAVIOR_NONE, "compress test(release_focus)");
+  if (ret)
+    g_printerr("fail to sound_manager_release_focus(), ret(0x%x)\n", ret);
+}
+
+
+static void interpret (char *cmd, gpointer data)
+{
+  GstStateChangeReturn ret;
+  AppData *adata = (AppData *) data;
+
+  if (strncmp (cmd, "s", 1) == 0) {
+    _start_stream(adata);
+
+    // Play
+    g_print ("Start pipeline...\n");
+    ret = gst_element_set_state (adata->pipeline, GST_STATE_PLAYING);
+    if (ret == GST_STATE_CHANGE_FAILURE) {
+      g_printerr ("Unable to set pipeline state to the playing state\n");
+    }
+
+    _start_progress(adata);
+  } else if (strncmp (cmd, "p", 1) == 0) {
+    _stop_progress(adata);
+
+    // Pause
+    g_print ("Pause pipeline...\n");
+    ret = gst_element_set_state (adata->pipeline, GST_STATE_PAUSED);
+    if (ret == GST_STATE_CHANGE_FAILURE) {
+      g_printerr ("Unable to set pipeline state to the paused state\n");
+    }
+
+    _stop_stream(adata);
+  } else if (strncmp (cmd, "r", 1) == 0) {
+    _start_stream(adata);
+
+    // Resume
+    g_print ("Resume pipeline...\n");
+    ret = gst_element_set_state (adata->pipeline, GST_STATE_PLAYING);
+    if (ret == GST_STATE_CHANGE_FAILURE) {
+      g_printerr ("Unable to resume pipeline\n");
+    }
+
+    _start_progress(adata);
+  } else if (strncmp (cmd, "x", 1) == 0) {
+    _stop_progress(adata);
+
+    // Stop
+    g_print ("Stop pipeline...\n");
+    ret = gst_element_set_state (adata->pipeline, GST_STATE_NULL);
+    if (ret == GST_STATE_CHANGE_FAILURE) {
+      g_printerr ("Unable to set pipeline state to the null state\n");
+    }
+
+    _stop_stream(adata);
+  } else if (strncmp (cmd, "q", 1) == 0) {
+   GstState state, pending;
+
+     ret = gst_element_get_state (adata->pipeline, &state, &pending, GST_CLOCK_TIME_NONE);
+     if (ret == GST_STATE_CHANGE_FAILURE) {
+       g_printerr ("Unable to get pipeline state\n");
+     }
+
+   if (state != GST_STATE_NULL) {
+      _stop_progress(adata);
+    g_print ("Stop pipeline here......\n");
+    ret = gst_element_set_state (adata->pipeline, GST_STATE_NULL);
+    if (ret == GST_STATE_CHANGE_FAILURE) {
+      g_printerr ("Unable to set pipeline state to the null state\n");
+    }
+    _stop_stream(adata);
+   }
+
+    // Quit
+    g_print ("Quiting\n");
+    g_main_loop_quit (adata->main_loop);
+  } else if (strncmp (cmd, "e", 1) == 0) {
+    // Seek
+    g_print ("Seek\n");
+    sub_menu = CURRENT_STATUS_POSITION;
+    g_print ("Input seek position:\n");
+    return;
+  } else if (sub_menu == CURRENT_STATUS_POSITION) {
+    GstSeekFlags seek_flag = TRUE;
+    gboolean result = FALSE;
+    GstEvent *event = NULL;
+    gint64 g_time = atoi(cmd);
+    g_time = g_time * GST_MSECOND;
+
+    if (seek_flag)
+      seek_flag = GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE;
+    else
+      seek_flag = GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT;
+
+    event = gst_event_new_seek(1.0, GST_FORMAT_TIME, seek_flag,
+        GST_SEEK_TYPE_SET, g_time,
+        GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
+    if (event)
+      result = gst_element_send_event(adata->pipeline, event);
+    if (result)
+      g_print ("send seek event\n");
+
+    sub_menu = CURRENT_STATUS_MAINMENU;
+  } else {
+    g_printerr ("Unknown command!\n");
+  }
+
+  print_menu();
+}
+
+static gboolean input (GIOChannel * channel, GIOCondition condition,
+  gpointer data)
+{
+  gchar buf[MAX_STRING_LEN];
+  gsize read;
+  GError *error = NULL;
+
+  g_io_channel_read_chars (channel, buf, MAX_STRING_LEN, &read, &error);
+  buf[read] = '\0';
+  g_strstrip (buf);
+  g_print ("Typed %s\n", buf);
+  interpret (buf, data);
+
+  return TRUE;
+}
+
+int main (int argc, char *argv[])
+{
+  AppData adata;
+  GIOChannel *stdin_channel;
+  GstBus *bus;
+  guint bus_watch_id;
+
+  memset (&adata, 0, sizeof (adata));
+  adata.duration = GST_CLOCK_TIME_NONE;
+
+  _prepare_stream(&adata);
+
+  // Create and form pipeline
+  gst_init (&argc, &argv);
+
+  adata.pipeline = gst_pipeline_new ("test-pipeline");
+
+  bus = gst_pipeline_get_bus (GST_PIPELINE (adata.pipeline));
+  bus_watch_id = gst_bus_add_watch (bus, _bus_cb, &adata);
+  gst_object_unref (bus);
+
+  adata.source = gst_element_factory_make ("filesrc", "source");
+  adata.queue = gst_element_factory_make ("queue", "queue");
+
+#ifdef IS_AAC
+  adata.parser = gst_element_factory_make ("aacparse", "parser");
+#else /* IS_MP3 */
+  adata.parser = gst_element_factory_make ("mpegaudioparse", "parser");
+#endif
+
+  adata.compressed_sink = gst_element_factory_make ("tinycompresssink", "compressed_sink");
+  if (!adata.compressed_sink) {
+    g_printerr ("Compressed elements were not created\n");
+    return -1;
+  }
+
+  adata.file_path = argv[1];
+  g_object_set (G_OBJECT (adata.source), "location", argv[1], NULL);
+  g_object_set (G_OBJECT (adata.compressed_sink), "sync", TRUE, NULL);
+
+  if (!adata.pipeline || !adata.source || !adata.queue || !adata.parser) {
+    g_printerr ("Not all elements were created\n");
+    return -1;
+  }
+
+  gst_bin_add_many (GST_BIN (adata.pipeline), adata.source, adata.queue,
+    adata.parser, adata.compressed_sink, NULL);
+  if (gst_element_link_many (adata.source, adata.queue, adata.parser,
+        adata.compressed_sink, NULL) != TRUE) {
+    g_printerr ("Elements could not be linked\n");
+    return -1;
+  }
+
+  print_menu ();
+
+  adata.main_loop = g_main_loop_new (NULL, FALSE);
+  stdin_channel = g_io_channel_unix_new (0);
+
+  g_io_channel_set_flags (stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
+  g_io_add_watch (stdin_channel, G_IO_IN, (GIOFunc) input, &adata);
+
+  g_main_loop_run (adata.main_loop);
+
+  gst_element_set_state(adata.pipeline, GST_STATE_NULL);
+  g_source_remove (bus_watch_id);
+
+  g_main_loop_unref(adata.main_loop);
+
+  _unprepare_stream(&adata);
+
+  return 0;
+}