Adaptive streaming client basic implementation 57/83557/5 accepted/tizen/common/20160907.154700 accepted/tizen/ivi/20160908.044200 accepted/tizen/mobile/20160908.043601 accepted/tizen/tv/20160908.043943 accepted/tizen/wearable/20160908.044054 submit/tizen/20160907.074000
authorVolodymyr Brynza <v.brynza@samsung.com>
Tue, 30 Aug 2016 10:57:03 +0000 (13:57 +0300)
committerEunhae Choi <eunhae1.choi@samsung.com>
Tue, 6 Sep 2016 04:43:07 +0000 (13:43 +0900)
Change-Id: Ia5f29a521f4d3838fa36d4107bc518aac5dcd4ce
Signed-off-by: Volodymyr Brynza <v.brynza@samsung.com>
include/media_streamer.h
include/media_streamer_gst.h
include/media_streamer_util.h
src/media_streamer_gst.c
src/media_streamer_node.c
src/media_streamer_util.c
test/media_streamer_test.c

index dfc3cf6..6275c69 100644 (file)
@@ -102,7 +102,8 @@ typedef enum {
        MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_CAPTURE,  /**<  Video capture src type, Camera feature is required */
        MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_TEST,     /**<  Audio test src type */
        MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_TEST,     /**<  Video test src type */
-       MEDIA_STREAMER_NODE_SRC_TYPE_CUSTOM          /**<  Custom src type */
+       MEDIA_STREAMER_NODE_SRC_TYPE_CUSTOM,         /**<  Custom src type */
+       MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE        /**<  Adaptive src type */
 } media_streamer_node_src_type_e;
 
 /**
@@ -1063,7 +1064,7 @@ int media_streamer_node_get_pad_format(media_streamer_node_h node, const char *p
  * @brief Gets name of node pads.
  * @since_tizen 3.0
  * @remark After using the src_pad_name and sink_pad_name, it have to be free.
- *         src_pad_name or sink_pad_name can be null accoring to the node type.
+ *         src_pad_name or sink_pad_name can be null according to the node type.
  *         In case of src type node, sink_pad_name will be null.
  *         In case of sink type node, src_pad_name will be null.
  * @param [in]  node            Media streamer node handle
@@ -1139,7 +1140,7 @@ int media_streamer_node_get_params(media_streamer_node_h node, bundle **param_li
  *          The externalstorage privilege(http://tizen.org/privilege/externalstorage) should be added if any video/audio files are written in the external storage devices.
  * @param [in] node        Media streamer node handle
  * @param [in] param_name  Param name of node
- * @param [in] param_value Parm value of node
+ * @param [in] param_value Param value of node
  * @return @c 0 on success,
  *         otherwise a negative error value
  * @retval #MEDIA_STREAMER_ERROR_NONE Successful
@@ -1165,7 +1166,7 @@ int media_streamer_node_set_param(media_streamer_node_h node,
  * @since_tizen 3.0
  * @param [in] node         Media streamer node handle
  * @param [in] param_name   Param name of node
- * @param [out] param_value Parm value of node
+ * @param [out] param_value Param value of node
  * @return @c 0 on success,
  *         otherwise a negative error value
  * @retval #MEDIA_STREAMER_ERROR_NONE Successful
index 26a6cc1..dbccb31 100644 (file)
@@ -75,6 +75,20 @@ GstElement *__ms_bin_find_element_by_klass(GstElement *sink_bin, GstElement *pre
 GstElement *__ms_element_create(const char *plugin_name, const char *name);
 
 /**
+ * @brief Creates GstBin name for adaptive streaming.
+ *
+ * @since_tizen 3.0
+ */
+GstElement *__ms_adaptive_element_create(void);
+
+/**
+ * @brief Prepares GstBin for adaptive streaming.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_adaptive_element_prepare(media_streamer_node_s *ms_node, bool auto_plug);
+
+/**
  * @brief Creates GstElement from specified node_plug_s structure.
  *
  * @since_tizen 3.0
@@ -103,6 +117,13 @@ GstElement *__ms_video_decoder_element_create(node_plug_s *plug_info, media_stre
 GstElement *__ms_audio_encoder_element_create(node_plug_s *plug_info, media_streamer_node_type_e type);
 
 /**
+ * @brief Creates audio decoder GstElement.
+ *
+ * @since_tizen 3.0
+ */
+GstElement *__ms_audio_decoder_element_create(node_plug_s *plug_info, media_streamer_node_type_e type);
+
+/**
  * @brief Creates rtp container GstElement.
  *
  * @since_tizen 3.0
@@ -246,3 +267,10 @@ int __ms_element_push_packet(GstElement *src_element, media_packet_h packet);
  * @since_tizen 3.0
  */
 int __ms_element_pull_packet(GstElement *sink_element, media_packet_h *packet);
+
+/**
+ * @brief Prepare demuxer elemetn for playing.
+ *
+ * @since_tizen 3.0
+ */
+int __ms_demux_element_prepare(media_streamer_s *ms_streamer, media_streamer_node_s *demux_node);
index 01ecb96..74de8ba 100644 (file)
@@ -183,6 +183,9 @@ typedef struct {
 #define DEFAULT_AUDIO_RTPPAY                "rtpamrpay"
 #define DEFAULT_AUDIO_RTPDEPAY              "rtpamrdepay"
 
+/* adaptive streaming default */
+#define DEFAULT_ADAPTIVE_SOURCE             "hlsdemux"
+
 #define MEDIA_STREAMER_DEFAULT_CAMERA_FORMAT "video/x-raw,format=I420,width=352,height=288"
 #define MEDIA_STREAMER_DEFAULT_AUDIO_RAW_FORMAT "audio/x-raw,channels=1,rate=8000,format=S16LE"
 #define MEDIA_STREAMER_DEFAULT_VIDEO_FORMAT "video/x-h263,width=352,height=288,framerate = 3/1"
@@ -330,6 +333,13 @@ void __ms_signal_destroy(void *data);
  */
 void __ms_param_value_destroy(gpointer data);
 
+/**
+ * @brief Check URI is valid file
+ *
+ * @since_tizen 3.0
+ */
+int __ms_node_uri_path_check(const char *file_uri);
+
 #ifdef __cplusplus
 }
 #endif
