in source/src/AppRtspSrc.c [471:583]
static void onRtspSrcPadAddedDiscovery(GstElement* element, GstPad* pad, gpointer udata)
{
STATUS retStatus = STATUS_SUCCESS;
PRtspSrcContext pRtspSrcContext = (PRtspSrcContext) udata;
PCodecConfiguration pGstConfiguration = NULL;
PCodecStreamConf pCodecStreamConf = NULL;
BOOL video = FALSE;
BOOL audio = FALSE;
// gstreamer
gchar* srcPadName = NULL;
GstCaps* srcPadTemplateCaps = NULL;
GstCaps* srcPadCurrentCaps = NULL;
GstStructure* srcPadStructure = NULL;
GstElement* nextElement = NULL;
gchar* media = NULL;
guint curCapsNum;
BOOL locked = FALSE;
guint i;
CHK((element != NULL) && (pad != NULL) && (pRtspSrcContext != NULL), STATUS_MEDIA_NULL_ARG);
pGstConfiguration = &pRtspSrcContext->codecConfiguration;
srcPadName = app_gst_pad_get_name(pad);
srcPadTemplateCaps = app_gst_pad_get_pad_template_caps(pad);
DLOGD("new pad template %s was created", srcPadName);
srcPadCurrentCaps = app_gst_pad_get_current_caps(pad);
curCapsNum = app_gst_caps_get_size(srcPadCurrentCaps);
MUTEX_LOCK(pRtspSrcContext->codecConfLock);
locked = TRUE;
for (i = 0; i < curCapsNum; i++) {
srcPadStructure = app_gst_caps_get_structure(srcPadCurrentCaps, i);
pCodecStreamConf = NULL;
if (app_gst_structure_has_field(srcPadStructure, GST_STRUCT_FIELD_MEDIA) == TRUE &&
app_gst_structure_has_field(srcPadStructure, GST_STRUCT_FIELD_ENCODING) == TRUE) {
media = app_gst_structure_get_string(srcPadStructure, GST_STRUCT_FIELD_MEDIA);
const gchar* encoding_name = app_gst_structure_get_string(srcPadStructure, GST_STRUCT_FIELD_ENCODING);
DLOGD("media:%s, encoding_name:%s", media, encoding_name);
if (STRCMP(media, GST_STRUCT_FIELD_MEDIA_VIDEO) == 0) {
video = TRUE;
pCodecStreamConf = &pGstConfiguration->videoStream;
// h264
if (STRCMP(encoding_name, GST_STRUCT_FIELD_ENCODING_H264) == 0) {
pCodecStreamConf->codec = RTC_CODEC_H264_PROFILE_42E01F_LEVEL_ASYMMETRY_ALLOWED_PACKETIZATION_MODE;
// vp8
} else if (STRCMP(encoding_name, GST_STRUCT_FIELD_ENCODING_VP8) == 0) {
pCodecStreamConf->codec = RTC_CODEC_VP8;
// others
} else {
DLOGW("unsupported video format");
continue;
}
} else if (STRCMP(media, GST_STRUCT_FIELD_MEDIA_AUDIO) == 0) {
audio = TRUE;
pCodecStreamConf = &pGstConfiguration->audioStream;
if (STRCMP(encoding_name, GST_STRUCT_FIELD_ENCODING_PCMU) == 0) {
pCodecStreamConf->codec = RTC_CODEC_MULAW;
} else if (STRCMP(encoding_name, GST_STRUCT_FIELD_ENCODING_PCMA) == 0) {
pCodecStreamConf->codec = RTC_CODEC_ALAW;
} else if (STRCMP(encoding_name, GST_STRUCT_FIELD_ENCODING_OPUS) == 0) {
pCodecStreamConf->codec = RTC_CODEC_OPUS;
} else {
DLOGW("unsupported audio format");
continue;
}
} else {
DLOGW("unsupported media format");
continue;
}
DLOGD("codec:%d", pCodecStreamConf->codec);
if (app_gst_structure_has_field(srcPadStructure, GST_STRUCT_FIELD_PAYLOAD_TYPE) == TRUE) {
gint payloadType;
app_gst_structure_get_int(srcPadStructure, GST_STRUCT_FIELD_PAYLOAD_TYPE, &payloadType);
DLOGD("payload:%d", payloadType);
pCodecStreamConf->payloadType = payloadType;
}
if (app_gst_structure_has_field(srcPadStructure, GST_STRUCT_FIELD_CLOCK_RATE) == TRUE) {
gint clock_rate;
app_gst_structure_get_int(srcPadStructure, GST_STRUCT_FIELD_CLOCK_RATE, &clock_rate);
DLOGD("clock-rate:%d", clock_rate);
pCodecStreamConf->clockRate = clock_rate;
}
}
}
CHK_STATUS((createDummyAppSink(pRtspSrcContext, &nextElement, media)));
CHK(app_gst_element_link_filtered(element, nextElement, srcPadTemplateCaps) == TRUE, STATUS_MEDIA_LINK_ELEMENT);
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);
}
}
}