Add support for media packet source pipeline 96/249696/8
authorSangchul Lee <sc11.lee@samsung.com>
Wed, 16 Dec 2020 07:16:57 +0000 (16:16 +0900)
committerSangchul Lee <sangchul1011@gmail.com>
Thu, 31 Dec 2020 05:32:20 +0000 (14:32 +0900)
The appsrc element is used to build this new type of media source
pipeline. A buffer packetizing by media packet API will be able to
be pushed to this new source pipeline with further patches.

In this patch, only limited types of raw format are supported to make
the new media source pipeline.

[Version] 0.1.74
[Issue Type] New feature

Change-Id: I44b207010df183ca350f763187e6aca063f98f42
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
include/webrtc.h
include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc_ini.c
src/webrtc_private.c
src/webrtc_source.c

index e46d0dc11ef3167225dde534148129b9af26a813..aa700fd05f11ac892c15768138914e58e78b3e31 100644 (file)
@@ -99,6 +99,7 @@ typedef enum {
        WEBRTC_MEDIA_SOURCE_TYPE_MIC,         /**<  Audio from microphone */
        WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST,   /**<  Audio test */
        WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST,   /**<  Video test */
+       WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET /**<  Media packet */
 } webrtc_media_source_type_e;
 
 /**
index 8f732abe7a1b6671f2a7f1716ca147441e31e1be..c53acdbd9ff63141f27393d745248e4a81af9af4 100644 (file)
@@ -237,16 +237,19 @@ typedef struct _webrtc_display {
        webrtc_tbm_s *tbm;
 } webrtc_display_s;
 
-/* FIXME: divide into two slot types */
+/* FIXME: divide into two slot types or use union */
 typedef struct _webrtc_gst_slot_s {
        unsigned int id;
        GstElement *bin;
-       int media_types;    /* values of media_type_e combined with bitwise 'or' */
-       int mlines[2];      /* index 0 for audio, 1 for video */
-
        GstElement *webrtcbin;
        GList *signals;
 
+       GstPad *src_pad;
+       webrtc_media_source_type_e type;
+       int media_types;    /* values of media_type_e combined with bitwise 'or' */
+       int mlines[2];      /* index 0 for audio, 1 for video */
+       media_format_h media_format;
+
        webrtc_display_s *display;
 } webrtc_gst_slot_s;
 
@@ -327,6 +330,7 @@ void _gst_destroy_pipeline(webrtc_s *webrtc);
 int _gst_pipeline_set_state(webrtc_s *webrtc, GstState state);
 int _add_media_source(webrtc_s *webrtc, webrtc_media_source_type_e type, unsigned int *source_id);
 int _remove_media_source(webrtc_s *webrtc, unsigned int source_id);
+int _set_media_format(webrtc_s *webrtc, unsigned int source_id, media_format_h format);
 int _get_transceiver_direction(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_direction_e *direction);
 int _set_transceiver_direction(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_direction_e direction);
 void _post_state_in_idle(webrtc_s *webrtc, webrtc_state_e new_state);
