#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"
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;
}
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;
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) {
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);
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;
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");
}
/* 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);
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;
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);
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;
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");
}
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);
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;
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");
}
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);
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;
}
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);
}
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;
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