From: Vyacheslav Valkovoy Date: Thu, 8 Oct 2015 14:13:25 +0000 (+0300) Subject: Added VideoFile / VideoFile + Subtitles / HTTPsource playing Scenarios. X-Git-Tag: submit/tizen/20151014.055942~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7b43a92bc5554cd5f7029f3df18d8b5d0406da01;p=platform%2Fcore%2Fapi%2Fmediastreamer.git Added VideoFile / VideoFile + Subtitles / HTTPsource playing Scenarios. Change-Id: I1775b1f3da09424a2e92299770d25f4c516e9756 Signed-off-by: Vyacheslav Valkovoy --- diff --git a/include/media_streamer_gst.h b/include/media_streamer_gst.h index fb253cc..c664cc7 100755 --- a/include/media_streamer_gst.h +++ b/include/media_streamer_gst.h @@ -28,8 +28,10 @@ #define MEDIA_STREAMER_PAYLOADER_KLASS "Codec/Payloader/Network/RTP" #define MEDIA_STREAMER_RTP_KLASS "Filter/Network/RTP" + #define MEDIA_STREAMER_DEPAYLOADER_KLASS "Depayloader/Network/RTP" #define MEDIA_STREAMER_BIN_KLASS "Generic/Bin" +#define MEDIA_STREAMER_OVERLAY_KLASS "Filter/Editor" #define MEDIA_STREAMER_PARSER_KLASS "Codec/Parser/Converter" #define MEDIA_STREAMER_CONVERTER_KLASS "Filter/Converter" #define MEDIA_STREAMER_DECODER_KLASS "Codec/Decoder" @@ -42,6 +44,14 @@ */ void __ms_generate_dots(GstElement *bin, gchar *name_tag); +/** + * @brief Finds GstElement by klass name. + * + * @since_tizen 3.0 + */ +GstElement *__ms_bin_find_element_by_klass(GstElement *sink_bin, + const gchar *klass_name, const gchar *bin_name); + /** * @brief Creates GstElement by klass name. * @@ -129,7 +139,18 @@ gboolean __ms_element_set_property(GstElement *src_element, gboolean __ms_element_unlink(GstElement *src_element); /** - * @brief Callback function to link decodebin with the sink element at the streamer part. + * @brief Callback function to filter factories while decodebin is searching them. + * + * @since_tizen 3.0 + */ +gint __ms_decodebin_autoplug_select(GstElement *bin, + GstPad *pad, + GstCaps *caps, + GstElementFactory *factory, + gpointer data); + +/** + * @brief Callback function to link decodebin for file playing. * * @since_tizen 3.0 */ @@ -142,6 +163,13 @@ void __decodebin_newpad_streamer_cb(GstElement *decodebin, GstPad *pad, gpointer */ void __decodebin_newpad_cb(GstElement *decodebin, GstPad *pad, gpointer user_data); +/** + * @brief Callback function to link decodebin with the sink element at the client part. + * + * @since_tizen 3.0 + */ +void __decodebin_newpad_client_cb(GstElement *decodebin, GstPad *pad, gpointer user_data); + /** * @brief Creates next element by klass or by properties and links with the previous one. * diff --git a/include/media_streamer_util.h b/include/media_streamer_util.h index e1ffa30..074d3d8 100755 --- a/include/media_streamer_util.h +++ b/include/media_streamer_util.h @@ -114,20 +114,22 @@ typedef struct __media_streamer_ini { #define DEFAULT_VIDEO_SOURCE "ximagesrc" #define DEFAULT_APP_SOURCE "appsrc" #define DEFAULT_AUDIO_SINK "pulsesink" -#define DEFAULT_VIDEO_SINK "autovideosink" +#define DEFAULT_VIDEO_SINK "waylandsink" #define DEFAULT_VIDEO_CONVERT "videoconvert" +#define DEFAULT_TEXT_OVERLAY "textoverlay" #define DEFAULT_AUDIO_CONVERT "audioconvert" #define DEFAULT_AUDIO_RESAMPLE "audioresample" #define DEFAULT_APP_SINK "appsink" /* udp streaming */ #define DEFAULT_UDP_SOURCE "udpsrc" +#define DEFAULT_HTTP_SOURCE "souphttpsrc" #define DEFAULT_UDP_SINK "udpsink" #define DEFAULT_RTP_BIN "rtpbin" /* video format defaults */ -#define DEFAULT_VIDEO_ENCODER "omxh264enc" -#define DEFAULT_VIDEO_DECODER "omxh264dec" +#define DEFAULT_VIDEO_ENCODER "avenc_h263" +#define DEFAULT_VIDEO_DECODER "avdec_h263" #define DEFAULT_VIDEO_PARSER "h263parse" #define DEFAULT_VIDEO_RTPPAY "rtph263pay" #define DEFAULT_VIDEO_RTPDEPAY "rtph263depay" @@ -145,6 +147,7 @@ typedef struct __media_streamer_ini { #define MS_ELEMENT_IS_INPUT(el) g_strrstr(el, "in") #define MS_ELEMENT_IS_AUDIO(el) g_strrstr(el, "audio") #define MS_ELEMENT_IS_VIDEO(el) g_strrstr(el, "video") +#define MS_ELEMENT_IS_TEXT(el) g_strrstr(el, "text") #define MS_ELEMENT_IS_ENCODER(el) g_strrstr(el, "encoder") #define MS_ELEMENT_IS_DECODER(el) g_strrstr(el, "decoder") @@ -236,6 +239,13 @@ gchar *__ms_ini_get_string(dictionary *dict, const char *ini_path, */ const gchar *__ms_convert_mime_to_string(media_format_mimetype_e mime); +/** + * @brief Converts Media Format mime type into rtp media type. + * + * @since_tizen 3.0 + */ +const gchar *__ms_convert_mime_to_rtp_format(media_format_mimetype_e mime); + /** * @brief Converts Caps stream format into Media Format mime type. * diff --git a/src/media_streamer_gst.c b/src/media_streamer_gst.c index 511b2f7..a6132d5 100755 --- a/src/media_streamer_gst.c +++ b/src/media_streamer_gst.c @@ -351,9 +351,9 @@ static void __ms_link_elements_on_pad_added_cb(GstPad *new_pad, GstElement *sink } #endif -static GstElement *__ms_bin_find_element_by_klass(GstElement *sink_bin, - const gchar *klass_name, - const gchar *bin_name) +GstElement *__ms_bin_find_element_by_klass(GstElement *sink_bin, + const gchar *klass_name, + const gchar *bin_name) { GValue elem = G_VALUE_INIT; GstIterator *bin_iterator = gst_bin_iterate_sorted(GST_BIN(sink_bin)); @@ -368,6 +368,7 @@ static GstElement *__ms_bin_find_element_by_klass(GstElement *sink_bin, while (GST_ITERATOR_OK == gst_iterator_next(bin_iterator, &elem)) { found_element = (GstElement *) g_value_get_object(&elem); + const gchar *found_klass = gst_element_factory_get_klass(gst_element_get_factory(found_element)); if (klass_name && g_strrstr(found_klass, klass_name)) { @@ -376,6 +377,7 @@ static GstElement *__ms_bin_find_element_by_klass(GstElement *sink_bin, pad_iterator = gst_element_iterate_sink_pads(found_element); while (GST_ITERATOR_OK == gst_iterator_next(pad_iterator, &element)) { pad = (GstPad *) g_value_get_object(&element); + if (!gst_pad_is_linked(pad)) { unlinked_pad_found = TRUE; } @@ -402,31 +404,33 @@ static GstElement *__ms_bin_find_element_by_klass(GstElement *sink_bin, return found ? found_element : NULL; } -int __ms_get_rank_increase(const char *factory_class) +int __ms_get_rank_increase(const char *factory_name) { gint rank_priority = 20; gint rank_second = 10; + gint rank_skip = -10; gint ret = 0; - if (g_strrstr(factory_class, "Dsp")) + if (g_strrstr(factory_name, "av")) ret = rank_priority; - else if (g_strrstr(factory_class, "HW")) - ret = rank_priority; - else if (g_strrstr(factory_class, "Arm")) + else if (g_strrstr(factory_name, "omx")) ret = rank_second; + else if (g_strrstr(factory_name, "v4l2video")) + ret = rank_skip; return ret; } int __ms_factory_rank_compare(GstPluginFeature *first_feature, GstPluginFeature *second_feature) { - const gchar *class; + const gchar *name; int first_feature_rank_inc=0, second_feature_rank_inc = 0; - class = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(first_feature)); - first_feature_rank_inc = __ms_get_rank_increase(class); - class = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(second_feature)); - second_feature_rank_inc = __ms_get_rank_increase(class); + name = gst_plugin_feature_get_plugin_name(first_feature); + first_feature_rank_inc = __ms_get_rank_increase(name); + + name = gst_plugin_feature_get_plugin_name(second_feature); + second_feature_rank_inc = __ms_get_rank_increase(name); return (gst_plugin_feature_get_rank(second_feature) + second_feature_rank_inc) - (gst_plugin_feature_get_rank(first_feature) + first_feature_rank_inc ); @@ -445,12 +449,11 @@ GstElement *__ms_create_element_by_registry(GstPad *src_pad, const gchar *klass_ GList *factories; const GList *pads; GstElement *next_element = NULL; - GstCaps *new_pad_caps = NULL; - new_pad_caps = gst_pad_query_caps(src_pad, NULL); + GstCaps *new_pad_caps = gst_pad_query_caps(src_pad, NULL); factories = gst_registry_feature_filter(gst_registry_get(), - (GstPluginFeatureFilter)__ms_feature_filter, FALSE, NULL); + (GstPluginFeatureFilter)__ms_feature_filter, FALSE, NULL); factories = g_list_sort(factories, (GCompareFunc)__ms_factory_rank_compare); for(; factories != NULL ; factories = factories->next) { @@ -476,7 +479,7 @@ GstElement *__ms_create_element_by_registry(GstPad *src_pad, const gchar *klass_ intersect_caps = gst_caps_intersect_full(new_pad_caps, static_caps, GST_CAPS_INTERSECT_FIRST); - if (!gst_caps_is_empty(intersect_caps)) { + if ((!gst_caps_is_any(static_caps)) && (!gst_caps_is_empty(intersect_caps))) { if (!next_element) { next_element = __ms_element_create(GST_OBJECT_NAME(factory), NULL); } @@ -486,7 +489,8 @@ GstElement *__ms_create_element_by_registry(GstPad *src_pad, const gchar *klass_ } } } - + gst_caps_unref(new_pad_caps); + gst_plugin_feature_list_free(factories); return next_element; } @@ -500,38 +504,41 @@ GstElement * __ms_link_with_new_element(GstElement *previous_element, GValue element = G_VALUE_INIT; GstPad *sink_pad = NULL; - GstPad *src_pad = NULL; + GstPad *prev_elem_sink_pad = NULL; GstIterator *pad_iterator = NULL; if (next_elem_bin_name) { pad_iterator = gst_element_iterate_sink_pads(new_element); - while (GST_ITERATOR_OK == gst_iterator_next(pad_iterator, &element)) - { + while (GST_ITERATOR_OK == gst_iterator_next(pad_iterator, &element)) { sink_pad = (GstPad *)g_value_get_object(&element); - src_pad = gst_element_get_static_pad(previous_element, "sink"); + prev_elem_sink_pad = gst_element_get_static_pad(previous_element, "sink"); - new_pad_caps = gst_pad_query_caps(src_pad, 0); + new_pad_caps = gst_pad_query_caps(prev_elem_sink_pad, 0); new_pad_struct = gst_caps_get_structure(new_pad_caps, 0); new_pad_type = gst_structure_get_name(new_pad_struct); if (!gst_pad_is_linked(sink_pad)) { if(!strncmp(new_pad_type,GST_PAD_NAME(sink_pad), COMPARED_NUMBER)) { if (gst_element_link_pads_filtered(previous_element, "src", new_element, - GST_PAD_NAME(sink_pad), NULL)) { + GST_PAD_NAME(sink_pad), NULL)) { ms_info("Succeeded to link [%s] -> [%s]\n", - GST_ELEMENT_NAME(previous_element), - GST_ELEMENT_NAME(new_element)); + GST_ELEMENT_NAME(previous_element), + GST_ELEMENT_NAME(new_element)); } else { ms_error("Failed to link [%s] -> [%s]\n", - GST_ELEMENT_NAME(previous_element), - GST_ELEMENT_NAME(new_element)); + GST_ELEMENT_NAME(previous_element), + GST_ELEMENT_NAME(new_element)); } } } + MS_SAFE_UNREF(prev_elem_sink_pad); + gst_caps_unref(new_pad_caps); g_value_reset(&element); + } g_value_unset(&element); gst_iterator_free(pad_iterator); + } else { gboolean ret = gst_element_link_pads_filtered(previous_element, NULL, new_element, NULL, NULL); @@ -543,6 +550,13 @@ GstElement * __ms_link_with_new_element(GstElement *previous_element, ms_error("Failed to link [%s] and [%s] \n", GST_ELEMENT_NAME(previous_element), GST_ELEMENT_NAME(new_element)); + + /*Remove created element*/ + if (gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(new_element)), new_element)) { + ms_debug("Element removed from bin successfully "); + } else { + ms_error("Element was not removed from bin"); + } new_element = NULL; } } @@ -558,20 +572,10 @@ GstElement *__ms_combine_next_element(GstElement *previous_element, GstElement *found_element = NULL; GstElement *parent_element = NULL; - char *plugin_name = NULL; - char *format_prefix = NULL; - - media_format_h vfmt_encoded = NULL; - media_format_create(&vfmt_encoded); - if (media_format_set_video_mime(vfmt_encoded, MEDIA_FORMAT_H264_SP) != MEDIA_FORMAT_ERROR_NONE) { - ms_error("media_format_set_video_mime failed!\n"); + if(!previous_element) { + return NULL; } - media_format_set_video_width(vfmt_encoded, 1280); - media_format_set_video_height(vfmt_encoded, 720); - media_format_set_video_avg_bps(vfmt_encoded, 1031); - media_format_set_video_max_bps(vfmt_encoded, 2063); - parent_element = (GstElement *)gst_element_get_parent(previous_element); /*Look for node created by user*/ @@ -590,35 +594,20 @@ GstElement *__ms_combine_next_element(GstElement *previous_element, return NULL; /* Create element by element name*/ - } else if(!found_element && !next_elem_klass_name) { + } else if(!found_element && !next_elem_klass_name && default_element) { found_element = __ms_element_create(default_element, NULL); /* Create element by predefined format element type*/ - } else if(!found_element && element_type) { + } else if(!found_element && MS_ELEMENT_IS_ENCODER(next_elem_bin_name)) { dictionary *dict = NULL; - media_format_mimetype_e mime; - - if (MEDIA_FORMAT_ERROR_NONE != media_format_get_video_info(vfmt_encoded, &mime, - NULL, NULL, NULL, NULL)) { - media_format_get_audio_info(vfmt_encoded, &mime, NULL, NULL, NULL, NULL); - } __ms_load_ini_dictionary(&dict); - format_prefix = g_strdup_printf("%s:%s", __ms_convert_mime_to_string(mime), element_type); - plugin_name = __ms_ini_get_string(dict, format_prefix, default_element); - - if (MS_ELEMENT_IS_ENCODER(next_elem_bin_name)) { - if (MS_ELEMENT_IS_VIDEO(next_elem_bin_name)) { - found_element = __ms_video_encoder_element_create(dict, mime); - } else if (MS_ELEMENT_IS_AUDIO(next_elem_bin_name)) { - found_element = __ms_audio_encoder_element_create(); - } - } else if (MS_ELEMENT_IS_DECODER(next_elem_bin_name)) { - if (MS_ELEMENT_IS_VIDEO(next_elem_bin_name)) { - found_element = __ms_video_decoder_element_create(dict, mime); - } + if (MS_ELEMENT_IS_VIDEO(next_elem_bin_name)) { + found_element = __ms_video_encoder_element_create(dict, MEDIA_FORMAT_H263); + } else { + found_element = __ms_audio_encoder_element_create(); } __ms_destroy_ini_dictionary(dict); @@ -631,27 +620,70 @@ GstElement *__ms_combine_next_element(GstElement *previous_element, } /*Add created element*/ - if (found_element && gst_bin_add(GST_BIN(parent_element), found_element)) { - ms_debug("Element [%s] added into [%s] bin", - GST_ELEMENT_NAME(found_element), - GST_ELEMENT_NAME(parent_element)); + if (found_element) { + if (gst_bin_add(GST_BIN(parent_element), found_element)) { + ms_debug("Element [%s] added into [%s] bin", + GST_ELEMENT_NAME(found_element), + GST_ELEMENT_NAME(parent_element)); + + gst_element_sync_state_with_parent(found_element); + previous_element = __ms_link_with_new_element(previous_element, found_element, NULL); + __ms_generate_dots(parent_element, GST_ELEMENT_NAME(found_element)); + } else { + ms_error("Element [%s] was not added into [%s] bin", + GST_ELEMENT_NAME(found_element), + GST_ELEMENT_NAME(parent_element)); + MS_SAFE_UNREF(found_element); + found_element = NULL; + } } else { - ms_error("Element [%s] was not added into [%s] bin", - GST_ELEMENT_NAME(found_element), - GST_ELEMENT_NAME(parent_element)); + ms_error("Could not find compatible element to link [%s]",GST_ELEMENT_NAME(previous_element)); } - previous_element = __ms_link_with_new_element(previous_element, found_element, NULL); } - gst_element_sync_state_with_parent(found_element); - __ms_generate_dots(parent_element, GST_ELEMENT_NAME(found_element)); - - MS_SAFE_FREE(plugin_name); - MS_SAFE_FREE(format_prefix); + MS_SAFE_UNREF(parent_element); return found_element; } + gint __ms_decodebin_autoplug_select(GstElement *bin, + GstPad *pad, + GstCaps *caps, + GstElementFactory *factory, + gpointer data) +{ + /* NOTE : GstAutoplugSelectResult is defined in gstplay-enum.h but not exposed */ + typedef enum { + GST_AUTOPLUG_SELECT_TRY, + GST_AUTOPLUG_SELECT_EXPOSE, + GST_AUTOPLUG_SELECT_SKIP + } GstAutoplugSelectResult; + + gchar *factory_name = NULL; + const gchar *klass = NULL; + + factory_name = GST_OBJECT_NAME(factory); + klass = gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS); + + ms_debug("Decodebin: found new element [%s] to link [%s]\n\n", factory_name, klass); + + if ((g_strrstr(klass, "Codec/Decoder/Video"))) { + + /* Skip Video4Linux decoders */ + if (g_strrstr(factory_name, "v4l2video")) { + ms_debug("Decodebin: skipping [%s] by not required\n", factory_name); + return GST_AUTOPLUG_SELECT_SKIP; + } + + /* Skip OMX HW decoders */ + if (g_strrstr(factory_name, "omx")) { + ms_debug("Decodebin: skipping [%s] by disabled", factory_name); + return GST_AUTOPLUG_SELECT_SKIP; + } + } + + return GST_AUTOPLUG_SELECT_TRY; +} void __decodebin_newpad_streamer_cb(GstElement *decodebin, GstPad *new_pad, gpointer user_data) { @@ -686,6 +718,7 @@ void __decodebin_newpad_streamer_cb(GstElement *decodebin, GstPad *new_pad, gpoi found_element = __ms_combine_next_element(found_element, MEDIA_STREAMER_PAYLOADER_KLASS, NULL, NULL, NULL); found_element = __ms_combine_next_element(found_element, MEDIA_STREAMER_BIN_KLASS, "rtp_container", NULL, NULL); } + gst_caps_unref(new_pad_caps); } void __decodebin_newpad_cb(GstElement *decodebin, GstPad *new_pad, gpointer user_data) @@ -694,11 +727,14 @@ void __decodebin_newpad_cb(GstElement *decodebin, GstPad *new_pad, gpointer user ms_retm_if(ms_streamer == NULL, "Handle is NULL"); GstElement *found_element = NULL; + GstElement *queue_element = NULL; GstCaps *new_pad_caps = NULL; GstStructure *new_pad_struct = NULL; const gchar *new_pad_type = NULL; + GstElement *sink_bin = NULL; + ms_info("Received new pad '%s' from [%s]", GST_PAD_NAME(new_pad), GST_ELEMENT_NAME(decodebin)); /* Check the new pad's type */ @@ -706,17 +742,120 @@ void __decodebin_newpad_cb(GstElement *decodebin, GstPad *new_pad, gpointer user new_pad_struct = gst_caps_get_structure(new_pad_caps, 0); new_pad_type = gst_structure_get_name(new_pad_struct); - if(MS_ELEMENT_IS_VIDEO(new_pad_type)) { - found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_VIDEO_CONVERT); - } else if (MS_ELEMENT_IS_AUDIO(new_pad_type)) { + if (MS_ELEMENT_IS_AUDIO(new_pad_type)) { + sink_bin = ms_streamer->sink_audio_bin; found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_AUDIO_CONVERT); + } else if (MS_ELEMENT_IS_VIDEO(new_pad_type)) { + sink_bin = ms_streamer->sink_video_bin; + found_element = __ms_bin_find_element_by_klass(GST_ELEMENT_PARENT(decodebin), MEDIA_STREAMER_OVERLAY_KLASS, NULL); + if (!found_element) { + found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_VIDEO_CONVERT); + } else { + found_element = __ms_combine_next_element(decodebin, MEDIA_STREAMER_OVERLAY_KLASS, NULL, NULL, NULL); + return; + } + } else if (MS_ELEMENT_IS_TEXT(new_pad_type)) { + sink_bin = ms_streamer->sink_video_bin; + found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_TEXT_OVERLAY); + found_element = __ms_combine_next_element(found_element, NULL, NULL, NULL, DEFAULT_VIDEO_CONVERT); + } else { + ms_error("Pad type of the element is invalid"); + return; + } + + /* Check if sink bin has been added to pipeline before */ + if (sink_bin && gst_object_get_parent(GST_OBJECT(sink_bin)) == NULL) { + + /*Add created sink bin*/ + if (gst_bin_add(GST_BIN(ms_streamer->pipeline), sink_bin)) { + ms_debug("Bin [%s] added into [%s] bin", + GST_ELEMENT_NAME(sink_bin), + GST_ELEMENT_NAME(ms_streamer->pipeline)); + + gst_element_sync_state_with_parent(sink_bin); + } else { + ms_error("Bin [%s] was not added into [%s] bin", + GST_ELEMENT_NAME(sink_bin), + GST_ELEMENT_NAME(ms_streamer->pipeline)); + } + + queue_element = __ms_element_create(DEFAULT_QUEUE, NULL); + + /*Add created queue element*/ + if (gst_bin_add(GST_BIN(sink_bin), queue_element)) { + ms_debug("Element [%s] added into [%s] bin", + GST_ELEMENT_NAME(queue_element), + GST_ELEMENT_NAME(sink_bin)); + + gst_element_sync_state_with_parent(queue_element); + found_element = __ms_link_with_new_element(found_element, queue_element, NULL); + __ms_generate_dots(ms_streamer->pipeline, GST_ELEMENT_NAME(found_element)); + } else { + ms_error("Element [%s] was not added into [%s] bin", + GST_ELEMENT_NAME(queue_element), + GST_ELEMENT_NAME(sink_bin)); + } } /* Getting Sink */ found_element = __ms_combine_next_element(found_element, MEDIA_STREAMER_SINK_KLASS, NULL, NULL, NULL); + + if(!found_element) { + ms_error("Could not link to sink element \n"); + } + + gst_caps_unref(new_pad_caps); __ms_generate_dots(ms_streamer->pipeline, "pipeline_linked"); } +void __decodebin_newpad_client_cb(GstElement *decodebin, GstPad *new_pad, gpointer user_data) +{ + media_streamer_node_s *ms_node = (media_streamer_node_s *)user_data; + ms_retm_if(ms_node == NULL, "Handle is NULL"); + + GstElement *found_element = NULL; + + GstCaps *new_pad_caps = NULL; + GstStructure *new_pad_struct = NULL; + const gchar *new_pad_type = NULL; + + ms_info("Received new pad '%s' from [%s]", GST_PAD_NAME(new_pad), GST_ELEMENT_NAME(decodebin)); + + /* Check the new pad's type */ + new_pad_caps = gst_pad_query_caps(new_pad, 0); + new_pad_struct = gst_caps_get_structure(new_pad_caps, 0); + new_pad_type = gst_structure_get_name(new_pad_struct); + + if (MS_ELEMENT_IS_AUDIO(new_pad_type)) { + found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_AUDIO_CONVERT); + } else if (MS_ELEMENT_IS_VIDEO(new_pad_type)) { + + found_element = __ms_bin_find_element_by_klass(GST_ELEMENT_PARENT(decodebin), MEDIA_STREAMER_OVERLAY_KLASS, NULL); + if (!found_element) { + found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_VIDEO_CONVERT); + } else { + found_element = __ms_combine_next_element(decodebin, MEDIA_STREAMER_OVERLAY_KLASS, NULL, NULL, NULL); + return; + } + } else if (MS_ELEMENT_IS_TEXT(new_pad_type)) { + + found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_TEXT_OVERLAY); + found_element = __ms_combine_next_element(found_element, NULL, NULL, NULL, DEFAULT_VIDEO_CONVERT); + } + else { + ms_error("Pad type of the element is invalid"); + return; + } + + /* Getting Sink */ + found_element = __ms_combine_next_element(found_element, MEDIA_STREAMER_SINK_KLASS, NULL, NULL, NULL); + + if(!found_element) { + ms_error("Could not link to sink element \n"); + } + gst_caps_unref(new_pad_caps); +} + static gboolean __ms_sink_bin_prepare(media_streamer_node_s *ms_node, GstElement *sink_bin, GstPad *source_pad) { @@ -731,7 +870,7 @@ static gboolean __ms_sink_bin_prepare(media_streamer_node_s *ms_node, /* Getting Depayloader */ found_element = __ms_bin_find_element_by_klass(sink_bin, MEDIA_STREAMER_DEPAYLOADER_KLASS, - MEDIA_STREAMER_NODE_TYPE_NONE); + MEDIA_STREAMER_NODE_TYPE_NONE); if (!found_element) { found_element = __ms_create_element_by_registry(source_pad, MEDIA_STREAMER_DEPAYLOADER_KLASS); @@ -748,19 +887,23 @@ static gboolean __ms_sink_bin_prepare(media_streamer_node_s *ms_node, previous_element = found_element; src_pad = gst_element_get_static_pad(found_element, "src"); - __ms_add_ghostpad(found_element, "sink", sink_bin, "sink"); - previous_element = __ms_combine_next_element(previous_element, NULL, NULL, NULL, DEFAULT_QUEUE); - /* Getting Decodebin */ decodebin_usage = ms_node->parent_streamer->ini.use_decodebin; found_element = __ms_bin_find_element_by_klass(sink_bin, MEDIA_STREAMER_BIN_KLASS, MEDIA_STREAMER_NODE_TYPE_NONE); if (!found_element) { if (decodebin_usage) { - previous_element = __ms_combine_next_element(previous_element, MEDIA_STREAMER_BIN_KLASS, NULL, NULL, NULL); - g_signal_connect(previous_element, "pad-added", G_CALLBACK(__decodebin_newpad_cb), (gpointer )ms_node); + + found_element = __ms_element_create("decodebin", NULL); + gst_bin_add_many((GstBin *)sink_bin, found_element, NULL); + gst_element_sync_state_with_parent(found_element); + g_signal_connect(found_element, "pad-added", G_CALLBACK(__decodebin_newpad_client_cb), (gpointer )ms_node); + g_signal_connect(found_element, "autoplug-select", G_CALLBACK(__ms_decodebin_autoplug_select), NULL); + previous_element = __ms_link_with_new_element(previous_element, found_element, NULL); + __ms_element_set_state(found_element, GST_STATE_PLAYING); + } else { src_pad = gst_element_get_static_pad(previous_element, "src"); new_pad_caps = gst_pad_query_caps(src_pad, 0); @@ -785,7 +928,7 @@ static gboolean __ms_sink_bin_prepare(media_streamer_node_s *ms_node, } else { /* If decode element was added but not linked yet */ - if (!gst_pad_is_linked(src_pad)) { + if (!gst_pad_is_linked(gst_element_get_static_pad(found_element, "sink"))) { previous_element = __ms_link_with_new_element(previous_element, found_element, NULL); } else { @@ -828,6 +971,9 @@ static void __ms_rtpbin_pad_added_cb(GstElement *src, GstPad *new_pad, gpointer src_pad_caps = gst_pad_query_caps(target_pad, NULL); if (ms_node->parent_streamer && !gst_caps_is_any(src_pad_caps)) { + + g_mutex_lock(&ms_node->parent_streamer->mutex_lock); + gchar *source_pad_name = NULL; GstElement *sink_bin = NULL; GstStructure *src_pad_struct = NULL; @@ -849,30 +995,32 @@ static void __ms_rtpbin_pad_added_cb(GstElement *src, GstPad *new_pad, gpointer gst_ghost_pad_set_target(GST_GHOST_PAD(source_pad), new_pad); gst_pad_set_active(source_pad, TRUE); - g_mutex_lock(&ms_node->parent_streamer->mutex_lock); if (__ms_sink_bin_prepare(ms_node, sink_bin, source_pad)) { + gboolean add_ret = TRUE; if (gst_object_get_parent(GST_OBJECT(sink_bin)) == NULL) { - gst_bin_add(GST_BIN(ms_node->parent_streamer->pipeline), sink_bin); + add_ret = gst_bin_add(GST_BIN(ms_node->parent_streamer->pipeline), sink_bin); } - gst_element_sync_state_with_parent(sink_bin); + if(add_ret) { + gst_element_sync_state_with_parent(sink_bin); - if (gst_element_link_pads(ms_node->gst_element, source_pad_name, sink_bin, "sink")) { - __ms_element_set_state(ms_node->gst_element, GST_STATE_PLAYING); - __ms_generate_dots(ms_node->parent_streamer->pipeline, "playing"); - } else { - ms_error("Failed to link [rtp_containeer].[%s] and [sink_bin].[sink]\n", source_pad_name); + if (gst_element_link_pads(ms_node->gst_element, source_pad_name, sink_bin, "sink")) { + __ms_element_set_state(ms_node->gst_element, GST_STATE_PLAYING); + __ms_generate_dots(ms_node->parent_streamer->pipeline, "playing"); + } else { + ms_error("Failed to link [rtp_containeer].[%s] and [sink_bin].[sink]\n", source_pad_name); + } } } else { ms_error("Failed to prepare sink_bin for pad type [%s]\n", src_pad_type); } - g_mutex_unlock(&ms_node->parent_streamer->mutex_lock); - MS_SAFE_UNREF(source_pad); MS_SAFE_GFREE(source_pad_name); } + g_mutex_unlock(&ms_node->parent_streamer->mutex_lock); + } else { ms_debug("Node doesn`t have parent streamer or caps media type\n"); } @@ -1083,7 +1231,12 @@ GstElement *__ms_rtp_element_create(media_streamer_node_s *ms_node) ms_retvm_if(!rtp_container || !rtp_elem, (GstElement *)NULL, "Error: creating elements for rtp container"); - gst_bin_add(GST_BIN(rtp_container), rtp_elem); + if(!gst_bin_add(GST_BIN(rtp_container), rtp_elem)) { + MS_SAFE_UNREF(rtp_container); + MS_SAFE_UNREF(rtp_elem); + return NULL; + } + g_signal_connect(rtp_elem, "pad-added", G_CALLBACK(__ms_rtpbin_pad_added_cb), ms_node); return rtp_container; @@ -1213,6 +1366,10 @@ int __ms_add_node_into_bin(media_streamer_s *ms_streamer, media_streamer_node_s gst_ret = gst_bin_add(GST_BIN(ms_streamer->topology_bin), ms_node->gst_element); bin_name = g_strdup(MEDIA_STREAMER_TOPOLOGY_BIN_NAME); break; + case MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER: + gst_ret = gst_bin_add(GST_BIN(ms_streamer->sink_video_bin), ms_node->gst_element); + bin_name = g_strdup(MEDIA_STREAMER_VIDEO_SINK_BIN_NAME); + break; case MEDIA_STREAMER_NODE_TYPE_VIDEO_DEPAY: gst_ret = gst_bin_add(GST_BIN(ms_streamer->sink_video_bin), ms_node->gst_element); bin_name = g_strdup(MEDIA_STREAMER_VIDEO_SINK_BIN_NAME); @@ -1573,7 +1730,9 @@ int __ms_element_set_fmt(media_streamer_node_s *node, const char *pad_name, medi if (node->type == MEDIA_STREAMER_NODE_TYPE_RTP) { /* It is needed to set 'application/x-rtp' for audio and video udpsrc*/ media_format_mimetype_e mime; + int audio_channels, audio_samplerate; GstElement *rtp_elem, *rtcp_elem; + gchar *rtp_caps_str = NULL; /*Check if it is a valid pad*/ GstPad *pad = gst_element_get_static_pad(node->gst_element, pad_name); @@ -1585,15 +1744,18 @@ int __ms_element_set_fmt(media_streamer_node_s *node, const char *pad_name, medi if (MEDIA_FORMAT_ERROR_NONE == media_format_get_video_info(fmt, &mime, NULL, NULL, NULL, NULL)) { __ms_get_rtp_elements(node, &rtp_elem, &rtcp_elem, "video", "in", FALSE); - caps = gst_caps_from_string("application/x-rtp,media=video,clock-rate=90000,encoding-name=H264"); + rtp_caps_str = g_strdup_printf("application/x-rtp,media=video,clock-rate=90000,encoding-name=%s", + __ms_convert_mime_to_rtp_format(mime)); + caps = gst_caps_from_string(rtp_caps_str); ms_retvm_if(caps == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Fail creating caps from fmt."); obj = __ms_get_property_owner(rtp_elem, "caps", &value); - } else if (MEDIA_FORMAT_ERROR_NONE == media_format_get_audio_info(fmt, &mime, NULL, NULL, NULL, NULL)) { + } else if (MEDIA_FORMAT_ERROR_NONE == media_format_get_audio_info(fmt, &mime, &audio_channels, &audio_samplerate, NULL, NULL)) { __ms_get_rtp_elements(node, &rtp_elem, &rtcp_elem, "audio", "in", FALSE); - caps = gst_caps_from_string("application/x-rtp,media=audio,clock-rate=44100,encoding-name=L16," - "encoding-params=1,channels=1,payload=96"); + rtp_caps_str = g_strdup_printf("application/x-rtp,media=audio,clock-rate=%d,encoding-name=%s,channels=%d,payload=96", + audio_samplerate, __ms_convert_mime_to_rtp_format(mime), audio_channels); + caps = gst_caps_from_string(rtp_caps_str); ms_retvm_if(caps == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Fail creating caps from fmt."); obj = __ms_get_property_owner(rtp_elem, "caps", &value); @@ -1602,6 +1764,7 @@ int __ms_element_set_fmt(media_streamer_node_s *node, const char *pad_name, medi return MEDIA_STREAMER_ERROR_INVALID_PARAMETER; } + MS_SAFE_GFREE(rtp_caps_str); MS_SAFE_UNREF(pad); } else { caps = __ms_create_caps_from_fmt(fmt); diff --git a/src/media_streamer_node.c b/src/media_streamer_node.c index e37bd6f..cb4c07e 100755 --- a/src/media_streamer_node.c +++ b/src/media_streamer_node.c @@ -161,7 +161,8 @@ int __ms_node_create(media_streamer_node_s *node, dec_use = iniparser_getboolean(dict, "general:use decodebin", DEFAULT_USE_DECODEBIN); if (dec_use) { node->gst_element = __ms_element_create("decodebin", NULL); - g_signal_connect(node->gst_element, "pad-added", G_CALLBACK (__decodebin_newpad_cb), (gpointer)node); + g_signal_connect(node->gst_element, "pad-added", G_CALLBACK(__decodebin_newpad_client_cb), (gpointer )node); + g_signal_connect(node->gst_element, "autoplug-select", G_CALLBACK(__ms_decodebin_autoplug_select), NULL); } else { format_prefix = g_strdup_printf("%s:decoder", __ms_convert_mime_to_string(mime)); plugin_name = __ms_ini_get_string(dict, @@ -284,7 +285,7 @@ int __ms_src_node_create(media_streamer_node_s *node) node->gst_element = __ms_element_create(DEFAULT_UDP_SOURCE, NULL); break; case MEDIA_STREAMER_NODE_SRC_TYPE_HTTP: - ms_error("Error: not implemented yet"); + node->gst_element = __ms_element_create(DEFAULT_HTTP_SOURCE, NULL); break; case MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA: plugin_name = __ms_ini_get_string(dict, @@ -512,7 +513,13 @@ int __ms_autoplug_prepare(media_streamer_s *ms_streamer) gst_bin_add_many((GstBin *)ms_streamer->topology_bin, found_element, NULL); gst_element_sync_state_with_parent(found_element); - g_signal_connect(found_element, "pad-added", G_CALLBACK (__decodebin_newpad_streamer_cb), ms_streamer); + + if(__ms_bin_find_element_by_klass(ms_streamer->topology_bin,MEDIA_STREAMER_BIN_KLASS, "rtp_container")) { + g_signal_connect(found_element, "pad-added", G_CALLBACK (__decodebin_newpad_streamer_cb), ms_streamer); + } else { + g_signal_connect(found_element, "pad-added", G_CALLBACK (__decodebin_newpad_cb), ms_streamer); + } + g_signal_connect(found_element, "autoplug-select", G_CALLBACK(__ms_decodebin_autoplug_select), NULL); found_element = __ms_link_with_new_element(unlinked_element, found_element, NULL); __ms_generate_dots(ms_streamer->pipeline, GST_ELEMENT_NAME(found_element)); @@ -792,4 +799,4 @@ int __ms_node_write_param_into_value(media_streamer_node_s *node, const char *pa *param_value = string_val; return MEDIA_STREAMER_ERROR_NONE; -} +} \ No newline at end of file diff --git a/src/media_streamer_util.c b/src/media_streamer_util.c index 201a92f..bac167f 100755 --- a/src/media_streamer_util.c +++ b/src/media_streamer_util.c @@ -192,7 +192,27 @@ const gchar *__ms_convert_mime_to_string(media_format_mimetype_e mime) default: ms_error("Invalid or Unsupported media format [%d].", mime); return NULL; - break; + } + +} + +const gchar *__ms_convert_mime_to_rtp_format(media_format_mimetype_e mime) +{ + switch (mime) { + case MEDIA_FORMAT_I420: + case MEDIA_FORMAT_YV12: + return "RAW"; + case MEDIA_FORMAT_H263: + return "H263"; + case MEDIA_FORMAT_H264_HP: + case MEDIA_FORMAT_H264_MP: + case MEDIA_FORMAT_H264_SP: + return "H264"; + case MEDIA_FORMAT_PCM: + return "L16"; + default: + ms_error("Invalid or Unsupported media format [%d].", mime); + return NULL; } } diff --git a/test/media_streamer_test.c b/test/media_streamer_test.c index d14b5e4..48c16f6 100755 --- a/test/media_streamer_test.c +++ b/test/media_streamer_test.c @@ -28,15 +28,18 @@ typedef enum { MENU_STATE_MAIN_MENU, MENU_STATE_BROADCAST_MENU, MENU_STATE_VOIP_MENU, + MENU_STATE_PLAYING_MENU, MENU_STATE_PRESET_MENU } menu_state_e; typedef enum { SUBMENU_STATE_UNKNOWN, SUBMENU_STATE_GETTING_IP, - SUBMENU_STATE_GETTING_URI, + SUBMENU_STATE_GETTING_VIDEOFILE_URI, + SUBMENU_STATE_GETTING_SUBFILE_URI, SUBMENU_STATE_AUTOPLUG, SUBMENU_STATE_SCENARIO, + SUBMENU_STATE_PLAYING_SCENARIO, SUBMENU_STATE_FORMAT } submenu_state_e; @@ -64,7 +67,9 @@ typedef enum SCENARIO_MODE_VIDEOTEST_SCREEN, SCENARIO_MODE_AUDIOTEST_PHONE, SCENARIO_MODE_TEST_VIDEO_AUDIO, - SCENARIO_MODE_FILESRC_VIDEO_AUDIO, + SCENARIO_MODE_FILE_VIDEO_AUDIO, + SCENARIO_MODE_FILE_SUBTITLE_VIDEO_AUDIO, + SCENARIO_MODE_HTTP_VIDEO_AUDIO, SCENARIO_MODE_APPSRC_APPSINK } scenario_mode_e; @@ -90,6 +95,7 @@ GMainLoop *g_loop; gchar *g_broadcast_address = NULL; gchar *g_uri = NULL; +gchar *g_sub_uri = NULL; menu_state_e g_menu_state = MENU_STATE_MAIN_MENU; submenu_state_e g_sub_menu_state = SUBMENU_STATE_UNKNOWN; preset_type_e g_menu_preset = PRESET_UNKNOWN; @@ -99,7 +105,6 @@ gboolean g_autoplug_mode = FALSE; gboolean g_video_is_on = FALSE; gboolean g_audio_is_on = FALSE; - media_format_h vfmt_raw = NULL; media_format_h vfmt_encoded = NULL; media_format_h afmt_raw = NULL; @@ -115,28 +120,26 @@ static void streamer_error_cb(media_streamer_h streamer, g_print("Media Streamer posted error [%d] \n", error); } -static gboolean _create(media_streamer_h *streamer) +static void _create(media_streamer_h *streamer) { g_print("== create \n"); int ret = MEDIA_STREAMER_ERROR_NONE; if (*streamer != NULL) { - return TRUE; + return; } ret = media_streamer_create(streamer); if (ret != MEDIA_STREAMER_ERROR_NONE) { g_print("Fail to create media streamer"); - return FALSE; + return; } media_streamer_set_error_cb(*streamer, streamer_error_cb, NULL); - - return TRUE; } -static gboolean _prepare(void) +static void _prepare(void) { g_print("== prepare \n"); int ret = MEDIA_STREAMER_ERROR_NONE; @@ -144,14 +147,12 @@ static gboolean _prepare(void) ret = media_streamer_prepare(current_media_streamer); if (ret != MEDIA_STREAMER_ERROR_NONE) { g_print("Fail to prepare media streamer"); - return FALSE; + return; } g_print("== success prepare \n"); - - return TRUE; } -static gboolean _unprepare(void) +static void _unprepare(void) { g_print("== unprepare \n"); int ret = MEDIA_STREAMER_ERROR_NONE; @@ -159,14 +160,12 @@ static gboolean _unprepare(void) ret = media_streamer_unprepare(current_media_streamer); if (ret != MEDIA_STREAMER_ERROR_NONE) { g_print("Fail to unprepare media streamer"); - return FALSE; + return; } g_print("== success unprepare \n"); - - return TRUE; } -static gboolean _play() +static void _play() { g_print("== play \n"); int ret = MEDIA_STREAMER_ERROR_NONE; @@ -174,14 +173,12 @@ static gboolean _play() ret = media_streamer_play(current_media_streamer); if (ret != MEDIA_STREAMER_ERROR_NONE) { g_print("Fail to play media streamer"); - return FALSE; + return; } g_print("== success play \n"); - - return TRUE; } -static gboolean _pause() +static void _pause() { g_print("== pause \n"); int ret = MEDIA_STREAMER_ERROR_NONE; @@ -189,14 +186,12 @@ static gboolean _pause() ret = media_streamer_pause(current_media_streamer); if (ret != MEDIA_STREAMER_ERROR_NONE) { g_print("Fail to pause media streamer"); - return FALSE; + return; } g_print("== success pause \n"); - - return TRUE; } -static gboolean _stop() +static void _stop() { g_print("== stop \n"); int ret = MEDIA_STREAMER_ERROR_NONE; @@ -204,11 +199,9 @@ static gboolean _stop() ret = media_streamer_stop(current_media_streamer); if (ret != MEDIA_STREAMER_ERROR_NONE) { g_print("Fail to stop media streamer"); - return FALSE; + return; } g_print("== success stop \n"); - - return TRUE; } static gboolean _destroy(media_streamer_h streamer) @@ -256,7 +249,7 @@ static void create_formats(void) /* Define encoded video format */ media_format_create(&vfmt_encoded); - if (media_format_set_video_mime(vfmt_encoded, MEDIA_FORMAT_H263) != MEDIA_FORMAT_ERROR_NONE) { + if (media_format_set_video_mime(vfmt_encoded, MEDIA_FORMAT_H264_SP) != MEDIA_FORMAT_ERROR_NONE) { g_print("media_format_set_video_mime failed!"); } media_format_set_video_width(vfmt_encoded, 800); @@ -324,7 +317,36 @@ static void set_rtp_params(media_streamer_node_h rtp_node, params = NULL; } -static gboolean _create_rtp_streamer(media_streamer_node_h rtp_bin) +static void _create_file_playing() +{ + media_streamer_node_h file_src = NULL; + media_streamer_node_create_src( MEDIA_STREAMER_NODE_SRC_TYPE_FILE, &file_src); + media_streamer_node_set_param(file_src,MEDIA_STREAMER_PARAM_URI, g_uri); + media_streamer_node_add(current_media_streamer, file_src); +} + +static void _create_file_sub_playing() +{ + media_streamer_node_h file_sub_src = NULL; + media_streamer_node_create_src( MEDIA_STREAMER_NODE_SRC_TYPE_FILE, &file_sub_src); + media_streamer_node_set_param(file_sub_src,MEDIA_STREAMER_PARAM_URI, g_uri); + media_streamer_node_add(current_media_streamer, file_sub_src); + + media_streamer_node_h txt_src = NULL; + media_streamer_node_create_src( MEDIA_STREAMER_NODE_SRC_TYPE_FILE, &txt_src); + media_streamer_node_set_param(txt_src,MEDIA_STREAMER_PARAM_URI, g_sub_uri); + media_streamer_node_add(current_media_streamer, txt_src); +} + +static void _create_http_playing() +{ + media_streamer_node_h http_src = NULL; + media_streamer_node_create_src( MEDIA_STREAMER_NODE_SRC_TYPE_HTTP, &http_src); + media_streamer_node_set_param(http_src,MEDIA_STREAMER_PARAM_URI, g_uri); + media_streamer_node_add(current_media_streamer, http_src); +} + +static void _create_rtp_streamer(media_streamer_node_h rtp_bin) { g_print("== _create_rtp_streamer \n"); @@ -339,9 +361,6 @@ static gboolean _create_rtp_streamer(media_streamer_node_h rtp_bin) } else if (g_scenario_mode == SCENARIO_MODE_VIDEOTEST_SCREEN || g_scenario_mode == SCENARIO_MODE_TEST_VIDEO_AUDIO) { media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_TEST, &video_src); - } else if (g_scenario_mode == SCENARIO_MODE_FILESRC_VIDEO_AUDIO) { - media_streamer_node_create_src( MEDIA_STREAMER_NODE_SRC_TYPE_FILE, &video_src); - media_streamer_node_set_param(video_src,MEDIA_STREAMER_PARAM_URI, g_uri); } media_streamer_node_add(current_media_streamer, video_src); @@ -400,11 +419,9 @@ static gboolean _create_rtp_streamer(media_streamer_node_h rtp_bin) g_print("== success streamer audio part \n"); } - - return TRUE; } -static gboolean _create_rtp_streamer_autoplug(media_streamer_node_h rtp_bin) +static void _create_rtp_streamer_autoplug(media_streamer_node_h rtp_bin) { g_print("== _create_rtp_streamer_autoplug \n"); @@ -415,13 +432,10 @@ static gboolean _create_rtp_streamer_autoplug(media_streamer_node_h rtp_bin) if (g_scenario_mode == SCENARIO_MODE_CAMERA_SCREEN || g_scenario_mode == SCENARIO_MODE_FULL_VIDEO_AUDIO) { - media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA, &video_src); + media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA, &video_src); } else if (g_scenario_mode == SCENARIO_MODE_VIDEOTEST_SCREEN || g_scenario_mode == SCENARIO_MODE_TEST_VIDEO_AUDIO) { media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_TEST, &video_src); - } else if (g_scenario_mode == SCENARIO_MODE_FILESRC_VIDEO_AUDIO) { - media_streamer_node_create_src( MEDIA_STREAMER_NODE_SRC_TYPE_FILE, &video_src); - media_streamer_node_set_param(video_src,MEDIA_STREAMER_PARAM_URI, g_uri); } media_streamer_node_add(current_media_streamer, video_src); @@ -437,7 +451,6 @@ static gboolean _create_rtp_streamer_autoplug(media_streamer_node_h rtp_bin) if (g_scenario_mode == SCENARIO_MODE_MICROPHONE_PHONE || g_scenario_mode == SCENARIO_MODE_FULL_VIDEO_AUDIO) { media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_CAPTURE, &audio_src); - media_streamer_node_add(current_media_streamer, audio_src); } else if (g_scenario_mode == SCENARIO_MODE_AUDIOTEST_PHONE || g_scenario_mode == SCENARIO_MODE_TEST_VIDEO_AUDIO) { media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_TEST, &audio_src); @@ -447,11 +460,9 @@ static gboolean _create_rtp_streamer_autoplug(media_streamer_node_h rtp_bin) g_print("== success streamer_autoplug audio part \n"); } - - return TRUE; } -static gboolean _create_rtp_client(media_streamer_node_h rtp_bin) +static void _create_rtp_client(media_streamer_node_h rtp_bin) { g_print("== _create_rtp_client \n"); @@ -510,11 +521,9 @@ static gboolean _create_rtp_client(media_streamer_node_h rtp_bin) g_print("== success client audio part \n"); } - - return TRUE; } -static gboolean _create_rtp_client_autoplug(media_streamer_node_h rtp_bin) +static void _create_rtp_client_autoplug(media_streamer_node_h rtp_bin) { g_print("== _create_rtp_client_autoplug \n"); @@ -537,8 +546,6 @@ static gboolean _create_rtp_client_autoplug(media_streamer_node_h rtp_bin) g_print("== success client_autoplug audio part \n"); } - - return TRUE; } static media_streamer_node_h _create_rtp(int video_port, @@ -571,10 +578,12 @@ static void buffer_status_cb(media_streamer_node_h node, guint64 size = strlen(test); media_packet_h packet; - media_packet_create_from_external_memory(vfmt_encoded, - (void *)test, size, NULL, NULL, &packet); + media_packet_create_from_external_memory(vfmt_encoded, (void *)test, size, NULL, NULL, &packet); media_streamer_node_push_packet(node, packet); count++; + + media_packet_destroy(packet); + g_free(test); } else { media_streamer_node_push_packet(node, NULL); g_print("Buffer status cb got overflow\n"); @@ -599,7 +608,7 @@ static void eos_cb(media_streamer_node_h node, void *user_data) g_print("Got EOS cb from appsink\n"); } -static gboolean _create_app_test() +static void _create_app_test() { g_print("== _create_appsrc \n"); @@ -623,8 +632,6 @@ static gboolean _create_app_test() media_streamer_sink_set_eos_cb(app_sink, eos_cb, NULL); g_print("== success appsrc part \n"); - - return TRUE; } //#endif @@ -661,6 +668,11 @@ void reset_current_menu_state(void) g_free(g_uri); g_uri = NULL; } + + if (g_sub_uri != NULL) { + g_free(g_sub_uri); + g_sub_uri = NULL; + } } void quit() @@ -679,7 +691,13 @@ static void display_getting_ip_menu(void) static void display_getting_uri_menu(void) { g_print("\n"); - g_print("Please input URI for playing\n"); + g_print("Please input video URI for playing\n"); +} + +static void display_getting_sub_uri_menu(void) +{ + g_print("\n"); + g_print("Please input Subtitle path for playing\n"); } static void display_autoplug_select_menu(void) @@ -696,16 +714,32 @@ static void display_scenario_select_menu(void) { g_print("\n"); g_print("Please select Scenario mode\n"); - g_print("By default will be used [%d] mode\n", - g_scenario_mode); + g_print("By default will be used [%d] mode\n", g_scenario_mode); g_print("1. Camera -> Screen \n"); g_print("2. Microphone -> Phones\n"); g_print("3. Camera + Microphone -> Screen + Phones\n"); g_print("4. Video test -> Screen\n"); g_print("5. Audio test -> Phones\n"); g_print("6. Video test + Audio test -> Screen + Phones\n"); - g_print("7. Filesrc -> Screen + Phones\n"); - g_print("8. Appsrc -> Appsink\n"); + +} + +static void display_playing_scenario_select_menu(void) +{ + g_print("\n"); + g_print("====================================================\n"); + g_print(" media streamer test: Playing menu v0.3\n"); + g_print("----------------------------------------------------\n"); + g_print("\n"); + g_print("Please select Playing Scenario mode\n"); + g_print("By default will be used [%d] mode\n", g_scenario_mode); + g_print("1. VideoFile playing \n"); + g_print("2. VideoFile + SubtitleFile playing \n"); + g_print("3. HTTP Source playing \n"); + g_print("4. Appsrc -> Appsink \n"); + g_print("b. back \n"); + g_print("----------------------------------------------------\n"); + g_print("====================================================\n"); } static void display_preset_menu(void) @@ -765,6 +799,7 @@ static void display_main_menu(void) g_print("----------------------------------------------------\n"); g_print("1. Broadcast \n"); g_print("2. VOIP \n"); + g_print("3. Local Playing \n"); g_print("q. quit \n"); g_print("----------------------------------------------------\n"); g_print("====================================================\n"); @@ -783,6 +818,9 @@ static void display_menu(void) case MENU_STATE_VOIP_MENU: display_voip_menu(); break; + case MENU_STATE_PLAYING_MENU: + display_preset_menu(); + break; case MENU_STATE_PRESET_MENU: display_preset_menu(); break; @@ -795,15 +833,21 @@ static void display_menu(void) case SUBMENU_STATE_GETTING_IP: display_getting_ip_menu(); break; - case SUBMENU_STATE_GETTING_URI: + case SUBMENU_STATE_GETTING_VIDEOFILE_URI: display_getting_uri_menu(); break; + case SUBMENU_STATE_GETTING_SUBFILE_URI: + display_getting_sub_uri_menu(); + break; case SUBMENU_STATE_AUTOPLUG: display_autoplug_select_menu(); break; case SUBMENU_STATE_SCENARIO: display_scenario_select_menu(); break; + case SUBMENU_STATE_PLAYING_SCENARIO: + display_playing_scenario_select_menu(); + break; case SUBMENU_STATE_FORMAT: /* display_format_menu(); */ break; @@ -822,22 +866,18 @@ static void run_preset(void) switch (g_menu_preset) { case PRESET_RTP_STREAMER: rtp_bin = _create_rtp(VIDEO_PORT, AUDIO_PORT, FALSE); - if (g_autoplug_mode && (g_scenario_mode != SCENARIO_MODE_APPSRC_APPSINK)) { + if (g_autoplug_mode) { _create_rtp_streamer_autoplug(rtp_bin); - } else if ((g_scenario_mode != SCENARIO_MODE_APPSRC_APPSINK)) { - _create_rtp_streamer(rtp_bin); } else { - _create_app_test(); + _create_rtp_streamer(rtp_bin); } break; case PRESET_RTP_CLIENT: rtp_bin = _create_rtp(VIDEO_PORT, AUDIO_PORT, TRUE); - if (g_autoplug_mode && (g_scenario_mode != SCENARIO_MODE_APPSRC_APPSINK)) { + if (g_autoplug_mode) { _create_rtp_client_autoplug(rtp_bin); - } else if ((g_scenario_mode != SCENARIO_MODE_APPSRC_APPSINK)) { - _create_rtp_client(rtp_bin); } else { - _create_app_test(); + _create_rtp_client(rtp_bin); } break; case PRESET_VOIP: @@ -872,6 +912,23 @@ static void run_preset(void) } } +void run_playing_preset(void) +{ + create_formats(); + + if (g_scenario_mode == SCENARIO_MODE_FILE_VIDEO_AUDIO) { + _create_file_playing(); + } else if (g_scenario_mode == SCENARIO_MODE_FILE_SUBTITLE_VIDEO_AUDIO) { + _create_file_sub_playing(); + } else if (g_scenario_mode == SCENARIO_MODE_HTTP_VIDEO_AUDIO) { + _create_http_playing(); + } else if ((g_scenario_mode == SCENARIO_MODE_APPSRC_APPSINK)) { + _create_app_test(); + } else { + g_print("Invalid playing menu preset was selected!"); + } +} + void _interpret_main_menu(char *cmd) { int len = strlen(cmd); @@ -881,6 +938,8 @@ void _interpret_main_menu(char *cmd) g_menu_state = MENU_STATE_BROADCAST_MENU; } else if (!strncmp(cmd, "2", len)) { g_menu_state = MENU_STATE_VOIP_MENU; + } else if (!strncmp(cmd, "3", len)) { + g_menu_state = MENU_STATE_PLAYING_MENU; } else if (!strncmp(cmd, "q", len)) { quit(); } @@ -946,12 +1005,36 @@ void _interpret_voip_menu(char *cmd) } } +void _interpret_playing_scenario_menu(char *cmd) +{ + int len = strlen(cmd); + + if (len == 1) { + if (!strncmp(cmd, "1", len)) { + g_scenario_mode = SCENARIO_MODE_FILE_VIDEO_AUDIO; + g_sub_menu_state = SUBMENU_STATE_GETTING_VIDEOFILE_URI; + return; + } else if (!strncmp(cmd, "2", len)) { + g_scenario_mode = SCENARIO_MODE_FILE_SUBTITLE_VIDEO_AUDIO; + g_sub_menu_state = SUBMENU_STATE_GETTING_VIDEOFILE_URI; + return; + } else if (!strncmp(cmd, "3", len)) { + g_scenario_mode = SCENARIO_MODE_HTTP_VIDEO_AUDIO; + g_sub_menu_state = SUBMENU_STATE_GETTING_VIDEOFILE_URI; + return; + } else if (!strncmp(cmd, "4", len)) { + g_scenario_mode = SCENARIO_MODE_APPSRC_APPSINK; + } + } + g_sub_menu_state = SUBMENU_STATE_UNKNOWN; +} + + void _interpret_scenario_menu(char *cmd) { int len = strlen(cmd); - if (len == 1 || len == 2) - { + if (len == 1) { if (!strncmp(cmd, "1", len)) { g_scenario_mode = SCENARIO_MODE_CAMERA_SCREEN; g_video_is_on = TRUE; @@ -976,18 +1059,6 @@ void _interpret_scenario_menu(char *cmd) g_scenario_mode = SCENARIO_MODE_TEST_VIDEO_AUDIO; g_video_is_on = TRUE; g_audio_is_on = TRUE; - } else if (!strncmp(cmd, "7", len)) { - g_scenario_mode = SCENARIO_MODE_FILESRC_VIDEO_AUDIO; - g_video_is_on = TRUE; - g_audio_is_on = TRUE; - if (g_menu_preset & PRESET_RTP_STREAMER) { - g_sub_menu_state = SUBMENU_STATE_GETTING_URI; - return; - } - } else if (!strncmp(cmd, "8", len)) { - g_scenario_mode = SCENARIO_MODE_APPSRC_APPSINK; - g_video_is_on = FALSE; - g_audio_is_on = FALSE; } } @@ -1014,6 +1085,28 @@ void _interpret_getting_ip_menu(char *cmd) g_sub_menu_state = SUBMENU_STATE_SCENARIO; } +void _interpret_getting_sub_uri_menu(char *cmd) +{ + if (cmd) { + if (g_sub_uri != NULL) { + g_free(g_sub_uri); + } + g_sub_uri = g_strdup(cmd); + g_print("== URI set to [%s]\n", g_sub_uri); + } else { + g_print("Empty URI!\n"); + return; + } + + if (g_menu_state == MENU_STATE_PLAYING_MENU) { + run_playing_preset(); + g_sub_menu_state = SUBMENU_STATE_UNKNOWN; + } else { + g_sub_menu_state = SUBMENU_STATE_UNKNOWN; + run_preset(); + } +} + void _interpret_getting_uri_menu(char *cmd) { if (cmd) { @@ -1027,8 +1120,17 @@ void _interpret_getting_uri_menu(char *cmd) return; } - g_sub_menu_state = SUBMENU_STATE_UNKNOWN; - run_preset(); + 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; + } else { + run_playing_preset(); + g_sub_menu_state = SUBMENU_STATE_UNKNOWN; + } + } else { + g_sub_menu_state = SUBMENU_STATE_UNKNOWN; + run_preset(); + } } void _interpret_autoplug_menu(char *cmd) @@ -1069,17 +1171,21 @@ void _interpret_preset_menu(char *cmd) } else if (!strncmp(cmd, "2", len)) { /* call the run_preset function after autoplug mode was selected; */ - g_sub_menu_state = SUBMENU_STATE_AUTOPLUG; + if (g_menu_state == MENU_STATE_PLAYING_MENU) { + g_sub_menu_state = SUBMENU_STATE_PLAYING_SCENARIO; + } else { + g_sub_menu_state = SUBMENU_STATE_AUTOPLUG; + } } else if (!strncmp(cmd, "4", len)) { _prepare(); } else if (!strncmp(cmd, "5", len)) { _unprepare(); } else if (!strncmp(cmd, "6", len)) { - _play(g_media_streamer); + _play(); } else if (!strncmp(cmd, "7", len)) { - _pause(g_media_streamer); + _pause(); } else if (!strncmp(cmd, "8", len)) { - _stop(g_media_streamer); + _stop(); } else if (!strncmp(cmd, "9", len)) { _destroy(current_media_streamer); } else if (!strncmp(cmd, "b", len)) { @@ -1090,6 +1196,7 @@ void _interpret_preset_menu(char *cmd) } else { reset_current_menu_state(); } + g_sub_menu_state = SUBMENU_STATE_UNKNOWN; display_menu(); } @@ -1111,6 +1218,9 @@ static void interpret_cmd(char *cmd) case MENU_STATE_VOIP_MENU: _interpret_voip_menu(cmd); break; + case MENU_STATE_PLAYING_MENU: + _interpret_preset_menu(cmd); + break; case MENU_STATE_PRESET_MENU: _interpret_preset_menu(cmd); break; @@ -1124,9 +1234,12 @@ static void interpret_cmd(char *cmd) case SUBMENU_STATE_GETTING_IP: _interpret_getting_ip_menu(cmd); break; - case SUBMENU_STATE_GETTING_URI: + case SUBMENU_STATE_GETTING_VIDEOFILE_URI: _interpret_getting_uri_menu(cmd); break; + case SUBMENU_STATE_GETTING_SUBFILE_URI: + _interpret_getting_sub_uri_menu(cmd); + break; case SUBMENU_STATE_AUTOPLUG: _interpret_autoplug_menu(cmd); break; @@ -1136,6 +1249,9 @@ static void interpret_cmd(char *cmd) case SUBMENU_STATE_SCENARIO: _interpret_scenario_menu(cmd); break; + case SUBMENU_STATE_PLAYING_SCENARIO: + _interpret_playing_scenario_menu(cmd); + break; default: g_print("*** Unknown Submenu state.\n"); break;