webrtc_source_file: Encoding audio stream from filesrc with default codec for compati... 72/278872/24
authorhj kim <backto.kim@samsung.com>
Wed, 27 Jul 2022 08:03:18 +0000 (17:03 +0900)
committerhj kim <backto.kim@samsung.com>
Tue, 2 Aug 2022 06:15:40 +0000 (15:15 +0900)
gstreamer does not support payloaders for some encoding audio formats.
In this case, after decoding, encode it again with the corresponding format in ini.

[Version] 0.3.188
[Issue Type] Improvement

Change-Id: I5c2f19bfe0056986e0128770ef9038966b7e3989

packaging/capi-media-webrtc.spec
src/webrtc_source_file.c
src/webrtc_source_private.c

index 71fc81be7376ed1ed85e9de0cfc6636952cf3f07..00556f90bdfdf39465f3fab18afbc172ab0e33cf 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.3.187
+Version:    0.3.188
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
@@ -86,6 +86,8 @@ cp %{SOURCE1003} .
 export CFLAGS+=" -DSYSCONFDIR=\\\"%{_hal_sysconfdir}\\\""
 export CXXFLAGS+=" -DSYSCONFDIR=\\\"%{_hal_sysconfdir}\\\""
 
+export CFLAGS+=" -DSUPPORT_FILESRC_AUDIO_FORMAT_CHANGE"
+
 %if 0%{?gcov:1}
 export CFLAGS+=" -fprofile-arcs -ftest-coverage"
 export CXXFLAGS+=" -fprofile-arcs -ftest-coverage"
index 623953e673546013d1e023dfbc2c320155943684..b410d5dd009f6bed0d8dc4b36c82751adf8be1bf 100644 (file)
@@ -456,7 +456,22 @@ static GstAutoplugSelectResult __filesrc_pipeline_decodebin_autoplug_select_cb(G
        const gchar *klass = gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS);
 
        if (g_strrstr(klass, "Codec/Decoder")) {
+#ifdef SUPPORT_FILESRC_AUDIO_FORMAT_CHANGE
+               const gchar *media_type = gst_structure_get_name(gst_caps_get_structure(caps, 0));
+               RET_VAL_IF(media_type == NULL, GST_AUTOPLUG_SELECT_TRY, "media_type is NULL");
+
+               if (g_strrstr(media_type, "audio")) {
+                       GstElement *payloader = __create_payloader_for_filesrc_pipeline(pad, true);
+                       if (!payloader) {
+                               LOG_INFO("failed to find payloader. decode it");
+                               return GST_AUTOPLUG_SELECT_TRY;
+                       }
+
+                       gst_object_unref(payloader);
+               }
+#endif
                LOG_INFO("expose [%s]", klass);
+
                return GST_AUTOPLUG_SELECT_EXPOSE;
        }
 
@@ -560,6 +575,62 @@ static int __link_decodebin_with_queue(GstPad *pad, webrtc_gst_slot_s *source, b
        return WEBRTC_ERROR_NONE;
 }
 
