static void onRtspSrcPadAdded()

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);
        }
    }
}