in source/src/AppRtspSrc.c [608:703]
static void onRtspSrcPadAdded(GstElement* element, GstPad* pad, gpointer udata)
{
STATUS retStatus = STATUS_SUCCESS;
PRtspSrcContext pRtspSrcContext = (PRtspSrcContext) udata;
PCodecConfiguration pGstConfiguration;
PCodecStreamConf pCodecStreamConf = NULL;
GstElement* pipeline = NULL;
gchar* srcPadName = NULL;
GstCaps* srcPadTemplateCaps = NULL;
GstCaps* srcPadCurrentCaps = NULL;
GstStructure* srcPadStructure = NULL;
GstElement* nextElement = NULL;
guint curCapsNum = 0;
gint payloadType = 0;
BOOL video = FALSE;
BOOL audio = FALSE;
BOOL locked = FALSE;
guint i;
CHK((element != NULL) && (pad != NULL) && (pRtspSrcContext != NULL), STATUS_MEDIA_NULL_ARG);
pGstConfiguration = &pRtspSrcContext->codecConfiguration;
pipeline = (GstElement*) pGstConfiguration->pipeline;
MUTEX_LOCK(pRtspSrcContext->codecConfLock);
locked = TRUE;
srcPadName = app_gst_pad_get_name(pad);
srcPadTemplateCaps = app_gst_pad_get_pad_template_caps(pad);
DLOGD("a new pad template %s was created", srcPadName);
srcPadCurrentCaps = app_gst_pad_get_current_caps(pad);
curCapsNum = app_gst_caps_get_size(srcPadCurrentCaps);
for (i = 0; i < curCapsNum; i++) {
srcPadStructure = app_gst_caps_get_structure(srcPadCurrentCaps, i);
if (app_gst_structure_has_field(srcPadStructure, GST_STRUCT_FIELD_MEDIA) == TRUE) {
const gchar* media_value = app_gst_structure_get_string(srcPadStructure, GST_STRUCT_FIELD_MEDIA);
DLOGD("media_value:%s", media_value);
if (STRCMP(media_value, GST_STRUCT_FIELD_MEDIA_VIDEO) == 0) {
video = TRUE;
pCodecStreamConf = &pGstConfiguration->videoStream;
} else if (STRCMP(media_value, GST_STRUCT_FIELD_MEDIA_AUDIO) == 0) {
audio = TRUE;
pCodecStreamConf = &pGstConfiguration->audioStream;
} else {
continue;
}
if (app_gst_structure_has_field(srcPadStructure, GST_STRUCT_FIELD_PAYLOAD_TYPE) == TRUE) {
app_gst_structure_get_int(srcPadStructure, GST_STRUCT_FIELD_PAYLOAD_TYPE, &payloadType);
DLOGD("payload type:%d", payloadType);
}
if (video == TRUE && pCodecStreamConf->payloadType == payloadType) {
DLOGD("connecting video sink");
CHK_STATUS((createVideoAppSink(pRtspSrcContext, &nextElement, srcPadName)));
} else if (audio == TRUE && pCodecStreamConf->payloadType == payloadType) {
DLOGD("connecting audio sink");
CHK_STATUS((createAudioAppSink(pRtspSrcContext, &nextElement, srcPadName)));
} else {
DLOGW("payload type conflicts, and connecting dummy sink");
CHK_STATUS((createDummyAppSink(pRtspSrcContext, &nextElement, srcPadName)));
}
}
}
CHK(nextElement != NULL, STATUS_MEDIA_EMPTY_ELEMENT);
CHK(app_gst_element_link_filtered(element, nextElement, srcPadTemplateCaps) == TRUE, STATUS_MEDIA_LINK_ELEMENT);
CHK(app_gst_element_set_state(pipeline, GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE, STATUS_MEDIA_PLAY);
CleanUp:
if (locked) {
MUTEX_UNLOCK(pRtspSrcContext->codecConfLock);
}
if (srcPadName != NULL) {
app_g_free(srcPadName);
}
if (srcPadCurrentCaps != NULL) {
app_gst_caps_unref(srcPadCurrentCaps);
}
if (srcPadTemplateCaps != NULL) {
app_gst_caps_unref(srcPadTemplateCaps);
}
if (STATUS_FAILED(retStatus)) {
DLOGE("operation returned status code: 0x%08x", retStatus);
if (nextElement != NULL) {
app_gst_object_unref(nextElement);
}
if (pRtspSrcContext != NULL) {
closeGstRtspSrc(pRtspSrcContext);
updateCodecStatus(pRtspSrcContext, STATUS_MEDIA_BUS_ERROR);
}
}
}