--- /dev/null
+/*
+* Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <appcore-efl.h>
+#include <Elementary.h>
+#include <glib.h>
+#include <dlog.h>
+#include <mediademuxer.h>
+
+#include "esplusplayer_capi/esplusplayer_capi.h"
+#include "esplusplayer_capi/esplusplayer_internal.h"
+#ifdef PACKAGE
+#undef PACKAGE
+#endif
+#define PACKAGE "espp_test"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "MM_PP_TEST"
+
+#define MAX_STRING_LEN 2048
+#define MAX_TRACK_COUNT 10
+
+// #define DEBUG_LOG
+
+enum {
+ CURRENT_STATUS_MAINMENU,
+ CURRENT_STATUS_FILENAME,
+ CURRENT_STATUS_ACTIVATE,
+ CURRENT_STATUS_DEACTIVATE,
+ CURRENT_STATUS_SEEK,
+ CURRENT_STATUS_SET_RATE,
+ CURRENT_STATUS_SET_VOLUME,
+ CURRENT_STATUS_SET_MUTE,
+ CURRENT_STATUS_SET_DISPLAY,
+ CURRENT_STATUS_SET_DISPLAY_MODE,
+ CURRENT_STATUS_SET_DISPLAY_ROI,
+ CURRENT_STATUS_SET_DISPLAY_VISIBLE,
+ CURRENT_STATUS_SET_DISPLAY_ROTATION,
+ CURRENT_STATUS_SET_VIDEO_ROI,
+ CURRENT_STATUS_SELECT_TRACK,
+};
+
+/* for video display */
+static Evas_Object *g_eo;
+static Evas_Object *g_win_id;
+static Evas_Object *g_selected_win_id;
+
+enum {
+ AUDIO_STREAM,
+ VIDEO_STREAM,
+ STREAM_MAX
+};
+
+typedef struct {
+ Evas_Object *win;
+ Evas_Object *layout_main;
+} appdata;
+
+typedef struct {
+ int track_index;
+ bool activate;
+ bool eos_track;
+ media_format_h format;
+ media_packet_h pending_packet;
+ GMutex mutex;
+ GCond cond;
+ bool wait_thread;
+ pthread_t thread;
+} stream_t;
+
+typedef struct {
+ mediademuxer_h demux_h;
+ esplusplayer_handle espp_h;
+ int num_tracks;
+ stream_t streams[STREAM_MAX];
+ media_format_h track_format[MAX_TRACK_COUNT];
+ bool stop_thread;
+} test_h;
+
+static appdata g_ad;
+static test_h *g_test_h;
+
+#define STREAM_LOCK(type) { \
+ g_mutex_lock(&g_test_h->streams[type].mutex); \
+}
+
+#define STREAM_UNLOCK(type) { \
+ g_mutex_unlock(&g_test_h->streams[type].mutex); \
+}
+
+#define STREAM_WAIT(type) { \
+ g_cond_wait (&g_test_h->streams[type].cond, &g_test_h->streams[type].mutex); \
+}
+
+#define STREAM_SIGNAL(type) { \
+ if (g_test_h->streams[type].wait_thread) { \
+ g_cond_signal (&g_test_h->streams[type].cond); \
+ } \
+}
+
+static char g_uri[MAX_STRING_LEN];
+static int g_menu_state = CURRENT_STATUS_MAINMENU;
+
+static void __deinit_test();
+
+static void __win_del(void *data, Evas_Object *obj, void *event)
+{
+ elm_exit();
+}
+
+static Evas_Object *__create_win(const char *name)
+{
+ Evas_Object *eo = NULL;
+ int w = 0;
+ int h = 0;
+
+ g_print("[%s][%d] name=%s\n", __func__, __LINE__, name);
+
+ eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
+ if (eo) {
+ elm_win_title_set(eo, name);
+ elm_win_borderless_set(eo, EINA_TRUE);
+ evas_object_smart_callback_add(eo, "delete,request", __win_del, NULL);
+ elm_win_screen_size_get(eo, NULL, NULL, &w, &h);
+ g_print("window size :%d,%d\n", w, h);
+ evas_object_resize(eo, w, h);
+ elm_win_autodel_set(eo, EINA_TRUE);
+ elm_win_alpha_set(eo, EINA_TRUE);
+ }
+ return eo;
+}
+
+static Evas_Object *__create_image_object(Evas_Object *eo_parent)
+{
+ if (!eo_parent)
+ return NULL;
+
+ Evas *evas = evas_object_evas_get(eo_parent);
+ Evas_Object *eo = NULL;
+
+ eo = evas_object_image_add(evas);
+
+ return eo;
+}
+
+void create_render_rect_and_bg(Evas_Object *win)
+{
+ if (!win) {
+ g_print("no win\n");
+ return;
+ }
+ Evas_Object *bg, *rect;
+
+ bg = elm_bg_add(win);
+ elm_win_resize_object_add(win, bg);
+ evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show(bg);
+
+ rect = evas_object_rectangle_add(evas_object_evas_get(win));
+ if (!rect) {
+ g_print("no rect\n");
+ return;
+ }
+ evas_object_color_set(rect, 0, 0, 0, 0);
+ evas_object_render_op_set(rect, EVAS_RENDER_COPY);
+
+ elm_win_resize_object_add(win, rect);
+ evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show(rect);
+ evas_object_show(win);
+}
+
+static int __app_create(void *data)
+{
+ appdata *ad = data;
+ Evas_Object *win = NULL;
+
+ /* use gl backend */
+ elm_config_accel_preference_set("opengl");
+
+ /* create window */
+ win = __create_win(PACKAGE);
+ if (win == NULL)
+ return -1;
+ ad->win = win;
+ g_win_id = win;
+ g_selected_win_id = g_win_id;
+ create_render_rect_and_bg(ad->win);
+ /* Create evas image object for EVAS surface */
+ g_eo = __create_image_object(ad->win);
+ evas_object_image_size_set(g_eo, 500, 500);
+ evas_object_image_fill_set(g_eo, 0, 0, 500, 500);
+ evas_object_resize(g_eo, 500, 500);
+
+ elm_win_activate(win);
+ evas_object_show(win);
+
+ return 0;
+}
+
+static int __app_terminate(void *data)
+{
+ appdata *ad = data;
+
+ if (g_eo) {
+ evas_object_del(g_eo);
+ g_eo = NULL;
+ }
+
+ if (g_win_id) {
+ evas_object_del(g_win_id);
+ g_win_id = NULL;
+ }
+
+ ad->win = NULL;
+ g_selected_win_id = NULL;
+
+ return 0;
+}
+
+static struct appcore_ops ops = {
+ .create = __app_create,
+ .terminate = __app_terminate,
+};
+
+void quit_program()
+{
+ __deinit_test();
+ g_print(" => EXIT\n");
+ elm_exit();
+}
+
+static void __mediademuxer_err_cb(mediademuxer_error_e error, void *user_data)
+{
+ g_print("Got Error %d from Mediademuxer\n", error);
+}
+
+static void __mediademuxer_eos_cb(int track_index, void *user_data)
+{
+ test_h *test_t = (test_h *)user_data;
+
+ g_print("Got EOS for track -- %d from Mediademuxer\n", track_index);
+ if (track_index == test_t->streams[VIDEO_STREAM].track_index)
+ test_t->streams[VIDEO_STREAM].eos_track = true;
+ else if (track_index == test_t->streams[AUDIO_STREAM].track_index)
+ test_t->streams[AUDIO_STREAM].eos_track = true;
+ else
+ g_print("EOS for invalid track number\n");
+}
+
+static void __espp_prepare_async_done_cb(bool ret, void* user_data)
+{
+ test_h *test_t = (test_h *)user_data;
+
+ g_print("__espp_prepare_async_done_cb() is called, result[%u] test_h[%p]\n", ret, test_t);
+}
+
+static void __espp_ready_to_prepare_cb(esplusplayer_stream_type type, void *user_data)
+{
+ test_h *test_t = (test_h *)user_data;
+
+ g_print("__espp_ready_to_prepare_cb() is called, type[%u] espp[%p]\n", type, test_t->espp_h);
+
+}
+
+static void __espp_error_cb(esplusplayer_error_type type, void *user_data)
+{
+ g_print("__espp_error_cb() is called, error type[0x%X]\n", type);
+}
+
+static void __espp_eos_cb(void *user_data)
+{
+ g_print("__espp_eos_cb() is called\n");
+}
+
+static void __espp_buffer_status_cb(esplusplayer_stream_type type, esplusplayer_buffer_status status, void *user_data)
+{
+#ifdef DEBUG_LOG
+ g_print("__espp_buffer_status_cb(type:%s, status:%s)\n",
+ type == ESPLUSPLAYER_STREAM_TYPE_AUDIO ? "Audio" : "Video",
+ status == ESPLUSPLAYER_BUFFER_STATUS_UNDERRUN ? "UNDERRUN": "OVERRUN");
+#endif
+ if (status == ESPLUSPLAYER_BUFFER_STATUS_OVERRUN) {
+ g_test_h->streams[type].wait_thread = true;
+ } else {
+ STREAM_SIGNAL(type);
+ }
+}
+
+static void __espp_ready_to_seek_cb(esplusplayer_stream_type type, uint64_t time, void *user_data)
+{
+ g_print("__espp_ready_to_seek_cb(type:%s, time:%llu)\n",
+ type == ESPLUSPLAYER_STREAM_TYPE_AUDIO ? "Audio" : "Video", time);
+ STREAM_SIGNAL(type);
+}
+
+static int __convert_media_format_mime_to_espp_mime(media_format_mimetype_e type)
+{
+ g_print("media_format_mimetype(0x%x)\n", type);
+
+ switch (type) {
+ case MEDIA_FORMAT_AAC:
+ return (int)ESPLUSPLAYER_AUDIO_MIME_TYPE_AAC;
+ case MEDIA_FORMAT_OPUS:
+ return (int)ESPLUSPLAYER_AUDIO_MIME_TYPE_OPUS;
+ case MEDIA_FORMAT_VP8:
+ return (int)ESPLUSPLAYER_VIDEO_MIME_TYPE_VP8;
+ case MEDIA_FORMAT_VP9:
+ return (int)ESPLUSPLAYER_VIDEO_MIME_TYPE_VP9;
+ case MEDIA_FORMAT_H264_SP:
+ case MEDIA_FORMAT_H264_MP:
+ case MEDIA_FORMAT_H264_HP:
+ return (int)ESPLUSPLAYER_VIDEO_MIME_TYPE_H264;
+ case MEDIA_FORMAT_MJPEG:
+ return (int)ESPLUSPLAYER_VIDEO_MIME_TYPE_MJPEG;
+ case MEDIA_FORMAT_MPEG4_SP:
+ case MEDIA_FORMAT_MPEG4_ASP:
+ return (int)ESPLUSPLAYER_VIDEO_MIME_TYPE_MPEG4;
+ default:
+ return -1;
+ }
+}
+
+static void __init_demux()
+{
+ int ret = 0;
+
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ ret = mediademuxer_create(&g_test_h->demux_h);
+ if (ret != MEDIADEMUXER_ERROR_NONE)
+ g_print(" => failed to mediademuxer_create()\n");
+ else
+ g_print(" => mediademuxer_create() success\n");
+
+ ret = mediademuxer_set_error_cb(g_test_h->demux_h, __mediademuxer_err_cb, g_test_h);
+ if (ret != MEDIADEMUXER_ERROR_NONE)
+ g_print(" => failed to mediademuxer_set_error_cb()\n");
+ else
+ g_print(" => mediademuxer_set_error_cb() success\n");
+
+ ret = mediademuxer_set_eos_cb(g_test_h->demux_h, __mediademuxer_eos_cb, g_test_h);
+ if (ret != MEDIADEMUXER_ERROR_NONE)
+ g_print(" => failed to mediademuxer_set_eos_cb()\n");
+ else
+ g_print(" => mediademuxer_set_eos_cb() success\n");
+}
+
+static void __init_espp()
+{
+ int ret = 0;
+
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ g_test_h->espp_h = esplusplayer_create();
+ if (!g_test_h->espp_h)
+ g_print(" => failed to esplusplayer_create()\n");
+ else
+ g_print(" => esplusplayer_create() success\n");
+
+ ret = esplusplayer_set_prepare_async_done_cb(g_test_h->espp_h, __espp_prepare_async_done_cb, g_test_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_prepare_async_done_cb()\n");
+ else
+ g_print(" => esplusplayer_set_prepare_async_done_cb() success\n");
+ ret = esplusplayer_set_ready_to_prepare_cb(g_test_h->espp_h, __espp_ready_to_prepare_cb, g_test_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_ready_to_prepare_cb()\n");
+ else
+ g_print(" => esplusplayer_set_ready_to_prepare_cb() success\n");
+
+ ret = esplusplayer_set_error_cb(g_test_h->espp_h, __espp_error_cb, g_test_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_error_cb()\n");
+ else
+ g_print(" => esplusplayer_set_error_cb() success\n");
+
+ ret = esplusplayer_set_eos_cb(g_test_h->espp_h, __espp_eos_cb, g_test_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_eos_cb()\n");
+ else
+ g_print(" => esplusplayer_set_eos_cb() success\n");
+
+ ret = esplusplayer_set_buffer_status_cb(g_test_h->espp_h, __espp_buffer_status_cb, g_test_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_buffer_status_cb()\n");
+ else
+ g_print(" => esplusplayer_set_buffer_status_cb() success\n");
+
+ ret = esplusplayer_set_ready_to_seek_cb(g_test_h->espp_h, __espp_ready_to_seek_cb, g_test_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_ready_to_seek_cb()\n");
+ else
+ g_print(" => esplusplayer_set_ready_to_seek_cb() success\n");
+
+ ret = esplusplayer_open(g_test_h->espp_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_open()\n");
+ else
+ g_print(" => esplusplayer_open() success\n");
+
+ ret = esplusplayer_set_submit_data_type(g_test_h->espp_h, ESPLUSPLAYER_SUBMIT_DATA_TYPE_CLEAN_DATA);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_submit_data_type()\n");
+ else
+ g_print(" => esplusplayer_set_submit_data_type() success\n");
+}
+
+static void __init_test()
+{
+ g_test_h = g_new0(test_h, 1);
+ for (int i = 0; i < STREAM_MAX; i++) {
+ g_mutex_init(&g_test_h->streams[i].mutex);
+ g_cond_init(&g_test_h->streams[i].cond);
+ g_test_h->streams[i].track_index = -1;
+ }
+ __init_espp();
+ __init_demux();
+}
+
+static void __deinit_test()
+{
+ int i = 0;
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ // need to stop feeding thread;
+ mediademuxer_stop(g_test_h->demux_h);
+ mediademuxer_unprepare(g_test_h->demux_h);
+ mediademuxer_destroy(g_test_h->demux_h);
+
+ esplusplayer_close(g_test_h->espp_h);
+ esplusplayer_destroy(g_test_h->espp_h);
+
+ for (i = 0; i < MAX_TRACK_COUNT; i++) {
+ if (g_test_h->track_format[i]) {
+ media_format_unref(g_test_h->track_format[i]);
+ g_test_h->track_format[i] = NULL;
+ }
+ }
+
+ g_test_h->stop_thread = true;
+
+ for (i = 0; i < STREAM_MAX; i++) {
+ if (!g_test_h->streams[i].thread)
+ continue;
+ g_test_h->streams[i].wait_thread = false;
+ g_test_h->streams[i].eos_track = false;
+ STREAM_SIGNAL(i);
+ pthread_join(g_test_h->streams[i].thread, NULL);
+ g_mutex_clear(&g_test_h->streams[i].mutex);
+ g_cond_clear(&g_test_h->streams[i].cond);
+ }
+
+ g_free(g_test_h);
+ g_test_h = NULL;
+}
+
+static void __test_demuxer_get_track_info()
+{
+ int num_tracks = 0;
+ int ret = 0;
+ int track = 0;
+ media_format_mimetype_e mime;
+ media_format_text_type_e t_type;
+ int w;
+ int h;
+ int channel = 0;
+ int samplerate = 0;
+ int bit = 0;
+ bool is_adts = 0;
+
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ mediademuxer_h demuxer = g_test_h->demux_h;
+
+ mediademuxer_get_track_count(demuxer, &num_tracks);
+ g_print("Number of total tracks [%d]\n", num_tracks);
+ if (num_tracks > MAX_TRACK_COUNT) {
+ g_print("total tracks %d > %d\n", num_tracks, MAX_TRACK_COUNT);
+ return;
+ }
+ g_test_h->num_tracks = num_tracks;
+ g_print("test_mediademuxer_get_track_info\n");
+
+ for (; track < num_tracks; track++) {
+ media_format_h get_format;
+ ret = mediademuxer_get_track_info(demuxer, track, &get_format);
+ if (ret == 0) {
+ if (media_format_get_video_info(get_format, &mime,
+ &w, &h, NULL, NULL) == MEDIA_FORMAT_ERROR_NONE) {
+ g_print("\t\t[video_id(%d)]mime:%x, width :%d, height :%d\n",
+ track, mime, w, h);
+ g_test_h->track_format[track] = get_format;
+ media_format_ref(get_format);
+ g_test_h->streams[VIDEO_STREAM].format = get_format;
+ } else if (media_format_get_audio_info(get_format, &mime,
+ &channel, &samplerate, &bit, NULL) == MEDIA_FORMAT_ERROR_NONE) {
+ g_print("\t\t[audio_id(%d)]mime:%x, channel :%d, samplerate :%d, bit :%d\n",
+ track, mime, channel, samplerate, bit);
+ if (mime == MEDIA_FORMAT_AAC_LC) {
+ media_format_get_audio_aac_type(get_format, &is_adts);
+ g_print("\t\t[media_format_get_audio]is_adts:%d\n", is_adts);
+ }
+ media_format_ref(get_format);
+ g_test_h->track_format[track] = get_format;
+ } else if (media_format_get_text_info(get_format, &mime, &t_type) == MEDIA_FORMAT_ERROR_NONE) {
+ g_print("media_format_get_text_info is success!\n");
+ g_print("\t\t[media_format_get_text]mime:%x, type:%x\n", mime, t_type);
+ } else {
+ g_print("Not Supported YET\n");
+ }
+ media_format_unref(get_format);
+ get_format = NULL;
+ } else {
+ g_print("Error while getting mediademuxer_get_track_info\n");
+ }
+ if (track > MAX_TRACK_COUNT - 1)
+ break;
+ }
+}
+
+static void __test_demuxer_prepare()
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = mediademuxer_prepare(g_test_h->demux_h);
+ if (ret != MEDIADEMUXER_ERROR_NONE)
+ g_print(" => failed to mediademuxer_prepare()\n");
+ else
+ g_print(" => mediademuxer_prepare() success\n");
+}
+
+static void __test_set_audio_stream_info()
+{
+ int ret = TIZEN_ERROR_NONE;
+ media_format_mimetype_e mimetype;
+ int type;
+ int channels = 0;
+ int rate = 0;
+ int bit = 0;
+ media_packet_h audbuf;
+ esplusplayer_audio_stream_info audio_info = {0, };
+
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ if (g_test_h->num_tracks == 0) {
+ g_print("run demuxer prepare\n");
+ return;
+ }
+
+ if (!g_test_h->streams[AUDIO_STREAM].format) {
+ g_print("not contain audio stream\n");
+ return;
+ }
+
+ ret = media_format_get_audio_info(g_test_h->streams[AUDIO_STREAM].format, &mimetype, &channels, &rate, &bit, NULL);
+ if (ret != MEDIA_FORMAT_ERROR_NONE) {
+ g_print("failed to media_format_get_audio_info\n");
+ return;
+ }
+
+ type = __convert_media_format_mime_to_espp_mime(mimetype);
+ if (type == -1) {
+ g_print("unsupported mime type\n");
+ return;
+ }
+
+ ret = mediademuxer_read_sample(g_test_h->demux_h,
+ g_test_h->streams[AUDIO_STREAM].track_index, &audbuf);
+ if (ret != MEDIADEMUXER_ERROR_NONE) {
+ g_print("Error (%d) return of (Audio) mediademuxer_read_sample()\n", ret);
+ } else {
+ void *codec_data = NULL;
+ unsigned int codec_data_length = 0;
+ g_test_h->streams[AUDIO_STREAM].pending_packet = audbuf;
+ if (media_packet_get_codec_data (audbuf, &codec_data, &codec_data_length) == MEDIA_PACKET_ERROR_NONE) {
+ g_print("Audio has codec data\n");
+ audio_info.codec_data = codec_data;
+ audio_info.codec_data_length = codec_data_length;
+ }
+ }
+
+ audio_info.bitrate = bit;
+ audio_info.channels = channels;
+ audio_info.sample_rate = rate;
+ audio_info.mime_type = type;
+
+ ret = esplusplayer_set_audio_stream_info(g_test_h->espp_h, &audio_info);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_audio_stream_info()\n");
+ else
+ g_print(" => esplusplayer_set_audio_stream_info() success\n");
+
+ g_test_h->streams[AUDIO_STREAM].activate = true;
+}
+
+static void __test_set_video_stream_info()
+{
+ int ret = MEDIA_PACKET_ERROR_NONE;
+ media_format_mimetype_e mimetype;
+ int type;
+ int width = 0;
+ int height = 0;
+ int framerate = 0;
+ media_packet_h vidbuf;
+
+ esplusplayer_video_stream_info video_info = {0, };
+
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ if (g_test_h->num_tracks == 0) {
+ g_print("run demuxer prepare\n");
+ return;
+ }
+
+ if (!g_test_h->streams[VIDEO_STREAM].format) {
+ g_print("not contain video stream\n");
+ return;
+ }
+
+ ret = media_format_get_video_info(g_test_h->streams[VIDEO_STREAM].format, &mimetype, &width, &height, NULL, NULL);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ g_print("failed to media_format_get_video_info\n");
+ return;
+ }
+
+ ret = media_format_get_video_frame_rate(g_test_h->streams[VIDEO_STREAM].format, &framerate);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ g_print("failed to media_format_get_video_info\n");
+ return;
+ }
+
+ type = __convert_media_format_mime_to_espp_mime(mimetype);
+ if (type == -1) {
+ g_print("unsupported mime type\n");
+ return;
+ }
+
+ ret = mediademuxer_read_sample(g_test_h->demux_h,
+ g_test_h->streams[VIDEO_STREAM].track_index, &vidbuf);
+ if (ret != MEDIADEMUXER_ERROR_NONE) {
+ g_print("Error (%d) return of (Video) mediademuxer_read_sample()\n", ret);
+ } else {
+ void *codec_data = NULL;
+ unsigned int codec_data_length = 0;
+ g_test_h->streams[VIDEO_STREAM].pending_packet = vidbuf;
+ if (media_packet_get_codec_data (vidbuf, &codec_data, &codec_data_length) == MEDIA_PACKET_ERROR_NONE) {
+ g_print("Video has codec data\n");
+ video_info.codec_data = codec_data;
+ video_info.codec_data_length = codec_data_length;
+ }
+ }
+ video_info.width = width;
+ video_info.height = height;
+ video_info.framerate_num = framerate;
+ video_info.framerate_den = 1;
+ video_info.mime_type = type;
+
+ ret = esplusplayer_set_video_stream_info(g_test_h->espp_h, &video_info);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_video_stream_info()\n");
+ else
+ g_print(" => esplusplayer_set_video_stream_info() success\n");
+
+ g_test_h->streams[VIDEO_STREAM].activate = true;
+}
+
+static void __test_activate(int type)
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_activate(g_test_h->espp_h, (esplusplayer_stream_type)type);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_activate(%d)\n", type);
+ else
+ g_print(" => esplusplayer_activate(%d) success\n", type);
+}
+
+static void __test_deactivate(int type)
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_deactivate(g_test_h->espp_h, (esplusplayer_stream_type)type);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_deactivate(%d)\n", type);
+ else
+ g_print(" => esplusplayer_deactivate(%d) success\n", type);
+}
+
+static void __test_destroy()
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_destroy(g_test_h->espp_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_destroy()\n");
+ else
+ g_print(" => esplusplayer_destroy() success\n");
+}
+
+static void __test_open()
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_open(g_test_h->espp_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_open()\n");
+ else
+ g_print(" => esplusplayer_open() success\n");
+}
+
+static void __test_close()
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_close(g_test_h->espp_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_close()\n");
+ else
+ g_print(" => esplusplayer_close() success\n");
+}
+
+static void __test_prepare_async()
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_prepare_async(g_test_h->espp_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_prepare_async()\n");
+ else
+ g_print(" => esplusplayer_prepare_async() success\n");
+}
+
+static void __convert_espp_packet(media_packet_h packet, esplusplayer_es_packet* espp_packet)
+{
+ bool is_audio;
+ uint64_t gst_pts;
+ uint64_t gst_duration;
+
+ if (!packet) {
+ g_print("media packet is NULL\n");
+ return;
+ }
+
+ media_packet_is_audio (packet, &is_audio);
+ espp_packet->type = is_audio ? ESPLUSPLAYER_STREAM_TYPE_AUDIO : ESPLUSPLAYER_STREAM_TYPE_VIDEO;
+
+ media_packet_get_buffer_data_ptr(packet, (void **)&espp_packet->buffer);
+ media_packet_get_buffer_size(packet, (uint64_t *)&espp_packet->buffer_size);
+ media_packet_get_pts(packet, &gst_pts);
+ media_packet_get_duration(packet, &gst_duration);
+ if (gst_pts != (uint64_t) -1)
+ espp_packet->pts = gst_pts / G_GINT64_CONSTANT (1000000);
+ if (gst_duration != (uint64_t) -1)
+ espp_packet->duration = gst_duration / G_GINT64_CONSTANT (1000000);
+
+ espp_packet->matroska_color_info = NULL;
+ espp_packet->hdr10p_metadata = NULL;
+}
+
+void *_fetch_audio_data(void *ptr)
+{
+ int ret = MEDIADEMUXER_ERROR_NONE;
+ int *status = (int *)g_malloc(sizeof(int));
+ esplusplayer_submit_status submit_status;
+ test_h *test_t = (test_h *)ptr;
+
+ *status = -1;
+
+ if (test_t->streams[AUDIO_STREAM].pending_packet) {
+ media_packet_h pending = test_t->streams[AUDIO_STREAM].pending_packet;
+ esplusplayer_es_packet pending_espp_packet;
+ __convert_espp_packet(pending, &pending_espp_packet);
+ submit_status = esplusplayer_submit_packet(test_t->espp_h, &pending_espp_packet);
+#ifdef DEBUG_LOG
+ g_print("Audio pending packet[media:%p, es:%p][%llu ms] espp submit packet status[%d]\n",
+ pending, &pending_espp_packet, pending_espp_packet.pts ,submit_status);
+#endif
+ media_packet_destroy(pending);
+ test_t->streams[AUDIO_STREAM].pending_packet = NULL;
+ }
+
+ while (!test_t->stop_thread) {
+ esplusplayer_es_packet espp_packet;
+ media_packet_h audbuf;
+
+ if (test_t->streams[AUDIO_STREAM].wait_thread) {
+ STREAM_LOCK(AUDIO_STREAM);
+ STREAM_WAIT(AUDIO_STREAM);
+ test_t->streams[AUDIO_STREAM].wait_thread = false;
+ STREAM_UNLOCK(AUDIO_STREAM);
+ }
+
+ if (test_t->stop_thread)
+ pthread_exit(NULL);
+
+ ret = mediademuxer_read_sample(test_t->demux_h,
+ test_t->streams[AUDIO_STREAM].track_index, &audbuf);
+ if (ret != MEDIADEMUXER_ERROR_NONE) {
+ g_print("Error (%x) return of (Audio) mediademuxer_read_sample()\n", ret);
+ pthread_exit(NULL);
+ }
+ if (test_t->streams[AUDIO_STREAM].eos_track) {
+ submit_status = esplusplayer_submit_eos_packet(test_t->espp_h, ESPLUSPLAYER_STREAM_TYPE_AUDIO);
+ g_print("espp submit audio EOS packet status[%d]\n", submit_status);
+ STREAM_LOCK(AUDIO_STREAM);
+ test_t->streams[AUDIO_STREAM].wait_thread = true;
+ g_print("Audio EOS wait thread\n");
+ STREAM_WAIT(AUDIO_STREAM);
+ test_t->streams[AUDIO_STREAM].wait_thread = false;
+ STREAM_UNLOCK(AUDIO_STREAM);
+ continue;
+ }
+
+ if (test_t->stop_thread)
+ pthread_exit(NULL);
+
+ __convert_espp_packet(audbuf, &espp_packet);
+ submit_status = esplusplayer_submit_packet(test_t->espp_h, &espp_packet);
+#ifdef DEBUG_LOG
+ g_print("Audio packet[media:%p, es:%p][%llu ms] espp submit packet status[%d]\n",
+ audbuf, &espp_packet, espp_packet.pts ,submit_status);
+#endif
+ media_packet_destroy(audbuf);
+ }
+
+ g_print("EOS return of mediademuxer_read_sample() for audio\n");
+ *status = 0;
+ return (void *)status;
+}
+
+void *_fetch_video_data(void *ptr)
+{
+ int ret = MEDIADEMUXER_ERROR_NONE;
+ int *status = (int *)g_malloc(sizeof(int));
+ esplusplayer_submit_status submit_status;
+ test_h *test_t = (test_h *)ptr;
+
+ *status = -1;
+ g_print("Video Data function\n");
+
+ if (test_t->streams[VIDEO_STREAM].pending_packet) {
+ media_packet_h pending = test_t->streams[VIDEO_STREAM].pending_packet;
+ esplusplayer_es_packet pending_espp_packet;
+ __convert_espp_packet(pending, &pending_espp_packet);
+ submit_status = esplusplayer_submit_packet(test_t->espp_h, &pending_espp_packet);
+ g_print("Video pending packet[media:%p, es:%p][%llu ms] espp submit packet status[%d]\n",
+ pending, &pending_espp_packet, pending_espp_packet.pts ,submit_status);
+ media_packet_destroy(pending);
+ test_t->streams[VIDEO_STREAM].pending_packet = NULL;
+ }
+
+ while (!test_t->stop_thread) {
+ esplusplayer_es_packet espp_packet;
+ media_packet_h vidbuf;
+
+ if (test_t->streams[VIDEO_STREAM].wait_thread) {
+ STREAM_LOCK(VIDEO_STREAM);
+ STREAM_WAIT(VIDEO_STREAM);
+ test_t->streams[VIDEO_STREAM].wait_thread = false;
+ STREAM_UNLOCK(VIDEO_STREAM);
+ }
+
+ if (test_t->stop_thread)
+ pthread_exit(NULL);
+
+ ret = mediademuxer_read_sample(test_t->demux_h,
+ test_t->streams[VIDEO_STREAM].track_index, &vidbuf);
+ if (ret != MEDIADEMUXER_ERROR_NONE) {
+ g_print("Error (%d) return of (Video) mediademuxer_read_sample()\n", ret);
+ pthread_exit(NULL);
+ }
+ if (test_t->streams[VIDEO_STREAM].eos_track) {
+ submit_status = esplusplayer_submit_eos_packet(test_t->espp_h, ESPLUSPLAYER_STREAM_TYPE_VIDEO);
+ g_print("espp submit video EOS packet status[%d]\n", submit_status);
+ STREAM_LOCK(VIDEO_STREAM);
+ test_t->streams[VIDEO_STREAM].wait_thread = true;
+ g_print("Video EOS wait thread\n");
+ STREAM_WAIT(VIDEO_STREAM);
+ test_t->streams[VIDEO_STREAM].wait_thread = false;
+ STREAM_UNLOCK(VIDEO_STREAM);
+ continue;
+ }
+
+ if (test_t->stop_thread)
+ pthread_exit(NULL);
+
+ __convert_espp_packet(vidbuf, &espp_packet);
+ submit_status = esplusplayer_submit_packet(test_t->espp_h, &espp_packet);
+#ifdef DEBUG_LOG
+ g_print("Video packet[media:%p, es:%p][%llu ms] espp submit packet status[%d]\n", vidbuf, &espp_packet, espp_packet.pts ,submit_status);
+#endif
+ media_packet_destroy(vidbuf);
+ }
+ g_print("EOS return of mediademuxer_read_sample() for video\n");
+ *status = 0;
+
+ return (void *)status;
+}
+
+static void __test_submit_packet()
+{
+ pthread_attr_t attr;
+ /* Initialize and set thread detached attribute */
+
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ if (g_test_h->streams[AUDIO_STREAM].activate) {
+ g_print("In main: creating thread for audio\n");
+ pthread_create(&g_test_h->streams[AUDIO_STREAM].thread,
+ &attr, _fetch_audio_data, g_test_h);
+ }
+ if (g_test_h->streams[VIDEO_STREAM].activate) {
+ g_print("In main: creating thread for video\n");
+ pthread_create(&g_test_h->streams[VIDEO_STREAM].thread,
+ &attr, _fetch_video_data, g_test_h);
+ }
+ pthread_attr_destroy(&attr);
+}
+
+static void __test_start()
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_start(g_test_h->espp_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_start()\n");
+ else
+ g_print(" => esplusplayer_start() success\n");
+}
+
+static void __test_stop()
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_stop(g_test_h->espp_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_stop()\n");
+ else
+ g_print(" => esplusplayer_stop() success\n");
+}
+
+static void __test_resume()
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_resume(g_test_h->espp_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_resume()\n");
+ else
+ g_print(" => esplusplayer_resume() success\n");
+}
+
+static void __test_pause()
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_pause(g_test_h->espp_h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_pause()\n");
+ else
+ g_print(" => esplusplayer_pause() success\n");
+}
+
+static void __test_seek(uint64_t time_ms)
+{
+ int ret = 0;
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ g_test_h->streams[AUDIO_STREAM].eos_track = false;
+ g_test_h->streams[AUDIO_STREAM].wait_thread = true;
+ g_test_h->streams[VIDEO_STREAM].eos_track = false;
+ g_test_h->streams[VIDEO_STREAM].wait_thread = true;
+
+ ret = mediademuxer_seek(g_test_h->demux_h, time_ms);
+ if (ret != MEDIADEMUXER_ERROR_NONE)
+ g_print(" => failed to mediademuxer_seek(%llu)\n", time_ms);
+ else
+ g_print(" => mediademuxer_seek(%llu) success\n", time_ms);
+
+ ret = esplusplayer_seek(g_test_h->espp_h, time_ms);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_seek(%llu)\n", time_ms);
+ else
+ g_print(" => esplusplayer_seek(%llu) success\n", time_ms);
+}
+
+static void __test_set_playback_rate(double playback_rate, bool audio_mute)
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_set_playback_rate(g_test_h->espp_h, playback_rate, audio_mute);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_playback_rate(%lf, %d)\n", playback_rate, audio_mute);
+ else
+ g_print(" => esplusplayer_set_playback_rate(%lf, %d) success\n", playback_rate, audio_mute);
+}
+
+static void __test_get_state()
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ esplusplayer_state state = esplusplayer_get_state(g_test_h->espp_h);
+ g_print(" => esplusplayer_get_state(%d) success\n", state);
+}
+
+static void __test_set_volume(int volume)
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_set_volume(g_test_h->espp_h, volume);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_volume(%d)\n", volume);
+ else
+ g_print(" => esplusplayer_set_volume(%d) success\n", volume);
+}
+
+static void __test_get_volume()
+{
+ int volume = 0;
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_get_volume(g_test_h->espp_h, &volume);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_get_volume\n");
+ else
+ g_print(" => esplusplayer_get_volume(%d) success\n", volume);
+}
+
+static void __test_set_mute(int mute)
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_set_audio_mute(g_test_h->espp_h, mute);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_audio_mute(%d)\n", mute);
+ else
+ g_print(" => esplusplayer_set_audio_mute(%d) success\n", mute);
+}
+
+static void __test_set_display(int type)
+{
+ int ret = 0;
+ void *display = NULL;
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ if (type == 1) {
+ display = (void *)g_win_id;
+ } else if (type == 2) {
+ display = (void *)g_eo;
+ } else {
+ g_print("!!! Not support display type(%d)\n", type);
+ return;
+ }
+ ret = esplusplayer_set_display(g_test_h->espp_h, type, display);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_display(%d)\n", type);
+ else
+ g_print(" => esplusplayer_set_display(%d) success\n", type);
+}
+
+static void __test_set_display_mode(int mode)
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ if (mode < 0 || mode > 5) {
+ g_print("!!! Not support display mode (%d)\n", mode);
+ return;
+ }
+
+ int ret = esplusplayer_set_display_mode(g_test_h->espp_h, mode);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_display_mode(%d)\n", mode);
+ else
+ g_print(" => esplusplayer_set_display_mode(%d) success\n", mode);
+}
+
+static void __test_set_display_roi(int x, int y, int w, int h)
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_set_display_roi(g_test_h->espp_h, x, y, w, h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_display_roi\n");
+ else
+ g_print(" => esplusplayer_set_display_roi() success\n");
+}
+
+static void __test_set_video_roi(double x, double y, double w, double h)
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_set_video_roi(g_test_h->espp_h, x, y, w, h);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_video_roi\n");
+ else
+ g_print(" => esplusplayer_set_video_roi() success\n");
+}
+
+static void __test_set_display_visible(int visible)
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ int ret = esplusplayer_set_display_visible(g_test_h->espp_h, visible);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_display_visible\n");
+ else
+ g_print(" => esplusplayer_set_display_visible() success\n");
+}
+
+static void __test_set_display_rotation(int mode)
+{
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ if (mode < 0 || mode > 3) {
+ g_print("!!! Not support display rotation (%d)\n", mode);
+ return;
+ }
+
+ int ret = esplusplayer_set_display_rotation(g_test_h->espp_h, mode);
+ if (ret != ESPLUSPLAYER_ERROR_TYPE_NONE)
+ g_print(" => failed to esplusplayer_set_display_rotation(%d)\n", mode);
+ else
+ g_print(" => esplusplayer_set_display_rotation(%d) success\n", mode);
+}
+
+static void __input_filename(char *filename)
+{
+ int len = 0;
+ gsize src_size = 0;
+ int ret = TIZEN_ERROR_NONE;
+
+ if (!filename)
+ return;
+
+ if (!g_test_h) {
+ g_print("test handle is NULL\n");
+ return;
+ }
+
+ len = strlen(filename);
+ if (len < 0 || len > MAX_STRING_LEN - 1)
+ return;
+
+ src_size = g_strlcpy(g_uri, filename, MAX_STRING_LEN);
+ if (src_size != len)
+ return;
+
+ ret = mediademuxer_set_data_source(g_test_h->demux_h, g_uri);
+ if (ret != MEDIADEMUXER_ERROR_NONE)
+ g_print(" => failed to mediademuxer_set_data_source()\n");
+}
+
+static void __interpret_main_menu(char *cmd)
+{
+ int len = strlen(cmd);
+ if (len == 1) {
+ if (strncmp(cmd, "c", 1) == 0) {
+ __init_test();
+ } else if (strncmp(cmd, "a", 1) == 0) {
+ g_menu_state = CURRENT_STATUS_FILENAME;
+ } else if (strncmp(cmd, "o", 1) == 0) {
+ __test_open();
+ } else if (strncmp(cmd, "S", 1) == 0) {
+ __test_get_state();
+ } else if (strncmp(cmd, "s", 1) == 0) {
+ __test_start();
+ } else if (strncmp(cmd, "t", 1) == 0) {
+ __test_stop();
+ } else if (strncmp(cmd, "d", 1) == 0) {
+ __test_resume();
+ } else if (strncmp(cmd, "e", 1) == 0) {
+ __test_pause();
+ } else if (strncmp(cmd, "j", 1) == 0) {
+ g_menu_state = CURRENT_STATUS_SEEK;
+ } else if (strncmp(cmd, "f", 1) == 0) {
+ g_menu_state = CURRENT_STATUS_SET_VOLUME;
+ } else if (strncmp(cmd, "g", 1) == 0) {
+ __test_get_volume();
+ } else if (strncmp(cmd, "h", 1) == 0) {
+ g_menu_state = CURRENT_STATUS_SET_MUTE;
+ } else if (strncmp(cmd, "q", 1) == 0) {
+ quit_program();
+ } else {
+ g_print("unknown menu \n");
+ }
+ } else if (len == 2) {
+ if (strncmp(cmd, "sa", 2) == 0) {
+ __test_set_audio_stream_info();
+ } else if (strncmp(cmd, "sv", 2) == 0) {
+ __test_set_video_stream_info();
+ } else if (strncmp(cmd, "at", 2) == 0) {
+ g_menu_state = CURRENT_STATUS_ACTIVATE;
+ } else if (strncmp(cmd, "da", 2) == 0) {
+ g_menu_state = CURRENT_STATUS_DEACTIVATE;
+ } else if (strncmp(cmd, "pa", 2) == 0) {
+ __test_prepare_async();
+ } else if (strncmp(cmd, "sp", 2) == 0) {
+ __test_submit_packet();
+ } else if (strncmp(cmd, "cl", 2) == 0) {
+ __test_close();
+ } else if (strncmp(cmd, "dt", 2) == 0) {
+ __test_destroy();
+ } else if (strncmp(cmd, "tr", 2) == 0) {
+ g_menu_state = CURRENT_STATUS_SET_RATE;
+ } else if (strncmp(cmd, "ds", 2) == 0) {
+ g_menu_state = CURRENT_STATUS_SET_DISPLAY;
+ } else if (strncmp(cmd, "dm", 2) == 0) {
+ g_menu_state = CURRENT_STATUS_SET_DISPLAY_MODE;
+ } else if (strncmp(cmd, "dr", 2) == 0) {
+ g_menu_state = CURRENT_STATUS_SET_DISPLAY_ROI;
+ } else if (strncmp(cmd, "dv", 2) == 0) {
+ g_menu_state = CURRENT_STATUS_SET_DISPLAY_VISIBLE;
+ } else {
+ g_print("unknown menu \n");
+ }
+ } else if (len == 3) {
+ if (strncmp(cmd, "prd", 3) == 0) {
+ __test_demuxer_prepare();
+ __test_demuxer_get_track_info();
+ g_menu_state = CURRENT_STATUS_SELECT_TRACK;
+ } else if (strncmp(cmd, "dvr", 3) == 0) {
+ g_menu_state = CURRENT_STATUS_SET_VIDEO_ROI;
+ } else if (strncmp(cmd, "drt", 3) == 0) {
+ g_menu_state = CURRENT_STATUS_SET_DISPLAY_ROTATION;
+ } else {
+ g_print("unknown menu \n");
+ }
+ } else {
+ g_print("unknown menu \n");
+ }
+}
+
+static void __display_sub_basic()
+{
+ g_print("\n");
+ g_print("=========================================================================================\n");
+ g_print(" ESPlusplayer Test with mediademuxer (press q to quit) \n");
+ g_print("-----------------------------------------------------------------------------------------\n");
+ g_print("c -> ds -> a -> prd (select track) -> sa / sv \n -> pa -> sp -> (got prepare async done cb) -> s\n");
+ g_print("-----------------------------------------------------------------------------------------\n");
+ g_print("[playback] c.Create\t");
+ g_print("a.Input media path\t");
+ g_print("o.Open\t\t");
+ g_print("cl.Close\n");
+ g_print(" sa.set audio stream info\t");
+ g_print("sv.set video stream info\n");
+ g_print(" at.Activate\t");
+ g_print("da.Deactivate\t");
+ g_print("pa.Prepare async\t");
+ g_print("sp.Submit packet\n");
+ g_print(" s.Start\t");
+ g_print("t.Stop\t\t");
+ g_print("d.Resume\t");
+ g_print("e.Pause\t\t");
+ g_print("dt.Destroy\n");
+ g_print("[seek] j.Seek\t\t");
+ g_print("[trick] tr.set playback rate\n");
+ g_print("[State] S.Get state\n");
+ g_print("[volume] f.Set Volume\t");
+ g_print("g.Get Volume\t");
+ g_print("h.Set Mute\n\n");
+
+ g_print("-- << mediademuxer cmd >> ---------------------------------------------------------------\n");
+ g_print("prd.prepare demuxer\n\n");
+
+ g_print("-- << display >> ------------------------------------------------------------------------\n");
+ g_print("ds.set display\t\t");
+ g_print("dm.set display mode\n");
+ g_print("dr.set display roi\t");
+ g_print("dvr.set video roi\n");
+ g_print("dv.set display visible\t");
+ g_print("drt.set display rotation\n");
+ g_print("=========================================================================================\n");
+}
+
+static void __displaymenu()
+{
+ if (g_menu_state == CURRENT_STATUS_MAINMENU) {
+ __display_sub_basic();
+ } else if (g_menu_state == CURRENT_STATUS_FILENAME) {
+ g_print("*** Input media path.\n");
+ } else if (g_menu_state == CURRENT_STATUS_ACTIVATE) {
+ g_print("*** Input activate stream.(0:audio, 1:video)\n");
+ } else if (g_menu_state == CURRENT_STATUS_DEACTIVATE) {
+ g_print("*** Input deactivate stream.(0:audio, 1:video)\n");
+ } else if (g_menu_state == CURRENT_STATUS_SEEK) {
+ g_print("*** Input seek position.(ms)\n");
+ } else if (g_menu_state == CURRENT_STATUS_SET_RATE) {
+ g_print("*** Input playback rate.(rate(0.0~2.0), audio_mute)\n");
+ } else if (g_menu_state == CURRENT_STATUS_SET_VOLUME) {
+ g_print("*** Input volume.(0 ~ 100)\n");
+ } else if (g_menu_state == CURRENT_STATUS_SET_MUTE) {
+ g_print("*** Set audio mute.(0:non-mute, 1:mute)\n");
+ } else if (g_menu_state == CURRENT_STATUS_SET_DISPLAY) {
+ g_print("*** Input display surface type. (0:none, 1:overlay, 2:evas)\n");
+ } else if (g_menu_state == CURRENT_STATUS_SET_DISPLAY_MODE) {
+ g_print("*** Input display mode. (0:Letter box, 1:Origin size, 2:Full screen, 3:Cropped full, 4:Origin or Letter, 5:Dst ROI)\n");
+ } else if (g_menu_state == CURRENT_STATUS_SET_DISPLAY_ROI) {
+ g_print("*** Input display roi. (x, y, w, h)\n");
+ } else if (g_menu_state == CURRENT_STATUS_SET_VIDEO_ROI) {
+ g_print("*** Input video roi(scale). (x, y, w, h)\n");
+ } else if (g_menu_state == CURRENT_STATUS_SET_DISPLAY_VISIBLE) {
+ g_print("*** Input display visible. (0:non-visible, 1:visible)\n");
+ } else if (g_menu_state == CURRENT_STATUS_SET_DISPLAY_ROTATION) {
+ g_print("*** Input display rotation.(0: NONE, 1: 90, 2: 180, 3: 270)\n");
+ } else if (g_menu_state == CURRENT_STATUS_SELECT_TRACK) {
+ g_print("*** Input select track id(video_id, audio_id <unselect -1>)\n");
+ } else {
+ g_print("*** Unknown status.\n");
+ quit_program();
+ }
+ g_print(" >>> ");
+}
+
+gboolean timeout_menu_display(void *data)
+{
+ __displaymenu();
+ return FALSE;
+}
+
+gboolean timeout_quit_program(void *data)
+{
+ quit_program();
+ return FALSE;
+}
+
+void reset_menu_state(void)
+{
+ g_menu_state = CURRENT_STATUS_MAINMENU;
+}
+
+static void interpret(char *cmd)
+{
+ int value = 0;
+ float value_f = 0.0;
+ uint64_t value_uin64 = 0;
+
+ switch (g_menu_state) {
+ case CURRENT_STATUS_MAINMENU:
+ {
+ __interpret_main_menu(cmd);
+ break;
+ }
+ case CURRENT_STATUS_FILENAME:
+ {
+ __input_filename(cmd);
+ reset_menu_state();
+ break;
+ }
+ case CURRENT_STATUS_ACTIVATE:
+ {
+ value = atoi(cmd);
+ __test_activate(value);
+ reset_menu_state();
+ break;
+ }
+ case CURRENT_STATUS_DEACTIVATE:
+ {
+ value = atoi(cmd);
+ __test_deactivate(value);
+ reset_menu_state();
+ break;
+ }
+ case CURRENT_STATUS_SEEK:
+ {
+ value_uin64 = (uint64_t)strtoul(cmd, NULL, 10);
+ __test_seek(value_uin64);
+ reset_menu_state();
+ break;
+ }
+ case CURRENT_STATUS_SET_RATE:
+ {
+ static float rate;
+ static int mute = 0;
+ static int cnt = 0;
+ switch (cnt) {
+ case 0:
+ value_f = atof(cmd);
+ rate = value_f;
+ cnt++;
+ break;
+ case 1:
+ cnt = 0;
+ value = atoi(cmd);
+ mute = value;
+ __test_set_playback_rate(rate, mute);
+ rate = 0;
+ mute = 0;
+ reset_menu_state();
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case CURRENT_STATUS_SET_VOLUME:
+ {
+ value = atoi(cmd);
+ __test_set_volume(value);
+ reset_menu_state();
+ break;
+ }
+ case CURRENT_STATUS_SET_MUTE:
+ {
+ value = atoi(cmd);
+ __test_set_mute(value);
+ reset_menu_state();
+ break;
+ }
+ case CURRENT_STATUS_SET_DISPLAY:
+ {
+ value = atoi(cmd);
+ __test_set_display(value);
+ reset_menu_state();
+ break;
+ }
+ case CURRENT_STATUS_SET_DISPLAY_MODE:
+ {
+ value = atoi(cmd);
+ __test_set_display_mode(value);
+ reset_menu_state();
+ break;
+ }
+ case CURRENT_STATUS_SET_DISPLAY_ROI:
+ {
+ value = atoi(cmd);
+ static int x = 0;
+ static int y = 0;
+ static int w = 0;
+ static int h = 0;
+ static int cnt = 0;
+ switch (cnt) {
+ case 0:
+ x = value;
+ cnt++;
+ break;
+ case 1:
+ y = value;
+ cnt++;
+ break;
+ case 2:
+ w = value;
+ cnt++;
+ break;
+ case 3:
+ cnt = 0;
+ h = value;
+ __test_set_display_roi(x, y, w, h);
+ x = y = w = h = 0;
+ reset_menu_state();
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case CURRENT_STATUS_SET_VIDEO_ROI:
+ {
+ value_f = atof(cmd);
+ static double x = 0;
+ static double y = 0;
+ static double w = 0;
+ static double h = 0;
+ static int cnt = 0;
+ switch (cnt) {
+ case 0:
+ x = (double)value_f;
+ cnt++;
+ break;
+ case 1:
+ y = (double)value_f;
+ cnt++;
+ break;
+ case 2:
+ w = (double)value_f;
+ cnt++;
+ break;
+ case 3:
+ cnt = 0;
+ h = (double)value_f;
+ __test_set_video_roi(x, y, w, h);
+ x = y = w = h = 0;
+ reset_menu_state();
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case CURRENT_STATUS_SET_DISPLAY_VISIBLE:
+ {
+ value = atoi(cmd);
+ __test_set_display_visible(value);
+ reset_menu_state();
+ break;
+ }
+ case CURRENT_STATUS_SET_DISPLAY_ROTATION:
+ {
+ value = atoi(cmd);
+ __test_set_display_rotation(value);
+ reset_menu_state();
+ break;
+ }
+ case CURRENT_STATUS_SELECT_TRACK:
+ {
+ int ret = 0;
+ value = atoi(cmd);
+ static int cnt = 0;
+ switch (cnt) {
+ case 0:
+ {
+ if (value != -1) {
+ g_test_h->streams[VIDEO_STREAM].format = g_test_h->track_format[value];
+ g_test_h->streams[VIDEO_STREAM].track_index = value;
+ ret = mediademuxer_select_track(g_test_h->demux_h, g_test_h->streams[VIDEO_STREAM].track_index);
+ if (ret != MEDIADEMUXER_ERROR_NONE)
+ g_print(" => failed to mediademuxer_select_track(video)\n");
+ else
+ g_print(" => mediademuxer_select_track(video) success\n");
+ }
+ cnt++;
+ break;
+ }
+ case 1:
+ {
+ cnt = 0;
+ if (value != -1) {
+ g_test_h->streams[AUDIO_STREAM].format = g_test_h->track_format[value];
+ g_test_h->streams[AUDIO_STREAM].track_index = value;
+ ret = mediademuxer_select_track(g_test_h->demux_h, g_test_h->streams[AUDIO_STREAM].track_index);
+ if (ret != MEDIADEMUXER_ERROR_NONE)
+ g_print(" => failed to mediademuxer_select_track(audio)\n");
+ else
+ g_print(" => mediademuxer_select_track(audio) success\n");
+ }
+ ret = mediademuxer_start(g_test_h->demux_h);
+ if (ret != MEDIADEMUXER_ERROR_NONE)
+ g_print(" => failed to mediademuxer_start()\n");
+ else
+ g_print(" => mediademuxer_start() success\n");
+
+ reset_menu_state();
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ g_timeout_add(100, timeout_menu_display, 0);
+}
+
+static gboolean input(GIOChannel *channel, GIOCondition condition, gpointer data)
+{
+ gchar buf[MAX_STRING_LEN];
+ gsize read;
+ GIOStatus status;
+
+ status = g_io_channel_read_chars(channel, buf, MAX_STRING_LEN, &read, NULL);
+ if (status != G_IO_STATUS_NORMAL) {
+ g_printerr("failed to g_io_channel_read_chars(), status[%d]\n", status);
+ return TRUE;
+ }
+
+ buf[read] = '\0';
+ g_strstrip(buf);
+ interpret(buf);
+
+ return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+ GIOChannel *stdin_channel;
+ 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, NULL);
+
+ __displaymenu();
+ memset(&g_ad, 0x0, sizeof(appdata));
+ ops.data = &g_ad;
+
+ return appcore_efl_main(PACKAGE, &argc, &argv, &ops);
+}