+#ifdef SUPPORT_FILESRC_AUDIO_FORMAT_CHANGE
+static int __create_rest_of_raw_audio_elements_for_filesrc_pipeline(webrtc_s *webrtc, webrtc_gst_slot_s *source, GList **element_list)
+{
+       GstElement *queue = NULL;
+       GstElement *resample = NULL;
+       GstElement *conv = NULL;
+       GstElement *fakesink = NULL;
+       GList *_element_list = NULL;
+
+       RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+       RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
+       RET_VAL_IF(source->filesrc_pipeline == NULL, WEBRTC_ERROR_INVALID_OPERATION, "filesrc_pipeline is NULL");
+
+       if (!(queue = _create_element(DEFAULT_ELEMENT_QUEUE, _get_element_name(GET_AV_IDX(true), ELEMENT_QUEUE))))
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       APPEND_ELEMENT(_element_list, queue);
+
+       if (!(resample = _create_element(DEFAULT_ELEMENT_AUDIORESAMPLE, NULL)))
+               goto exit;
+       APPEND_ELEMENT(_element_list, resample);
+
+       if (!(conv = _create_element(DEFAULT_ELEMENT_AUDIOCONVERT, NULL)))
+               goto exit;
+       APPEND_ELEMENT(_element_list, conv);
+
+       if (_create_rest_of_elements(webrtc, source, false, &_element_list, true) != WEBRTC_ERROR_NONE)
+               goto exit;
+
+       if(!(fakesink = __prepare_fakesink_for_filesrc_pipeline(source, true)))
+               goto exit;
+       APPEND_ELEMENT(_element_list, fakesink);
+
+       if (!_add_elements_to_bin(GST_BIN(source->filesrc_pipeline), _element_list))
+               goto exit;
+
+       if (!_link_elements(_element_list))
+               goto exit_with_remove_from_bin;
+
+       if (!_sync_elements_state_with_parent(_element_list))
+               goto exit_with_remove_from_bin;
+
+       *element_list = _element_list;
+
+       return WEBRTC_ERROR_NONE;
+
+exit_with_remove_from_bin:
+       _remove_elements_from_bin(GST_BIN(source->filesrc_pipeline), _element_list);
+       SAFE_G_LIST_FREE(_element_list);
+       return WEBRTC_ERROR_INVALID_OPERATION;
+
+exit:
+       SAFE_G_LIST_FREE_FULL(_element_list, gst_object_unref);
+       return WEBRTC_ERROR_INVALID_OPERATION;
+}
+#endif
+
 static void __filesrc_pipeline_decodebin_pad_added_cb(GstElement *element, GstPad *pad, gpointer data)
 {
        int ret = WEBRTC_ERROR_NONE;
@@ -570,6 +641,10 @@ static void __filesrc_pipeline_decodebin_pad_added_cb(GstElement *element, GstPa
        GList *filesrc_element_list = NULL;
        GList *bin_element_list = NULL;
        GstElement *queue = NULL;
+       bool need_decoding = true;
+#ifdef SUPPORT_FILESRC_AUDIO_FORMAT_CHANGE
+       GList *audio_pipeline_element_list = NULL;
+#endif
 
        RET_IF(source == NULL, "source is NULL");
        RET_IF(source->filesrc_pipeline == NULL, "filesrc_pipeline is NULL");
@@ -587,6 +662,17 @@ static void __filesrc_pipeline_decodebin_pad_added_cb(GstElement *element, GstPa
        is_audio = _is_audio_media_type(media_type);
        av_idx = GET_AV_IDX(is_audio);
 
+#ifdef SUPPORT_FILESRC_AUDIO_FORMAT_CHANGE
+       if (is_audio && g_strrstr(media_type, "raw")) {
+               need_decoding = false;
+
+               const ini_item_media_source_s *ini_source = _ini_get_source_by_type(&source->webrtc->ini, source->type);
+               if (ini_source == NULL)
+                       ini_source = &(source->webrtc->ini.media_source);
+
+               source->av[AV_IDX_AUDIO].codec = ini_source->a_codecs[0];
+       }
+#endif
        g_free(media_type);
 
        if (source->av[av_idx].src_pad_probe_id > 0) {
@@ -597,7 +683,14 @@ static void __filesrc_pipeline_decodebin_pad_added_cb(GstElement *element, GstPa
                return;
        }
 
+#ifdef SUPPORT_FILESRC_AUDIO_FORMAT_CHANGE
+       if (need_decoding)
+               ret = __create_rest_of_elements_for_filesrc_pipeline(source, pad, &filesrc_element_list, is_audio);
+       else
+               ret = __create_rest_of_raw_audio_elements_for_filesrc_pipeline(source->webrtc, source, &audio_pipeline_element_list);
+#else
        ret = __create_rest_of_elements_for_filesrc_pipeline(source, pad, &filesrc_element_list, is_audio);
+#endif
        if (ret != WEBRTC_ERROR_NONE) {
                LOG_ERROR("failed to __create_rest_of_elements_for_filesrc_pipeline()");
                return;
@@ -627,12 +720,15 @@ static void __filesrc_pipeline_decodebin_pad_added_cb(GstElement *element, GstPa
                goto exit_with_remove_from_bin;
        }
 
-       source->av[av_idx].render.need_decoding = true;
+       source->av[av_idx].render.need_decoding = need_decoding;
        source->av[av_idx].render.appsrc_caps = gst_pad_get_current_caps(pad);
        _add_probe_to_pad_for_render(source, av_idx, gst_element_get_static_pad(queue, "src"), _source_data_probe_cb);
 
        SAFE_G_LIST_FREE(filesrc_element_list);
        SAFE_G_LIST_FREE(bin_element_list);
+#ifdef SUPPORT_FILESRC_AUDIO_FORMAT_CHANGE
+       SAFE_G_LIST_FREE(audio_pipeline_element_list);
+#endif
 
        GENERATE_DOT(source->webrtc, source->filesrc_pipeline, "%s.%s-%s",
                GST_ELEMENT_NAME(source->filesrc_pipeline), GST_ELEMENT_NAME(element), GST_PAD_NAME(pad));
@@ -646,8 +742,18 @@ exit_with_remove_from_bin:
        _remove_elements_from_bin(GST_BIN(source->bin), bin_element_list);
        SAFE_G_LIST_FREE(bin_element_list);
 exit:
+#ifdef SUPPORT_FILESRC_AUDIO_FORMAT_CHANGE
+       if (filesrc_element_list)
+               _remove_elements_from_bin(GST_BIN(source->filesrc_pipeline), filesrc_element_list);
+       SAFE_G_LIST_FREE(filesrc_element_list);
+
+       if (audio_pipeline_element_list)
+               _remove_elements_from_bin(GST_BIN(source->filesrc_pipeline), audio_pipeline_element_list);
+       SAFE_G_LIST_FREE(audio_pipeline_element_list);
+#else
        _remove_elements_from_bin(GST_BIN(source->filesrc_pipeline), filesrc_element_list);
        SAFE_G_LIST_FREE(filesrc_element_list);
+#endif
        return;
 }
 
index e694bb976abf8070be2fdd08d7b028cfea52c178..cb576d8e981333fb89849af34c11e8c64e4f3fdb 100644 (file)
@@ -762,6 +762,9 @@ static GstCaps *__make_default_raw_caps(webrtc_gst_slot_s *source, webrtc_ini_s
        case WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST:
        case WEBRTC_MEDIA_SOURCE_TYPE_MIC:
        case WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_AUDIO:
+#ifdef SUPPORT_FILESRC_AUDIO_FORMAT_CHANGE
+       case WEBRTC_MEDIA_SOURCE_TYPE_FILE:
+#endif
                format = _get_gst_audio_raw_format_from_string(ini_source->a_raw_format);
                RET_VAL_IF(format == GST_AUDIO_FORMAT_UNKNOWN, NULL, "not supported raw format");
 
@@ -815,6 +818,9 @@ static GstCaps *__make_default_encoded_caps(webrtc_gst_slot_s *source, webrtc_in
        case WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST:
        case WEBRTC_MEDIA_SOURCE_TYPE_MIC:
        case WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_AUDIO:
+#ifdef SUPPORT_FILESRC_AUDIO_FORMAT_CHANGE
+       case WEBRTC_MEDIA_SOURCE_TYPE_FILE:
+#endif
                _media_type = _get_audio_media_type(source->av[AV_IDX_AUDIO].codec);
                RET_VAL_IF(_media_type == NULL, NULL, "_media_type is NULL");