index 4d2f53c..dd3e0d0 100644 (file)
@@ -454,6 +454,7 @@ static gint __decodebin_autoplug_select_cb(GstElement * bin, GstPad * pad, GstCa
                                return GST_AUTOPLUG_SELECT_SKIP;
                        }
                }
+
        }
 
        return result;
@@ -695,6 +696,116 @@ GstElement *__ms_element_create(const char *plugin_name, const char *name)
        return plugin_elem;
 }
 
+static void __hlsdemux_pad_added_cb(GstElement *demux, GstPad *pad, gpointer data)
+{
+       GstPad *gp = GST_PAD(data);
+       gst_ghost_pad_set_target (GST_GHOST_PAD(gp), pad);
+}
+
+GstElement *__ms_adaptive_element_create(void)
+{
+       GstElement *adaptive_bin = gst_bin_new("adaptive_src");
+       ms_retvm_if(!adaptive_bin, (GstElement *) NULL, "Error: creating elements for adaptive source");
+
+       __ms_add_no_target_ghostpad(adaptive_bin, "src", GST_PAD_SRC);
+
+       /* Add adaptive node parameters as GObject data with destroy function */
+       MS_SET_INT_STATIC_STRING_PARAM(adaptive_bin, MEDIA_STREAMER_PARAM_URI, "http://localhost");
+
+       return adaptive_bin;
+}
+
+static GstElement *__ms_manifest_src_create(media_streamer_node_s *ms_node)
+{
+       char *manifest_src_name = NULL;
+       gchar *location = NULL;
+       GstElement *manifest_src = NULL;
+
+       GValue *val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), MEDIA_STREAMER_PARAM_URI);
+       const char *uri = g_value_get_string(val);
+       gchar *protocol = gst_uri_is_valid(uri) ? gst_uri_get_protocol(uri) : NULL;
+
+       if (protocol && g_strrstr(protocol, "http")) {
+               manifest_src_name = __ms_ini_get_string("node type 1:http", DEFAULT_HTTP_SOURCE);
+               location = g_strdup(uri);
+       } else if (protocol && g_strrstr(protocol, "file")) {
+               manifest_src_name = __ms_ini_get_string("node type 1:file", DEFAULT_FILE_SOURCE);
+               location = gst_uri_get_location(uri);
+       } else {
+               ms_error("Unsupported URI protocol... Check URI is file path");
+               if (__ms_node_uri_path_check(uri) == MEDIA_STREAMER_ERROR_NONE) {
+                       manifest_src_name = __ms_ini_get_string("node type 1:file", DEFAULT_FILE_SOURCE);
+                       location = g_strdup(uri);
+               } else {
+                       g_free(protocol);
+                       ms_error("URI is not valid file path");
+                       return NULL;
+               }
+       }
+       g_free(protocol);
+       ms_retvm_if(manifest_src_name == NULL, NULL,
+                       "Error empty manifest source name for adaprive source");
+       manifest_src = gst_element_factory_make(manifest_src_name, NULL);
+       ms_retvm_if(manifest_src == NULL, NULL,
+                       "Error creating manifest source for adaptive source");
+       g_object_set(manifest_src, "location", location, NULL);
+       g_free(location);
+
+       return manifest_src;
+}
+
+int __ms_adaptive_element_prepare(media_streamer_node_s *ms_node, bool auto_plug)
+{
+       char *plugin_name = NULL;
+       GstElement *manifest_src = NULL;
+       GstElement *plugin_elem = NULL;
+       gboolean res = FALSE;
+       GstPad *gp = NULL;
+
+       ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       if (!auto_plug) {
+               plugin_name = __ms_ini_get_string("node type 1:adaptive", DEFAULT_ADAPTIVE_SOURCE);
+               ms_retvm_if(plugin_name == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error empty plugin name for adaprive source");
+               ms_info("Creating [%s] element", plugin_name);
+               plugin_elem = gst_element_factory_make(plugin_name, NULL);
+               ms_retvm_if(plugin_elem == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER,
+                               "Error creating element [%s] for adaptive source", plugin_name);
+
+               res = gst_bin_add(GST_BIN(ms_node->gst_element), plugin_elem);
+               ms_retvm_if(res == FALSE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER,
+                               "Error adding adaptive element to bin for adaptive source");
+       }
+
+       manifest_src = __ms_manifest_src_create(ms_node);
+       ms_retvm_if(manifest_src == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER,
+                       "Error creating manifest source for adaptive source");
+
+       res = gst_bin_add(GST_BIN(ms_node->gst_element), manifest_src);
+       ms_retvm_if(res == FALSE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER,
+                       "Error adding manifest source to bin for adaptive source");
+
+       if (!auto_plug) {
+               res = gst_element_link(manifest_src, plugin_elem);
+               ms_retvm_if(res == FALSE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER,
+                               "Error linking manifest source and element for adaptive source");
+       }
+
+       gp = gst_element_get_static_pad(ms_node->gst_element, "src");
+       ms_retvm_if(gp == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER,
+                       "Error getting source pad for adaptive source");
+
+       if (!auto_plug) {
+               g_signal_connect_object(plugin_elem, "pad-added",
+                               G_CALLBACK(__hlsdemux_pad_added_cb), gp, 0);
+       } else {
+               GstPad *manifest_src_pad = gst_element_get_static_pad(manifest_src, "src");
+               gst_ghost_pad_set_target (GST_GHOST_PAD(gp), manifest_src_pad);
+       }
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
 static gboolean __ms_feature_node_filter(GstPluginFeature *feature, gpointer data)
 {
        node_plug_s *plug_info = (node_plug_s*)data;
@@ -825,6 +936,8 @@ GstElement *__ms_node_element_create(node_plug_s *plug_info, media_streamer_node
         * element will be created immediately by format ot name */
        if (type == MEDIA_STREAMER_NODE_TYPE_AUDIO_ENCODER)
                gst_element = __ms_audio_encoder_element_create(plug_info, type);
+       else if (type == MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER)
+               gst_element = __ms_audio_decoder_element_create(plug_info, type);
        else if (type == MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER)
                gst_element = __ms_video_encoder_element_create(plug_info, type);
        else if (type == MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER)
@@ -1027,6 +1140,60 @@ GstElement *__ms_audio_encoder_element_create(node_plug_s *plug_info, media_stre
        return audio_enc_bin;
 }
 
+GstElement *__ms_audio_decoder_element_create(node_plug_s *plug_info, media_streamer_node_type_e type)
+{
+       GstCaps *dec_caps = plug_info->sink_caps;
+       if (!dec_caps) {
+               dec_caps = gst_caps_from_string(MEDIA_STREAMER_DEFAULT_AUDIO_FORMAT);
+               ms_debug("No Audio decoding format is set! Deafault will be: [%s]", MEDIA_STREAMER_DEFAULT_AUDIO_FORMAT);
+       }
+
+       /* Creating Audio Decoder */
+       node_info_s *node_klass_type = __ms_node_get_klass_by_its_type(type);
+       node_plug_s decoder_info = {node_klass_type, plug_info->src_caps, dec_caps, NULL};
+       GstElement *decoder_elem = __ms_element_create_from_ini(&decoder_info, MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER);
+       if (!decoder_elem)
+               decoder_elem = __ms_element_create_by_registry(&decoder_info, MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER);
+
+       /* Creating Audio Parser */
+       node_info_s nodes_info = {MEDIA_STREAMER_PARSER_KLASS, DEFAULT_AUDIO_PARSER};
+       node_plug_s parser_info = {&nodes_info, dec_caps, dec_caps, NULL};
+       GstElement *decoder_parser = __ms_element_create_from_ini(&parser_info, MEDIA_STREAMER_NODE_TYPE_PARSER);
+       if (!decoder_parser)
+               decoder_parser = __ms_element_create_by_registry(&parser_info, MEDIA_STREAMER_NODE_TYPE_PARSER);
+
+       /* Creating bin - Audio Decoder */
+       gboolean gst_ret = FALSE;
+       GstElement *decoder_bin = gst_bin_new("audio_decoder");
+       GstElement *decoder_queue = __ms_element_create("queue", NULL);
+       ms_retvm_if(!decoder_elem || !decoder_queue || !decoder_bin || !decoder_parser, (GstElement *) NULL, "Error: creating elements for audio decoder bin");
+
+       /* Adding elements to bin Audio Encoder */
+       gst_bin_add_many(GST_BIN(decoder_bin), decoder_queue, decoder_elem, decoder_parser, NULL);
+       gst_ret = gst_element_link_many(decoder_queue, decoder_parser, decoder_elem, NULL);
+       if (gst_ret != TRUE) {
+               ms_error("Failed to link elements into decoder_bin");
+               MS_SAFE_UNREF(decoder_bin);
+               return NULL;
+       }
+
+       GstElement *audio_conv = __ms_element_create("audioconvert", NULL);
+       GstElement *audio_resample = __ms_element_create("audioresample", NULL);
+       ms_retvm_if(!audio_conv || !audio_resample, (GstElement *) NULL, "Error: creating elements for audio decoder bin");
+       gst_bin_add_many(GST_BIN(decoder_bin), audio_conv, audio_resample, NULL);
+       gst_ret = gst_element_link_many(decoder_elem, audio_conv, audio_resample, NULL);
+       if (gst_ret != TRUE) {
+               ms_error("Failed to link elements into decoder_bin");
+               MS_SAFE_UNREF(decoder_bin);
+               return NULL;
+       }
+
+       __ms_add_ghostpad(audio_resample, "src", decoder_bin, "src");
+       __ms_add_ghostpad(decoder_queue, "sink", decoder_bin, "sink");
+
+       return decoder_bin;
+}
+
 GstElement *__ms_rtp_element_create(void)
 {
        GstElement *rtp_container = gst_bin_new("rtp_container");
@@ -1491,6 +1658,11 @@ GstCaps *__ms_create_caps_from_fmt(media_format_h fmt)
                caps_name = gst_caps_to_string(caps);
                ms_info("Creating Video Caps from media format [%s]", caps_name);
 
+       } else if (!media_format_get_container_mime(fmt, &mime)) {
+                       caps = gst_caps_new_empty_simple(__ms_convert_mime_to_string_format(mime));
+                       caps_name = gst_caps_to_string(caps);
+                       ms_info("Creating Video Caps from media format [%s]", caps_name);
+
        } else
                ms_error("Error getting media format information");
 
@@ -1785,3 +1957,61 @@ int __ms_element_pull_packet(GstElement *sink_element, media_packet_h *packet)
        gst_sample_unref(sample);
        return ret;
 }
+
+static void __demux_newpad_cb(GstElement * demux, GstPad * new_pad, gpointer user_data)
+{
+       media_streamer_s *ms_streamer = (media_streamer_s *) user_data;
+       ms_retm_if(ms_streamer == NULL, "Handle is NULL");
+
+       g_mutex_lock(&ms_streamer->mutex_lock);
+
+       g_object_ref(new_pad);
+       ms_streamer->pads_types_list = g_list_insert_sorted(ms_streamer->pads_types_list, new_pad, __pad_type_compare);
+
+       g_mutex_unlock(&ms_streamer->mutex_lock);
+}
+
+static void __demux_nomore_pads_combine(GstPad *src_pad, media_streamer_s *ms_streamer)
+{
+       GstElement *found_element = gst_pad_get_parent_element(src_pad);
+       const gchar *new_pad_type = __ms_get_pad_type(src_pad);
+       if (MS_ELEMENT_IS_VIDEO(new_pad_type)) {
+               found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER);
+       } else if (MS_ELEMENT_IS_AUDIO(new_pad_type)) {
+               found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER);
+       } else if (MS_ELEMENT_IS_TEXT(new_pad_type)) {
+               found_element = __ms_combine_next_element(found_element, src_pad, ms_streamer->topology_bin, MEDIA_STREAMER_NODE_TYPE_TEXT_OVERLAY);
+       } else {
+               ms_error("Unsupported pad type [%s]!", new_pad_type);
+       }
+       __ms_generate_dots(ms_streamer->pipeline, "after_demux_linked");
+       gst_object_unref(found_element);
+}
+
+static void __demux_nomore_pads_cb(GstElement *demux, gpointer user_data)
+{
+       media_streamer_s *ms_streamer = (media_streamer_s *) user_data;
+       ms_retm_if(ms_streamer == NULL, "Handle is NULL");
+
+       g_mutex_lock(&ms_streamer->mutex_lock);
+
+       GList *iterator = NULL;
+       GList *list = ms_streamer->pads_types_list;
+       for (iterator = list; iterator; iterator = iterator->next) {
+               GstPad *src_pad = GST_PAD(iterator->data);
+               __demux_nomore_pads_combine(src_pad, ms_streamer);
+       }
+
+       g_mutex_unlock(&ms_streamer->mutex_lock);
+}
+
+int __ms_demux_element_prepare(media_streamer_s * ms_streamer, media_streamer_node_s *demux_node)
+{
+       ms_retvm_if(!ms_streamer, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       ms_retvm_if(!demux_node, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       __ms_signal_create(&ms_streamer->autoplug_sig_list, demux_node->gst_element, "pad-added", G_CALLBACK(__demux_newpad_cb), ms_streamer);
+       __ms_signal_create(&ms_streamer->autoplug_sig_list, demux_node->gst_element, "no-more-pads", G_CALLBACK(__demux_nomore_pads_cb), ms_streamer);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
index ff86275..0ca0464 100644 (file)
@@ -17,8 +17,6 @@
 #include <media_streamer_node.h>
 #include <media_streamer_util.h>
 #include <media_streamer_gst.h>
-#include <fcntl.h>
-#include <sys/stat.h>
 #include <cynara-client.h>
 
 #define SMACK_LABEL_LEN 255
@@ -168,6 +166,62 @@ static int __ms_rtp_node_set_property(media_streamer_node_s *ms_node, param_s *p
        return ret;
 }
 
+static gboolean __ms_adaptive_src_node_has_property(media_streamer_node_s *ms_node, const char * param_name)
+{
+       ms_retvm_if(!ms_node || !ms_node->gst_element, FALSE, "Error: empty node");
+       ms_retvm_if(!param_name, FALSE, "Error: invalid property parameter");
+
+       if (ms_node->type == MEDIA_STREAMER_NODE_TYPE_SRC &&
+                       ms_node->subtype == MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE) {
+               GValue *val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), param_name);
+               return val ? TRUE : FALSE;
+       }
+
+       return FALSE;
+}
+
+static int __ms_adaptive_src_node_get_property(media_streamer_node_s *ms_node, param_s *param, GValue *value)
+{
+       ms_retvm_if(!ms_node || !ms_node->gst_element, FALSE, "Error: empty node");
+       ms_retvm_if(ms_node->type != MEDIA_STREAMER_NODE_TYPE_SRC &&
+                       ms_node->subtype != MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type");
+       ms_retvm_if(!param, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: invalid property parameter");
+
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       GValue *val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), param->param_name);
+       if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_URI))
+               g_value_init(value, G_TYPE_STRING);
+       else
+               ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
+
+       g_value_copy(val, value);
+       return ret;
+}
+
+static int __ms_adaptive_src_node_set_property(media_streamer_node_s *ms_node, param_s *param, const char *param_value)
+{
+       ms_retvm_if(!ms_node || !ms_node->gst_element, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Error: empty node");
+       ms_retvm_if(ms_node->type != MEDIA_STREAMER_NODE_TYPE_SRC &&
+                       ms_node->subtype != MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid node type");
+       ms_retvm_if(!param, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: invalid property parameter");
+
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       GValue *val = (GValue *)g_object_get_data(G_OBJECT(ms_node->gst_element), param->param_name);
+       if (!val)
+               ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
+
+       if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_URI)) {
+               g_value_unset(val);
+               g_value_init(val, G_TYPE_STRING);
+               g_value_set_string(val, param_value);
+       } else
+               ret = MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
+
+       return ret;
+}
+
 int __ms_node_create(media_streamer_node_s *node, media_format_h in_fmt, media_format_h out_fmt)
 {
        ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
@@ -235,6 +289,9 @@ static int __ms_node_check_priveleges(media_streamer_node_s *node)
                case MEDIA_STREAMER_NODE_SRC_TYPE_HTTP:
                        privilege = "http://tizen.org/privilege/internet";
                        break;
+               case MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE:
+                       privilege = "http://tizen.org/privilege/internet";
+                       break;
                case MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA:
                        privilege = "http://tizen.org/privilege/camera";
                        break;
@@ -367,6 +424,9 @@ int __ms_src_node_create(media_streamer_node_s *node)
                __ms_signal_create(&node->sig_list, node->gst_element, "need-data", G_CALLBACK(__ms_src_start_feed_cb), node);
                __ms_signal_create(&node->sig_list, node->gst_element, "enough-data", G_CALLBACK(__ms_src_stop_feed_cb), node);
                break;
+       case MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE:
+               node->gst_element = __ms_adaptive_element_create();
+               break;
        default:
                ms_error("Error: invalid Src node Type [%d]", node->subtype);
                break;
@@ -604,14 +664,22 @@ static void _src_node_prepare(const GValue *item, gpointer user_data)
        MS_SAFE_UNREF(src_pad);
 }
 
+static gboolean demux_find(gpointer key, gpointer value, gpointer user_data) {
+       return g_strrstr((char *)key, "demux") != NULL;
+}
+
 int __ms_pipeline_prepare(media_streamer_s *ms_streamer)
 {
        ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
 
        int ret = MEDIA_STREAMER_ERROR_NONE;
        media_streamer_node_s *rtp_node = (media_streamer_node_s *)g_hash_table_lookup(ms_streamer->nodes_table, "rtp_container");
+       media_streamer_node_s *demux = (media_streamer_node_s *)g_hash_table_find(ms_streamer->nodes_table, (GHRFunc)demux_find, NULL);
+       media_streamer_node_s *adaptive_src = (media_streamer_node_s *)g_hash_table_lookup(ms_streamer->nodes_table, "adaptive_src");
        if (rtp_node) {
                ret = __ms_rtp_element_prepare(rtp_node) ? MEDIA_STREAMER_ERROR_NONE : MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
+       } else if (demux) {
+               ret = __ms_demux_element_prepare(ms_streamer, demux) ? MEDIA_STREAMER_ERROR_NONE : MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
        } else {
                GstBin *nodes_bin = GST_BIN(ms_streamer->src_bin);
                if (nodes_bin->numchildren == 0) {
@@ -625,6 +693,14 @@ int __ms_pipeline_prepare(media_streamer_s *ms_streamer)
                }
        }
 
+       if (adaptive_src) {
+               if (GST_BIN(ms_streamer->topology_bin)->numchildren == 0) {
+                       ret = __ms_adaptive_element_prepare(adaptive_src, true);
+               } else {
+                       ret = __ms_adaptive_element_prepare(adaptive_src, false);
+               }
+       }
+
        MS_BIN_FOREACH_ELEMENTS(ms_streamer->sink_bin, __ms_element_lock_state, ms_streamer);
        MS_BIN_FOREACH_ELEMENTS(ms_streamer->src_bin, _src_node_prepare, ms_streamer);
 
@@ -780,7 +856,8 @@ int __ms_node_get_param(media_streamer_node_s *node, const char *param_name, par
        for (it_param = 0; param_table[it_param].param_name != NULL; it_param++) {
                if (!g_strcmp0(param_name, param_table[it_param].param_name)) {
                        param_spec = g_object_class_find_property(G_OBJECT_GET_CLASS(node->gst_element), param_table[it_param].origin_name);
-                       if (param_spec || __ms_rtp_node_has_property(node, param_name)) {
+                       if (param_spec || __ms_rtp_node_has_property(node, param_table[it_param].origin_name) ||
+                                       __ms_adaptive_src_node_has_property(node, param_table[it_param].origin_name)) {
                                *param = &(param_table[it_param]);
                                ms_info("Got parameter [%s] for node [%s]", (*param)->param_name, node->name);
                                found_param = TRUE;
@@ -799,7 +876,8 @@ int __ms_node_get_param_list(media_streamer_node_s *node, GList **param_list)
 
        for (it_param = 0; param_table[it_param].param_name != NULL; it_param++) {
                param_spec = g_object_class_find_property(G_OBJECT_GET_CLASS(node->gst_element), param_table[it_param].origin_name);
-               if (param_spec || __ms_rtp_node_has_property(node, param_table[it_param].param_name)) {
+               if (param_spec || __ms_rtp_node_has_property(node, param_table[it_param].origin_name) ||
+                               __ms_adaptive_src_node_has_property(node, param_table[it_param].origin_name)) {
                        ms_info("Got parameter [%s] for node [%s]", param_table[it_param].param_name, node->name);
                        *param_list = g_list_append(*param_list, &(param_table[it_param]));
                }
@@ -818,6 +896,9 @@ int __ms_node_get_param_value(media_streamer_node_s *node, param_s *param, char
 
        if (node->type == MEDIA_STREAMER_NODE_TYPE_RTP)
                ret = __ms_rtp_node_get_property(node, param, &value);
+       else if (node->type == MEDIA_STREAMER_NODE_TYPE_SRC &&
+                       node->subtype == MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE)
+               ret = __ms_adaptive_src_node_get_property(node, param, &value);
        else {
                param_spec = g_object_class_find_property(G_OBJECT_GET_CLASS(node->gst_element), param->origin_name);
                if (param_spec) {
@@ -891,46 +972,6 @@ int __ms_node_get_param_value(media_streamer_node_s *node, param_s *param, char
        return ret;
 }
 
-int __ms_node_uri_path_check(const char *file_uri)
-{
-       struct stat stat_results = {0, };
-       int file_open = 0;
-
-       if (!file_uri || !strlen(file_uri))
-               return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
-
-       /* We can not check wheter the content is available over http or other protocol
-        * Thus, here we have to check occurence of :// */
-       if (g_strrstr_len(file_uri, DEFAULT_URI_SCHEME_LENGTH,  "://"))
-               return MEDIA_STREAMER_ERROR_NONE;
-
-       file_open = open(file_uri, O_RDONLY);
-       if (file_open < 0) {
-               char mes_error[256];
-               strerror_r(errno, mes_error, sizeof(mes_error));
-               ms_error("Couldn`t open file according to [%s]. Error N [%d]", mes_error, errno);
-
-               if (EACCES == errno)
-                       return MEDIA_STREAMER_ERROR_PERMISSION_DENIED;
-
-               return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
-       }
-
-       if (fstat(file_open, &stat_results) < 0) {
-               ms_error("Couldn`t get status of the file [%s]", file_uri);
-       } else if (stat_results.st_size == 0) {
-               ms_error("The size of file is 0");
-               close(file_open);
-               return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
-       } else {
-               ms_debug("Size of file [%lld] bytes", (long long)stat_results.st_size);
-       }
-
-       close(file_open);
-
-       return MEDIA_STREAMER_ERROR_NONE;
-}
-
 int __ms_node_set_param_value(media_streamer_node_s *ms_node, param_s *param, const char *param_value)
 {
        ms_retvm_if(!ms_node || !param || !param_value,  MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
@@ -942,6 +983,12 @@ int __ms_node_set_param_value(media_streamer_node_s *ms_node, param_s *param, co
                return ret;
        }
 
+       if (ms_node->type == MEDIA_STREAMER_NODE_TYPE_SRC &&
+                       ms_node->subtype == MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE) {
+               ret = __ms_adaptive_src_node_set_property(ms_node, param, param_value);
+               return ret;
+       }
+
        if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_CAMERA_ID)) {
                int camera_id = (int)strtol(param_value, NULL, 10);
                ms_retvm_if(camera_id == -1, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Invalid %s value", param->param_name);
index dcb1d60..d639070 100644 (file)
@@ -19,6 +19,9 @@
 #include <media_streamer.h>
 #include <media_streamer_util.h>
 
+#include <fcntl.h>
+#include <sys/stat.h>
+
 format_s format_table[] = {
        /* Audio - ENCODED */
        {MEDIA_FORMAT_L16, "audio/x-raw"},
@@ -70,6 +73,9 @@ format_s format_table[] = {
        {MEDIA_FORMAT_RGBA, "RGBA"},
        {MEDIA_FORMAT_ARGB, "ARGB"},
        {MEDIA_FORMAT_NATIVE_VIDEO, "NATIVE_VIDEO"},
+       /* Container */
+       {MEDIA_FORMAT_CONTAINER_MP4, "video/quicktime"},
+       {MEDIA_FORMAT_CONTAINER_MPEG2TS, "video/mpegts"},
        {MEDIA_FORMAT_MAX, NULL}
 };
 
@@ -279,3 +285,38 @@ void __ms_param_value_destroy(gpointer data)
        }
        MS_SAFE_GFREE(val);
 }
+
+int __ms_node_uri_path_check(const char *file_uri)
+{
+       struct stat stat_results = {0, };
+       int file_open = 0;
+
+       if (!file_uri || !strlen(file_uri))
+               return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
+
+       file_open = open(file_uri, O_RDONLY);
+       if (file_open < 0) {
+               char mes_error[256];
+               strerror_r(errno, mes_error, sizeof(mes_error));
+               ms_error("Couldn`t open file according to [%s]. Error N [%d]", mes_error, errno);
+
+               if (EACCES == errno)
+                       return MEDIA_STREAMER_ERROR_PERMISSION_DENIED;
+
+               return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
+       }
+
+       if (fstat(file_open, &stat_results) < 0) {
+               ms_error("Couldn`t get status of the file [%s]", file_uri);
+       } else if (stat_results.st_size == 0) {
+               ms_error("The size of file is 0");
+               close(file_open);
+               return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
+       } else {
+               ms_debug("Size of file [%lld] bytes", (long long)stat_results.st_size);
+       }
+
+       close(file_open);
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
index bf6aad6..4974e5f 100644 (file)
@@ -28,7 +28,8 @@ typedef enum {
        MENU_STATE_BROADCAST_MENU,
        MENU_STATE_VOIP_MENU,
        MENU_STATE_PLAYING_MENU,
-       MENU_STATE_PRESET_MENU
+       MENU_STATE_PRESET_MENU,
+       MENU_STATE_ADAPTIVE_MENU,
 } menu_state_e;
 
 typedef enum {
@@ -40,7 +41,8 @@ typedef enum {
        SUBMENU_STATE_AUTOPLUG,
        SUBMENU_STATE_SCENARIO,
        SUBMENU_STATE_PLAYING_SCENARIO,
-       SUBMENU_STATE_FORMAT
+       SUBMENU_STATE_FORMAT,
+       SUBMENU_STATE_ADAPTIVE_SCENARIO,
 } submenu_state_e;
 
 #define SECOND_VOIP_MASK 0x8
@@ -70,7 +72,10 @@ typedef enum {
        SCENARIO_MODE_FILE_PLAY_VIDEO_AUDIO,
        SCENARIO_MODE_FILE_SUBTITLE_VIDEO_AUDIO,
        SCENARIO_MODE_HTTP_VIDEO_AUDIO,
-       SCENARIO_MODE_APPSRC_APPSINK
+       SCENARIO_MODE_APPSRC_APPSINK,
+       SCENARIO_MODE_ADAPTIVE_SERVER,
+       SCENARIO_MODE_ADAPTIVE_CLIENT_AUTO,
+       SCENARIO_MODE_ADAPTIVE_CLIENT_MANUAL,
 } scenario_mode_e;
 
 #define PACKAGE "media_streamer_test"
@@ -123,8 +128,11 @@ gboolean g_audio_is_on = FALSE;
 
 media_format_h vfmt_raw = NULL;
 media_format_h vfmt_encoded = NULL;
+media_format_h vfmt_aenc = NULL;
 media_format_h afmt_raw = NULL;
 media_format_h afmt_encoded = NULL;
+media_format_h afmt_aenc = NULL;
+media_format_h tsfmt = NULL;
 
 static void streamer_error_cb(media_streamer_h streamer, media_streamer_error_e error, void *user_data)
 {
@@ -297,6 +305,16 @@ static void create_formats(void)
        media_format_set_video_avg_bps(vfmt_encoded, VIDEO_AVG_BPS);
        media_format_set_video_max_bps(vfmt_encoded, VIDEO_MAX_BPS);
 
+       /* Define encoded video format for adaptive stream */
+       media_format_create(&vfmt_aenc);
+       if (media_format_set_video_mime(vfmt_aenc, MEDIA_FORMAT_H264_SP) != MEDIA_FORMAT_ERROR_NONE)
+               g_print("media_format_set_video_mime failed!");
+
+       media_format_set_video_width(vfmt_aenc, VIDEO_WIDTH);
+       media_format_set_video_height(vfmt_aenc, VIDEO_HIGHT);
+       media_format_set_video_avg_bps(vfmt_aenc, VIDEO_AVG_BPS);
+       media_format_set_video_max_bps(vfmt_aenc, VIDEO_MAX_BPS);
+
        /* Define audio raw format */
        media_format_create(&afmt_raw);
        if (media_format_set_audio_mime(afmt_raw, MEDIA_FORMAT_PCM) != MEDIA_FORMAT_ERROR_NONE)
@@ -312,6 +330,20 @@ static void create_formats(void)
 
        media_format_set_audio_channel(afmt_encoded, AUDIO_CHANNEL);
        media_format_set_audio_samplerate(afmt_encoded, AUDIO_SAMPLERATE);
+
+       /* Define audio encoded format for adaptive stream */
+       media_format_create(&afmt_aenc);
+       if (media_format_set_audio_mime(afmt_aenc, MEDIA_FORMAT_AAC) != MEDIA_FORMAT_ERROR_NONE)
+               g_print("media_format_set_audio_mime failed!");
+
+       media_format_set_audio_channel(afmt_aenc, AUDIO_CHANNEL);
+       media_format_set_audio_samplerate(afmt_aenc, AUDIO_SAMPLERATE);
+       media_format_set_audio_aac_type(afmt_aenc, TRUE);
+
+       /* Define mpegts stream format */
+       media_format_create(&tsfmt);
+       if (media_format_set_container_mime(tsfmt, MEDIA_FORMAT_CONTAINER_MPEG2TS) != MEDIA_FORMAT_ERROR_NONE)
+               g_print("media_format_set_container_mime failed!");
 }
 
 static void set_rtp_params(media_streamer_node_h rtp_node, const char *ip, int video_port, int audio_port, gboolean port_reverse)
@@ -640,6 +672,71 @@ static media_streamer_node_h _create_rtp(int video_port, int audio_port, gboolea
        return rtp_bin;
 }
 
+static void _create_adaptive_playing()
+{
+       g_print("\n _create_adaptive_playing \n");
+       media_streamer_node_h adaptive_src = NULL;
+       media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE, &adaptive_src);
+       media_streamer_node_set_param(adaptive_src, MEDIA_STREAMER_PARAM_URI, g_uri);
+       media_streamer_node_add(current_media_streamer, adaptive_src);
+       APPEND_NODE(adaptive_src);
+
+       /*********************** videosink *********************************** */
+       media_streamer_node_h video_sink = NULL;
+       media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY, &video_sink);
+       media_streamer_node_add(current_media_streamer, video_sink);
+       APPEND_NODE(video_sink);
+
+       /*********************** audiosink *********************************** */
+       media_streamer_node_h audio_sink = NULL;
+       media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_AUDIO, &audio_sink);
+       media_streamer_node_add(current_media_streamer, audio_sink);
+       APPEND_NODE(audio_sink);
+}
+
+static void _create_adaptive_playing_manual()
+{
+       g_print("\n _create_adaptive_playing_manual \n");
+       media_streamer_node_h adaptive_src = NULL;
+       media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_ADAPTIVE, &adaptive_src);
+       media_streamer_node_set_param(adaptive_src, MEDIA_STREAMER_PARAM_URI, g_uri);
+       media_streamer_node_add(current_media_streamer, adaptive_src);
+       APPEND_NODE(adaptive_src);
+
+       media_streamer_node_h ts_demux = NULL;
+       media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_DEMUXER, tsfmt, NULL, &ts_demux);
+       media_streamer_node_add(current_media_streamer, ts_demux);
+       APPEND_NODE(ts_demux);
+
+       media_streamer_node_h video_dec = NULL;
+       media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER, vfmt_aenc, vfmt_raw, &video_dec);
+       media_streamer_node_add(current_media_streamer, video_dec);
+       APPEND_NODE(video_dec);
+
+       media_streamer_node_h audio_dec = NULL;
+       media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER, afmt_aenc, afmt_raw, &audio_dec);
+       media_streamer_node_add(current_media_streamer, audio_dec);
+       APPEND_NODE(audio_dec);
+
+       /*********************** videosink *********************************** */
+       media_streamer_node_h video_sink = NULL;
+       media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY, &video_sink);
+       media_streamer_node_add(current_media_streamer, video_sink);
+       APPEND_NODE(video_sink);
+
+       /*********************** audiosink *********************************** */
+       media_streamer_node_h audio_sink = NULL;
+       media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_AUDIO, &audio_sink);
+       media_streamer_node_add(current_media_streamer, audio_sink);
+       APPEND_NODE(audio_sink);
+
+       /********************** link nodes *********************************** */
+       media_streamer_node_link(adaptive_src, "src", ts_demux, "sink");
+       media_streamer_node_link(video_dec, "src", video_sink, "sink");
+       media_streamer_node_link(audio_dec, "src", audio_sink, "sink");
+}
+
+
 /* Application source callback */
 static void buffer_status_cb(media_streamer_node_h node, media_streamer_custom_buffer_status_e status, void *user_data)
 {
@@ -842,6 +939,23 @@ static void display_playing_scenario_select_menu(void)
        g_print("====================================================\n");
 }
 
+static void display_adaptive_scenario_select_menu(void)
+{
+       g_print("\n");
+       g_print("====================================================\n");
+       g_print("   media streamer test: Adaptive menu v0.3\n");
+       g_print("----------------------------------------------------\n");
+       g_print("\n");
+       g_print("Please select Adaptive Scenario mode\n");
+       g_print("By default will be used [%d] mode\n", g_scenario_mode);
+       g_print("1. [Server] Create Video http file segment \n");
+       g_print("2. [Client] Adaptive playing auto-plug mode\n");
+       g_print("3. [Client] Adaptive playing manual plug mode\n");
+       g_print("b. back \n");
+       g_print("----------------------------------------------------\n");
+       g_print("====================================================\n");
+}
+
 static void display_preset_menu(void)
 {
        g_print("\n");
@@ -901,6 +1015,7 @@ static void display_main_menu(void)
        g_print("1. Broadcast \n");
        g_print("2. VOIP \n");
        g_print("3. Local Playing \n");
+       g_print("4. Adaptive \n");
        g_print("q. quit \n");
        g_print("----------------------------------------------------\n");
        g_print("====================================================\n");
@@ -925,6 +1040,9 @@ static void display_menu(void)
                case MENU_STATE_PRESET_MENU:
                        display_preset_menu();
                        break;
+               case MENU_STATE_ADAPTIVE_MENU:
+                       display_preset_menu();
+                       break;
                default:
                        g_print("*** Unknown status.\n");
                        break;
@@ -952,6 +1070,9 @@ static void display_menu(void)
                case SUBMENU_STATE_PLAYING_SCENARIO:
                        display_playing_scenario_select_menu();
                        break;
+               case SUBMENU_STATE_ADAPTIVE_SCENARIO:
+                       display_adaptive_scenario_select_menu();
+                       break;
                default:
                        g_print("*** Unknown Submenu state.\n");
                        break;
@@ -1037,6 +1158,22 @@ void run_playing_preset(void)
                g_print("Invalid playing menu preset was selected!");
 }
 
+void run_adaptive_preset(void)
+{
+       create_formats();
+
+       g_print("%s:%d, %d %d %d", __FUNCTION__, __LINE__, g_menu_state, g_sub_menu_state, g_scenario_mode);
+
+       if (g_scenario_mode == SCENARIO_MODE_ADAPTIVE_SERVER)
+               g_print("Adaptive server scenario");
+       else if (g_scenario_mode == SCENARIO_MODE_ADAPTIVE_CLIENT_AUTO)
+               _create_adaptive_playing(); /* temp */
+       else if (g_scenario_mode == SCENARIO_MODE_ADAPTIVE_CLIENT_MANUAL)
+               _create_adaptive_playing_manual(); /* temp */
+       else
+               g_print("Invalid adaptive menu preset was selected!");
+}
+
 void _interpret_main_menu(char *cmd)
 {
        int len = strlen(cmd);
@@ -1048,6 +1185,8 @@ void _interpret_main_menu(char *cmd)
                        g_menu_state = MENU_STATE_VOIP_MENU;
                else if (!strncmp(cmd, "3", len))
                        g_menu_state = MENU_STATE_PLAYING_MENU;
+               else if (!strncmp(cmd, "4", len))
+                       g_menu_state = MENU_STATE_ADAPTIVE_MENU;
                else if (!strncmp(cmd, "q", len))
                        quit();
        } else {
@@ -1112,6 +1251,28 @@ void _interpret_voip_menu(char *cmd)
        }
 }
 
+void _interpret_adaptive_scenario_menu(char *cmd)
+{
+       int len = strlen(cmd);
+
+       if (len == 1) {
+               if (!strncmp(cmd, "1", len)) {
+                       g_scenario_mode = SCENARIO_MODE_ADAPTIVE_SERVER;
+                       g_sub_menu_state = SUBMENU_STATE_GETTING_VIDEOFILE_URI;
+                       return;
+               } else if (!strncmp(cmd, "2", len)) {
+                       g_scenario_mode = SCENARIO_MODE_ADAPTIVE_CLIENT_AUTO;
+                       g_sub_menu_state = SUBMENU_STATE_GETTING_VIDEOFILE_URI;
+                       return;
+               } else if (!strncmp(cmd, "3", len)) {
+                       g_scenario_mode = SCENARIO_MODE_ADAPTIVE_CLIENT_MANUAL;
+                       g_sub_menu_state = SUBMENU_STATE_GETTING_VIDEOFILE_URI;
+                       return;
+               }
+       }
+       g_sub_menu_state = SUBMENU_STATE_UNKNOWN;
+}
+
 void _interpret_playing_scenario_menu(char *cmd)
 {
        int len = strlen(cmd);
@@ -1262,6 +1423,7 @@ void _interpret_getting_uri_menu(char *cmd)
                return;
        }
 
+       g_print("_interpret_getting_uri_menu %d %d %d", g_menu_state, g_sub_menu_state, g_scenario_mode);
        if (g_menu_state == MENU_STATE_PLAYING_MENU) {
                if (g_scenario_mode == SCENARIO_MODE_FILE_SUBTITLE_VIDEO_AUDIO) {
                        g_sub_menu_state = SUBMENU_STATE_GETTING_SUBFILE_URI;
@@ -1274,6 +1436,10 @@ void _interpret_getting_uri_menu(char *cmd)
                        create_formats();
                        _create_file_streaming();
                        _create_rtp(VIDEO_PORT, AUDIO_PORT, FALSE);
+               } else if (g_scenario_mode == SCENARIO_MODE_ADAPTIVE_SERVER ||
+                               g_scenario_mode == SCENARIO_MODE_ADAPTIVE_CLIENT_AUTO ||
+                               g_scenario_mode == SCENARIO_MODE_ADAPTIVE_CLIENT_MANUAL) {
+                       run_adaptive_preset();
                } else {
                        run_preset();
                }
@@ -1320,6 +1486,8 @@ void _interpret_preset_menu(char *cmd)
                        /* call the run_preset function after autoplug mode was selected; */
                        if (g_menu_state == MENU_STATE_PLAYING_MENU)
                                g_sub_menu_state = SUBMENU_STATE_PLAYING_SCENARIO;
+                       else if (g_menu_state == MENU_STATE_ADAPTIVE_MENU)
+                               g_sub_menu_state = SUBMENU_STATE_ADAPTIVE_SCENARIO;
                        else
                                g_sub_menu_state = SUBMENU_STATE_AUTOPLUG;
                } else if (!strncmp(cmd, "3", len)) {
@@ -1372,6 +1540,9 @@ static void interpret_cmd(char *cmd)
                case MENU_STATE_PRESET_MENU:
                        _interpret_preset_menu(cmd);
                        break;
+               case MENU_STATE_ADAPTIVE_MENU:
+                       _interpret_preset_menu(cmd);
+                       break;
                default:
                        g_print("Invalid command\n");
                        return;
@@ -1400,6 +1571,9 @@ static void interpret_cmd(char *cmd)
                case SUBMENU_STATE_PLAYING_SCENARIO:
                        _interpret_playing_scenario_menu(cmd);
                        break;
+               case SUBMENU_STATE_ADAPTIVE_SCENARIO:
+                       _interpret_adaptive_scenario_menu(cmd);
+                       break;
                default:
                        g_print("*** Unknown Submenu state.\n");
                        break;