@@ -336,6 +340,7 @@ void _connect_and_append_signal(GList **signals, GObject *obj, const char *sig_n
 void _disconnect_signal(gpointer data);
 GstElement *_create_element(const char *factory_name, const char *name);
 GstElement *_create_element_from_registry(element_info_s *elem_info);
+webrtc_gst_slot_s* _get_slot_by_id(GHashTable *slots, unsigned int id);
 int _add_no_target_ghostpad_to_slot(webrtc_gst_slot_s *slot, bool is_src, GstPad **new_pad);
 int _set_ghost_pad_target(GstPad *ghost_pad, GstElement *target_element, bool is_src);
 int _add_rendering_sink_bin(webrtc_s *webrtc, GstPad *src_pad);
index cc97edeb0ca23eb825221709a54007e80e7b3015..3e4a743d6577fc0b46833369da20823a725fb79c 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.1.73
+Version:    0.1.74
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 94fdd5f7242d52c376f9ec37acf5e76be4901ebd..bcba3fcb374a4e0b19787fd8af6164735cfabd59 100644 (file)
@@ -31,6 +31,7 @@
 #define INI_CATEGORY_SOURCE_MIC           "source mic"
 #define INI_CATEGORY_SOURCE_AUDIOTEST     "source audiotest"
 #define INI_CATEGORY_SOURCE_VIDEOTEST     "source videotest"
+#define INI_CATEGORY_SOURCE_MEDIA_PACKET  "source media packet"
 #define INI_CATEGORY_RENDERING_SINK       "rendering sink"
 
 /* items for general */
@@ -84,6 +85,7 @@ typedef enum {
        MEDIA_SOURCE_TYPE_MIC,
        MEDIA_SOURCE_TYPE_AUDIOTEST,
        MEDIA_SOURCE_TYPE_VIDEOTEST,
+       MEDIA_SOURCE_TYPE_MEDIA_PACKET,
        MEDIA_SOURCE_TYPE_MAX,
 } media_source_type_e;
 
@@ -96,6 +98,7 @@ static ini_category_name_s category_source_names[] = {
        [MEDIA_SOURCE_TYPE_MIC] = { INI_CATEGORY_SOURCE_MIC },
        [MEDIA_SOURCE_TYPE_AUDIOTEST] = { INI_CATEGORY_SOURCE_AUDIOTEST },
        [MEDIA_SOURCE_TYPE_VIDEOTEST] = { INI_CATEGORY_SOURCE_VIDEOTEST },
+       [MEDIA_SOURCE_TYPE_MEDIA_PACKET] = { INI_CATEGORY_SOURCE_MEDIA_PACKET },
        [MEDIA_SOURCE_TYPE_MAX] = { NULL },
 };
 
@@ -373,20 +376,9 @@ int _load_ini(webrtc_s *webrtc)
 
 ini_item_media_source_s* _ini_get_source_by_type(webrtc_ini_s *ini, webrtc_media_source_type_e type)
 {
-       const char *source_type = NULL;
-
        RET_VAL_IF(ini == NULL, NULL, "ini is NULL");
 
-       if (type == WEBRTC_MEDIA_SOURCE_TYPE_CAMERA)
-               source_type = INI_CATEGORY_SOURCE_CAMERA;
-       else if (type == WEBRTC_MEDIA_SOURCE_TYPE_MIC)
-               source_type = INI_CATEGORY_SOURCE_MIC;
-       else if (type == WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST)
-               source_type = INI_CATEGORY_SOURCE_AUDIOTEST;
-       else if (type == WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST)
-               source_type = INI_CATEGORY_SOURCE_VIDEOTEST;
-
-       return (ini_item_media_source_s*)g_hash_table_lookup(ini->sources, source_type);
+       return (ini_item_media_source_s*)g_hash_table_lookup(ini->sources, category_source_names[type].name);
 }
 
 void _unload_ini(webrtc_s *webrtc)
index 0c204a9e91a13a4ffe2574ec6dbee807ea7d815c..afeb3da6dfc16f0572eaaf2d6c9473d049ce21db 100644 (file)
@@ -972,7 +972,7 @@ static gboolean __check_id_equal_cb(gpointer key, gpointer value, gpointer user_
        return FALSE;
 }
 
-static webrtc_gst_slot_s* __get_slot_by_id(GHashTable *slots, unsigned int id)
+webrtc_gst_slot_s* _get_slot_by_id(GHashTable *slots, unsigned int id)
 {
        webrtc_gst_slot_s *slot;
 
@@ -1018,7 +1018,7 @@ int _get_transceiver_direction(webrtc_s *webrtc, unsigned int source_id, webrtc_
        RET_VAL_IF(direction == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "direction is NULL");
        RET_VAL_IF(webrtc->gst.webrtcbin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "webrtcbin is NULL");
        RET_VAL_IF(webrtc->gst.source_slots == NULL, WEBRTC_ERROR_INVALID_OPERATION, "source_slots is NULL");
-       RET_VAL_IF((source = __get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
+       RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
 
        if (media_type == WEBRTC_MEDIA_TYPE_AUDIO && source->media_types & MEDIA_TYPE_AUDIO) {
                mline = source->mlines[MLINES_IDX_AUDIO];
@@ -1064,7 +1064,7 @@ int _set_transceiver_direction(webrtc_s *webrtc, unsigned int source_id, webrtc_
        RET_VAL_IF(direction > WEBRTC_TRANSCEIVER_DIRECTION_SENDRECV, WEBRTC_ERROR_INVALID_PARAMETER, "invalid direction");
        RET_VAL_IF(webrtc->gst.webrtcbin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "webrtcbin is NULL");
        RET_VAL_IF(webrtc->gst.source_slots == NULL, WEBRTC_ERROR_INVALID_OPERATION, "source_slots is NULL");
-       RET_VAL_IF((source = __get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
+       RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
 
        if (media_type == WEBRTC_MEDIA_TYPE_AUDIO && source->media_types & MEDIA_TYPE_AUDIO) {
                mline = source->mlines[MLINES_IDX_AUDIO];
index 83d509b10c5142b7b3e3db8d65193b7b72ed3f3c..8b0968700fde394ad988621619423818466c8ca0 100644 (file)
@@ -30,6 +30,7 @@
 #define DEFAULT_ELEMENT_AUDIOSRC      "pulsesrc"
 #define DEFAULT_ELEMENT_VIDEOTESTSRC  "videotestsrc"
 #define DEFAULT_ELEMENT_AUDIOTESTSRC  "audiotestsrc"
+#define DEFAULT_ELEMENT_APPSRC        "appsrc"
 #define DEFAULT_ELEMENT_CAPSFILTER    "capsfilter"
 #define DEFAULT_ELEMENT_QUEUE         "queue"
 
@@ -138,80 +139,224 @@ static codec_type_e __get_video_codec_type(const gchar *media_type)
        return CODEC_TYPE_NOT_SUPPORTED;
 }
 
-static GstCaps *__make_default_raw_caps(webrtc_media_source_type_e type, webrtc_ini_s *ini)
+static bool __is_supported_mime_type(media_format_mimetype_e mime_type)
+{
+       switch (mime_type) {
+       /* RAW formats */
+       case MEDIA_FORMAT_PCM_S16LE:
+       case MEDIA_FORMAT_PCM_S24LE:
+       case MEDIA_FORMAT_I420:
+       case MEDIA_FORMAT_NV12:
+               LOG_INFO("[%s] mime_type[0x%x]", mime_type & MEDIA_FORMAT_AUDIO ? "AUDIO" : "VIDEO", mime_type);
+               return true;
+       /* TODO: ENCODED formats */
+       default:
+               LOG_ERROR("not supported mime_type(0x%x)", mime_type);
+               return false;
+       }
+}
+
+static const char *__get_format_name(media_format_mimetype_e mime_type)
+{
+       switch (mime_type) {
+       /* RAW formats */
+       case MEDIA_FORMAT_PCM_S16LE:
+               return "S16LE";
+       case MEDIA_FORMAT_PCM_S24LE:
+               return "S24LE";
+       case MEDIA_FORMAT_I420:
+               return "I420";
+       case MEDIA_FORMAT_NV12:
+               return "NV12";
+       /* TODO: ENCODED formats */
+       default:
+               LOG_ERROR("not supported mime_type(0x%x)", mime_type);
+               return NULL;
+       }
+}
+
+static GstCaps *__make_default_raw_caps(webrtc_gst_slot_s *source, webrtc_ini_s *ini)
 {
        GstCaps *caps = NULL;
-       ini_item_media_source_s *source;
+       ini_item_media_source_s *ini_source;
 
+       RET_VAL_IF(source == NULL, NULL, "source is NULL");
        RET_VAL_IF(ini == NULL, NULL, "ini is NULL");
 
-       source = _ini_get_source_by_type(ini, type);
-       if (source == NULL)
-               source = &ini->media_source;
+       ini_source = _ini_get_source_by_type(ini, source->type);
+       if (ini_source == NULL)
+               ini_source = &ini->media_source;
 
-       switch (type) {
+       switch (source->type) {
        case WEBRTC_MEDIA_SOURCE_TYPE_CAMERA:
        case WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST:
                caps = gst_caps_new_simple(MEDIA_TYPE_VIDEO_RAW,
-                                               "format", G_TYPE_STRING, source->v_raw_format,
-                                               "framerate", GST_TYPE_FRACTION, source->v_framerate, 1,
-                                               "width", G_TYPE_INT, source->v_width,
-                                               "height", G_TYPE_INT, source->v_height,
+                                               "format", G_TYPE_STRING, ini_source->v_raw_format,
+                                               "framerate", GST_TYPE_FRACTION, ini_source->v_framerate, 1,
+                                               "width", G_TYPE_INT, ini_source->v_width,
+                                               "height", G_TYPE_INT, ini_source->v_height,
                                                NULL);
                break;
 
        case WEBRTC_MEDIA_SOURCE_TYPE_MIC:
        case WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST:
                caps = gst_caps_new_simple(MEDIA_TYPE_AUDIO_RAW,
-                                               "format", G_TYPE_STRING, source->a_raw_format,
-                                               "channels", G_TYPE_INT, source->a_channels,
-                                               "rate", G_TYPE_INT, source->a_samplerate,
+                                               "format", G_TYPE_STRING, ini_source->a_raw_format,
+                                               "channels", G_TYPE_INT, ini_source->a_channels,
+                                               "rate", G_TYPE_INT, ini_source->a_samplerate,
                                                NULL);
                break;
 
+       case WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET: {
+               media_format_mimetype_e mime_type;
+
+               RET_VAL_IF(source->media_format == NULL, NULL, "media_format is NULL");
+
+               if (source->media_types == MEDIA_TYPE_AUDIO) {
+                       int channels;
+                       int samplerate;
+
+                       RET_VAL_IF(media_format_get_audio_info(source->media_format, &mime_type, &channels, &samplerate, NULL, NULL) != MEDIA_FORMAT_ERROR_NONE,
+                               NULL, "failed to media_format_get_audio_info()");
+                       caps = gst_caps_new_simple(MEDIA_TYPE_AUDIO_RAW,
+                                                       "format", G_TYPE_STRING, __get_format_name(mime_type),
+                                                       "channels", G_TYPE_INT, channels,
+                                                       "rate", G_TYPE_INT, samplerate,
+                                                       NULL);
+
+               } else if (source->media_types == MEDIA_TYPE_VIDEO) {
+                       int width;
+                       int height;
+                       int framerate;
+
+                       RET_VAL_IF(media_format_get_video_info(source->media_format, &mime_type, &width, &height, NULL, NULL) != MEDIA_FORMAT_ERROR_NONE,
+                               NULL, "failed to media_format_get_video_info()");
+                       RET_VAL_IF(media_format_get_video_frame_rate(source->media_format, &framerate) != MEDIA_FORMAT_ERROR_NONE,
+                               NULL, "failed to media_format_get_video_frame_rate()");
+                       caps = gst_caps_new_simple(MEDIA_TYPE_VIDEO_RAW,
+                                                       "format", G_TYPE_STRING, __get_format_name(mime_type),
+                                                       "framerate", GST_TYPE_FRACTION, framerate, 1,
+                                                       "width", G_TYPE_INT, width,
+                                                       "height", G_TYPE_INT, height,
+                                                       NULL);
+               } else {
+                       LOG_ERROR_IF_REACHED("source->media_types(0x%x)", source->media_types);
+               }
+               break;
+       }
        default:
-               LOG_ERROR_IF_REACHED("type(%d)", type);
+               LOG_ERROR_IF_REACHED("type(%d)", source->type);
                break;
        }
 
        return caps;
 }
 
+static GstCaps *__make_raw_caps_from_media_format(webrtc_gst_slot_s *source)
+{
+       GstCaps *caps = NULL;
+       media_format_mimetype_e mime_type;
+
+       RET_VAL_IF(source == NULL, NULL, "source is NULL");
+       RET_VAL_IF(source->media_format == NULL, NULL, "media_format is NULL");
+       RET_VAL_IF(source->type != WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET, NULL,
+               "type(%d) is not for media packet source", source->type);
+
+       if (source->media_types == MEDIA_TYPE_AUDIO) {
+               int channels;
+               int samplerate;
+
+               RET_VAL_IF(media_format_get_audio_info(source->media_format, &mime_type, &channels, &samplerate, NULL, NULL) != MEDIA_FORMAT_ERROR_NONE,
+                       NULL, "failed to media_format_get_audio_info()");
+               caps = gst_caps_new_simple(MEDIA_TYPE_AUDIO_RAW,
+                                               "format", G_TYPE_STRING, __get_format_name(mime_type),
+                                               "channels", G_TYPE_INT, channels,
+                                               "rate", G_TYPE_INT, samplerate,
+                                               NULL);
+
+       } else if (source->media_types == MEDIA_TYPE_VIDEO) {
+               int width;
+               int height;
+               int framerate;
+
+               RET_VAL_IF(media_format_get_video_info(source->media_format, &mime_type, &width, &height, NULL, NULL) != MEDIA_FORMAT_ERROR_NONE,
+                       NULL, "failed to media_format_get_video_info()");
+               RET_VAL_IF(media_format_get_video_frame_rate(source->media_format, &framerate) != MEDIA_FORMAT_ERROR_NONE,
+                       NULL, "failed to media_format_get_video_frame_rate()");
+               caps = gst_caps_new_simple(MEDIA_TYPE_VIDEO_RAW,
+                                               "format", G_TYPE_STRING, __get_format_name(mime_type),
+                                               "framerate", GST_TYPE_FRACTION, framerate, 1,
+                                               "width", G_TYPE_INT, width,
+                                               "height", G_TYPE_INT, height,
+                                               NULL);
+
+       } else {
+               LOG_ERROR_IF_REACHED("source->media_types(0x%x)", source->media_types);
+       }
+
+       return caps;
+}
+
 /* Use g_free() to free the media_type parameter. */
-static GstCaps *__make_default_encoded_caps(webrtc_media_source_type_e type, webrtc_ini_s *ini, gchar **media_type)
+static GstCaps *__make_default_encoded_caps(webrtc_gst_slot_s *source, webrtc_ini_s *ini, gchar **media_type)
 {
        GstCaps *caps;
-       ini_item_media_source_s *source;
+       ini_item_media_source_s *ini_source;
        const char *_media_type;
 
+       RET_VAL_IF(source == NULL, NULL, "source is NULL");
        RET_VAL_IF(ini == NULL, NULL, "ini is NULL");
 
-       source = _ini_get_source_by_type(ini, type);
-       if (source == NULL)
-               source = &ini->media_source;
+       ini_source = _ini_get_source_by_type(ini, source->type);
+       if (ini_source == NULL)
+               ini_source = &ini->media_source;
 
-       switch (type) {
+       switch (source->type) {
        case WEBRTC_MEDIA_SOURCE_TYPE_CAMERA:
        case WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST:
-               _media_type = __get_video_media_type(source->v_codec);
+               _media_type = __get_video_media_type(ini_source->v_codec);
                caps = gst_caps_new_simple(_media_type,
-                                               "framerate", GST_TYPE_FRACTION, source->v_framerate, 1,
-                                               "width", G_TYPE_INT, source->v_width,
-                                               "height", G_TYPE_INT, source->v_height,
+                                               "framerate", GST_TYPE_FRACTION, ini_source->v_framerate, 1,
+                                               "width", G_TYPE_INT, ini_source->v_width,
+                                               "height", G_TYPE_INT, ini_source->v_height,
                                                NULL);
                break;
 
        case WEBRTC_MEDIA_SOURCE_TYPE_MIC:
        case WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST:
-               _media_type = __get_audio_media_type(source->a_codec);
+               _media_type = __get_audio_media_type(ini_source->a_codec);
                caps = gst_caps_new_simple(_media_type,
-                                               "channels", G_TYPE_INT, source->a_channels,
-                                               "rate", G_TYPE_INT, source->a_samplerate,
+                                               "channels", G_TYPE_INT, ini_source->a_channels,
+                                               "rate", G_TYPE_INT, ini_source->a_samplerate,
                                                NULL);
                break;
 
+       case WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET: {
+               if (source->media_types == MEDIA_TYPE_AUDIO) {
+                       _media_type = __get_audio_media_type(ini_source->a_codec);
+                       caps = gst_caps_new_simple(_media_type,
+                                                       "channels", G_TYPE_INT, ini_source->a_channels,
+                                                       "rate", G_TYPE_INT, ini_source->a_samplerate,
+                                                       NULL);
+
+               } else if (source->media_types == MEDIA_TYPE_VIDEO) {
+                       _media_type = __get_video_media_type(ini_source->v_codec);
+                       caps = gst_caps_new_simple(_media_type,
+                                                       "framerate", GST_TYPE_FRACTION, ini_source->v_framerate, 1,
+                                                       "width", G_TYPE_INT, ini_source->v_width,
+                                                       "height", G_TYPE_INT, ini_source->v_height,
+                                                       NULL);
+
+               } else {
+                       LOG_ERROR_IF_REACHED("source->media_types(0x%x)", source->media_types);
+                       return NULL;
+               }
+
+               break;
+       }
+
        default:
-               LOG_ERROR_IF_REACHED("type(%d)", type);
+               LOG_ERROR_IF_REACHED("type(%d)", source->type);
                return NULL;
        }
 
@@ -274,7 +419,7 @@ static GstElement *__get_hw_encoder_element(webrtc_s *webrtc, webrtc_media_sourc
        return NULL;
 }
 
-static int __create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source, webrtc_media_source_type_e type,
+static int __create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source,
        GstElement **capsfilter, GstElement **encoder, GstElement **payloader, GstElement **queue, GstElement **capsfilter2)
 {
        GstCaps *sink_caps;
@@ -284,42 +429,47 @@ static int __create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source
 
        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(capsfilter == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "capsfilter is NULL");
        RET_VAL_IF(encoder == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "encoder is NULL");
        RET_VAL_IF(payloader == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "payloader is NULL");
        RET_VAL_IF(queue == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "queue is NULL");
        RET_VAL_IF(capsfilter2 == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "capsfilter2 is NULL");
 
-       if (!(*capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, NULL))) {
-               LOG_ERROR("failed to create capsfilter");
-               return WEBRTC_ERROR_INVALID_OPERATION;
-       }
-       if ((sink_caps = __make_default_raw_caps(type, &webrtc->ini))) {
-               gchar *caps_str = gst_caps_to_string(sink_caps);
-               LOG_INFO("capsfilter caps[%s]", caps_str);
-               g_free(caps_str);
+       if (capsfilter) {
+               if (!(*capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, NULL))) {
+                       LOG_ERROR("failed to create capsfilter");
+                       return WEBRTC_ERROR_INVALID_OPERATION;
+               }
+               if ((sink_caps = __make_default_raw_caps(source, &webrtc->ini))) {
+                       gchar *caps_str = gst_caps_to_string(sink_caps);
+                       LOG_INFO("capsfilter caps[%s]", caps_str);
+                       g_free(caps_str);
 
-               g_object_set(G_OBJECT(*capsfilter), "caps", sink_caps, NULL);
-               gst_caps_unref(sink_caps);
+                       g_object_set(G_OBJECT(*capsfilter), "caps", sink_caps, NULL);
+                       gst_caps_unref(sink_caps);
+               }
        }
 
-       if (type == WEBRTC_MEDIA_SOURCE_TYPE_CAMERA || type == WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST)
+       if (source->media_types == MEDIA_TYPE_VIDEO) {
                encoder_klass_name = GST_KLASS_NAME_ENCODER_VIDEO;
-       else
+       } else if (source->media_types == MEDIA_TYPE_AUDIO) {
                encoder_klass_name = GST_KLASS_NAME_ENCODER_AUDIO;
+       } else {
+               LOG_ERROR("not ready for this media_types[0x%x]", source->media_types);
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
 
-       *encoder = __get_hw_encoder_element(webrtc, type);
+       *encoder = __get_hw_encoder_element(webrtc, source->type);
        if (*encoder == NULL) {
                CREATE_ELEMENT_FROM_REGISTRY(elem_info, encoder_klass_name,
-                                                       __make_default_raw_caps(type, &webrtc->ini),
-                                                       __make_default_encoded_caps(type, &webrtc->ini, NULL),
+                                                       __make_default_raw_caps(source, &webrtc->ini),
+                                                       __make_default_encoded_caps(source, &webrtc->ini, NULL),
                                                        *encoder);
                if (*encoder == NULL)
                        return WEBRTC_ERROR_INVALID_OPERATION;
        }
 
        CREATE_ELEMENT_FROM_REGISTRY(elem_info, GST_KLASS_NAME_PAYLOADER_RTP,
-                                               __make_default_encoded_caps(type, &webrtc->ini, &media_type),
+                                               __make_default_encoded_caps(source, &webrtc->ini, &media_type),
                                                NULL,
                                                *payloader);
        if (*payloader == NULL) {
@@ -360,6 +510,8 @@ static const char *__get_default_element(webrtc_media_source_type_e type)
                element = DEFAULT_ELEMENT_AUDIOTESTSRC;
        else if (type == WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST)
                element = DEFAULT_ELEMENT_VIDEOTESTSRC;
+       else if (type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET)
+               element = DEFAULT_ELEMENT_APPSRC;
        else
                LOG_ERROR_IF_REACHED("type(%d)", type);
 
@@ -381,7 +533,7 @@ static const char *__get_source_element(webrtc_s *webrtc, webrtc_media_source_ty
        return source->source_element;
 }
 
-static int __build_camerasrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, GstPad *ghost_src_pad)
+static int __build_camerasrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
 {
        int ret = WEBRTC_ERROR_NONE;
        GstElement *camerasrc;
@@ -393,10 +545,10 @@ static int __build_camerasrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, GstPad
 
        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(ghost_src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "ghost_src_pad is NULL");
        RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
+       RET_VAL_IF(source->src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "src_pad is NULL");
 
-       source->media_types |= MEDIA_TYPE_VIDEO;
+       source->media_types = MEDIA_TYPE_VIDEO;
 
        if (!(camerasrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_CAMERA), NULL))) {
                LOG_ERROR("failed to create camerasrc");
@@ -404,7 +556,7 @@ static int __build_camerasrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, GstPad
        }
        /* FIXME: set camera default setting from ini */
 
-       if ((ret = __create_rest_of_elements(webrtc, source, WEBRTC_MEDIA_SOURCE_TYPE_CAMERA, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
+       if ((ret = __create_rest_of_elements(webrtc, source, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
                return ret;
 
        gst_bin_add_many(GST_BIN(source->bin), camerasrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL);
@@ -413,10 +565,10 @@ static int __build_camerasrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, GstPad
                return WEBRTC_ERROR_INVALID_OPERATION;
        }
 
-       return _set_ghost_pad_target(ghost_src_pad, capsfilter2, true);
+       return _set_ghost_pad_target(source->src_pad, capsfilter2, true);
 }
 
-static int __build_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, GstPad *ghost_src_pad)
+static int __build_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
 {
        int ret = WEBRTC_ERROR_NONE;
        GstElement *audiosrc;
@@ -428,17 +580,17 @@ static int __build_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, GstPad
 
        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(ghost_src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "ghost_src_pad is NULL");
        RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
+       RET_VAL_IF(source->src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "src_pad is NULL");
 
-       source->media_types |= MEDIA_TYPE_AUDIO;
+       source->media_types = MEDIA_TYPE_AUDIO;
 
        if (!(audiosrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_MIC), NULL))) {
                LOG_ERROR("failed to create audiosrc");
                return WEBRTC_ERROR_INVALID_OPERATION;
        }
 
-       if ((ret = __create_rest_of_elements(webrtc, source, WEBRTC_MEDIA_SOURCE_TYPE_MIC, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
+       if ((ret = __create_rest_of_elements(webrtc, source, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
                return ret;
 
        gst_bin_add_many(GST_BIN(source->bin), audiosrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL);
@@ -447,10 +599,10 @@ static int __build_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, GstPad
                return WEBRTC_ERROR_INVALID_OPERATION;
        }
 
-       return _set_ghost_pad_target(ghost_src_pad, capsfilter2, true);
+       return _set_ghost_pad_target(source->src_pad, capsfilter2, true);
 }
 
-static int __build_videotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, GstPad *ghost_src_pad)
+static int __build_videotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
 {
        int ret = WEBRTC_ERROR_NONE;
        GstElement *videotestsrc;
@@ -462,10 +614,10 @@ static int __build_videotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, Gst
 
        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(ghost_src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "ghost_src_pad is NULL");
        RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
+       RET_VAL_IF(source->src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "src_pad is NULL");
 
-       source->media_types |= MEDIA_TYPE_VIDEO;
+       source->media_types = MEDIA_TYPE_VIDEO;
 
        if (!(videotestsrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST), NULL))) {
                LOG_ERROR("failed to create videotestsrc");
@@ -473,7 +625,7 @@ static int __build_videotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, Gst
        }
        g_object_set(G_OBJECT(videotestsrc), "is-live", TRUE, "pattern", 18, NULL); /* 18: ball */
 
-       if ((ret = __create_rest_of_elements(webrtc, source, WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
+       if ((ret = __create_rest_of_elements(webrtc, source, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
                return ret;
 
        gst_bin_add_many(GST_BIN(source->bin), videotestsrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL);
@@ -482,10 +634,10 @@ static int __build_videotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, Gst
                return WEBRTC_ERROR_INVALID_OPERATION;
        }
 
-       return _set_ghost_pad_target(ghost_src_pad, capsfilter2, true);
+       return _set_ghost_pad_target(source->src_pad, capsfilter2, true);
 }
 
-static int __build_audiotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, GstPad *ghost_src_pad)
+static int __build_audiotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
 {
        int ret = WEBRTC_ERROR_NONE;
        GstElement *audiotestsrc;
@@ -497,10 +649,10 @@ static int __build_audiotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, Gst
 
        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(ghost_src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "ghost_src_pad is NULL");
        RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
+       RET_VAL_IF(source->src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "src_pad is NULL");
 
-       source->media_types |= MEDIA_TYPE_AUDIO;
+       source->media_types = MEDIA_TYPE_AUDIO;
 
        if (!(audiotestsrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST), NULL))) {
                LOG_ERROR("failed to create audiotestsrc");
@@ -508,7 +660,7 @@ static int __build_audiotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, Gst
        }
        g_object_set(G_OBJECT(audiotestsrc), "is-live", TRUE, NULL);
 
-       if ((ret = __create_rest_of_elements(webrtc, source, WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
+       if ((ret = __create_rest_of_elements(webrtc, source, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
                return ret;
 
        gst_bin_add_many(GST_BIN(source->bin), audiotestsrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL);
@@ -517,36 +669,148 @@ static int __build_audiotestsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source, Gst
                return WEBRTC_ERROR_INVALID_OPERATION;
        }
 
-       return _set_ghost_pad_target(ghost_src_pad, capsfilter2, true);
+       return _set_ghost_pad_target(source->src_pad, capsfilter2, true);
 }
 
-static int __build_source_bin(webrtc_s *webrtc, webrtc_gst_slot_s *source, webrtc_media_source_type_e type)
+static void _appsrc_need_data_cb(GstElement *appsrc, guint size, gpointer data)
+{
+       webrtc_gst_slot_s *source = (webrtc_gst_slot_s*)data;
+
+       RET_IF(source == NULL, "source is NULL");
+
+       LOG_INFO("appsrc[%s] size[%u] source[%p, idx:%u]", GST_ELEMENT_NAME(appsrc), size, source, source->id);
+}
+
+static void _appsrc_enough_data_cb(GstElement *appsrc, gpointer data)
+{
+       webrtc_gst_slot_s *source = (webrtc_gst_slot_s*)data;
+
+       RET_IF(source == NULL, "source is NULL");
+
+       LOG_INFO("appsrc[%s] source[%p, idx:%u]", GST_ELEMENT_NAME(appsrc), source, source->id);
+}
+
+static int __build_mediapacketsrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
+{
+       GstElement *appsrc;
+
+       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->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
+
+       if (!(appsrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET), NULL))) {
+               LOG_ERROR("failed to create appsrc");
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
+       g_object_set(G_OBJECT(appsrc), "emit-signals", TRUE, "is-live", TRUE, NULL);
+
+       _connect_and_append_signal(&source->signals, G_OBJECT(appsrc), "need-data", G_CALLBACK(_appsrc_need_data_cb), source);
+       _connect_and_append_signal(&source->signals, G_OBJECT(appsrc), "enough-data", G_CALLBACK(_appsrc_enough_data_cb), source);
+
+       gst_bin_add(GST_BIN(source->bin), appsrc);
+
+       return WEBRTC_ERROR_NONE;
+}
+
+static GstElement *__find_element_in_bin(GstElement *bin, const gchar *name)
+{
+       GValue value = G_VALUE_INIT;
+       GstElement *element;
+       GstIterator *bin_iterator;
+
+       RET_VAL_IF(bin == NULL, NULL, "bin is NULL");
+       RET_VAL_IF(name == NULL, NULL, "name is NULL");
+
+       bin_iterator = gst_bin_iterate_sorted(GST_BIN(bin));
+
+       while (GST_ITERATOR_OK == gst_iterator_next(bin_iterator, &value)) {
+               element = GST_ELEMENT(g_value_get_object(&value));
+
+               if (g_strrstr(GST_ELEMENT_NAME(element), name)) {
+                       LOG_DEBUG("found element by name [%s]", GST_ELEMENT_NAME(element));
+                       gst_iterator_free(bin_iterator);
+                       return element;
+               }
+
+               g_value_reset(&value);
+       }
+
+       gst_iterator_free(bin_iterator);
+
+       return NULL;
+}
+
+static int __complete_mediapacketsrc_from_raw_format(webrtc_s *webrtc, webrtc_gst_slot_s *source)
+{
+       int ret = WEBRTC_ERROR_NONE;
+       GstElement *appsrc;
+       GstElement *encoder;
+       GstElement *payloader;
+       GstElement *queue;
+       GstElement *capsfilter;
+       GstCaps *sink_caps;
+       gchar *caps_str;
+
+       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->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
+       RET_VAL_IF(source->src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "src_pad is NULL");
+
+       appsrc = __find_element_in_bin(source->bin, "appsrc");
+       RET_VAL_IF(appsrc == NULL, WEBRTC_ERROR_INVALID_OPERATION, "appsrc is NULL");
+
+       if (!(sink_caps = __make_raw_caps_from_media_format(source))) {
+               LOG_ERROR("failed to __make_raw_caps_from_media_format()");
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
+       caps_str = gst_caps_to_string(sink_caps);
+       LOG_INFO("appsrc caps[%s]", caps_str);
+       g_free(caps_str);
+
+       g_object_set(G_OBJECT(appsrc), "caps", sink_caps, NULL);
+       gst_caps_unref(sink_caps);
+
+       if ((ret = __create_rest_of_elements(webrtc, source, NULL, &encoder, &payloader, &queue, &capsfilter)) != WEBRTC_ERROR_NONE)
+               return ret;
+
+       gst_bin_add_many(GST_BIN(source->bin), encoder, payloader, queue, capsfilter, NULL);
+       if (!gst_element_link_many(appsrc, encoder, payloader, queue, capsfilter, NULL)) {
+               LOG_ERROR("failed to gst_element_link_many()");
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
+
+       return _set_ghost_pad_target(source->src_pad, capsfilter, true);
+}
+
+static int __build_source_bin(webrtc_s *webrtc, webrtc_gst_slot_s *source)
 {
        int ret = WEBRTC_ERROR_NONE;
-       GstPad *src_pad;
 
        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->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
 
-       ret = _add_no_target_ghostpad_to_slot(source, true, &src_pad);
+       ret = _add_no_target_ghostpad_to_slot(source, true, &source->src_pad);
        RET_VAL_IF(ret != WEBRTC_ERROR_NONE, ret, "failed to _add_no_target_ghostpad_to_slot()");
 
-       switch (type) {
+       switch (source->type) {
        case WEBRTC_MEDIA_SOURCE_TYPE_CAMERA:
-               return __build_camerasrc(webrtc, source, src_pad);
+               return __build_camerasrc(webrtc, source);
 
        case WEBRTC_MEDIA_SOURCE_TYPE_MIC:
-               return __build_audiosrc(webrtc, source, src_pad);
+               return __build_audiosrc(webrtc, source);
 
        case WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST:
-               return __build_videotestsrc(webrtc, source, src_pad);
+               return __build_videotestsrc(webrtc, source);
 
        case WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST:
-               return __build_audiotestsrc(webrtc, source, src_pad);
+               return __build_audiotestsrc(webrtc, source);
+
+       case WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET:
+               return __build_mediapacketsrc(webrtc, source);
 
        default:
-               LOG_ERROR_IF_REACHED("type(%d)", type);
+               LOG_ERROR_IF_REACHED("type(%d)", source->type);
                return WEBRTC_ERROR_INVALID_PARAMETER;
        }
 
@@ -609,6 +873,9 @@ void _source_slot_destroy_cb(gpointer data)
 
        gst_bin_remove(GST_BIN(gst_element_get_parent(source->bin)), source->bin);
 
+       if (source->media_format)
+               media_format_unref(source->media_format);
+
        g_free(source);
 }
 
@@ -633,8 +900,9 @@ int _add_media_source(webrtc_s *webrtc, webrtc_media_source_type_e type, unsigne
        bin_name = g_strdup_printf("media_source_%u", id);
 
        MALLOC_AND_INIT_SLOT(source, id, bin_name, webrtc->gst.webrtcbin);
+       source->type = type;
 
-       ret = __build_source_bin(webrtc, source, type);
+       ret = __build_source_bin(webrtc, source);
        if (ret != WEBRTC_ERROR_NONE) {
                LOG_ERROR("failed to __build_source_bin()");
                goto error;
@@ -710,3 +978,54 @@ int _remove_media_source(webrtc_s *webrtc, unsigned int source_id)
 
        return ret;
 }
+
+int _set_media_format(webrtc_s *webrtc, unsigned int source_id, media_format_h format)
+{
+       int ret;
+       webrtc_gst_slot_s *source;
+       media_format_type_e format_type;
+       media_format_mimetype_e mime_type;
+
+       RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+       RET_VAL_IF(format == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "format is NULL");
+       RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "could not find source");
+       RET_VAL_IF(!__find_element_in_bin(source->bin, "appsrc"), WEBRTC_ERROR_INVALID_PARAMETER, "source_id[%u] is not for media packet source", source_id);
+       RET_VAL_IF(source->media_format != NULL, WEBRTC_ERROR_INVALID_OPERATION, "format is already set to this media packet source");
+
+       RET_VAL_IF(media_format_get_type(format, &format_type) != MEDIA_FORMAT_ERROR_NONE, WEBRTC_ERROR_INVALID_OPERATION,
+               "failed to media_format_get_type()");
+
+       if (format_type == MEDIA_FORMAT_AUDIO) {
+               source->media_types = MEDIA_TYPE_AUDIO;
+               RET_VAL_IF(media_format_get_audio_info(format, &mime_type, NULL, NULL, NULL, NULL) != MEDIA_FORMAT_ERROR_NONE,
+                       WEBRTC_ERROR_INVALID_OPERATION, "failed to media_format_get_audio_info()");
+
+       } else if (format_type == MEDIA_FORMAT_VIDEO) {
+               source->media_types = MEDIA_TYPE_VIDEO;
+               RET_VAL_IF(media_format_get_video_info(format, &mime_type, NULL, NULL, NULL, NULL) != MEDIA_FORMAT_ERROR_NONE,
+                       WEBRTC_ERROR_INVALID_OPERATION, "failed to media_format_get_video_info()");
+
+       } else {
+               LOG_ERROR("invalid media format type[0x%x]", format_type);
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
+
+       RET_VAL_IF(!__is_supported_mime_type(mime_type), WEBRTC_ERROR_INVALID_PARAMETER, "mime_type[0x%x] is not supported", mime_type);
+
+       media_format_ref(format);
+       source->media_format = format;
+
+       if (mime_type & MEDIA_FORMAT_RAW)
+               ret = __complete_mediapacketsrc_from_raw_format(webrtc, source);
+       else
+               ret = WEBRTC_ERROR_INVALID_OPERATION;  /* TODO: implementation */
+
+       if (ret != WEBRTC_ERROR_NONE) {
+               LOG_ERROR("failed to complete mediapacketsrc");
+               media_format_unref(format);
+               source->media_format = NULL;
+               return ret;
+       }
+
+       return WEBRTC_ERROR_NONE;
+}
\ No newline at end of file