int ms_ticker_attach_multiple(MSTicker *ticker,MSFilter *f,...) { MSList *sources=NULL; MSList *filters=NULL; MSList *it; MSList *total_sources=NULL; va_list l; va_start(l,f); do{ if (f->ticker==NULL) { filters=ms_filter_find_neighbours(f); sources=get_sources(filters); if (sources==NULL){ ms_fatal("No sources found around filter %s",f->desc->name); ms_list_free(filters); break; } /*run preprocess on each filter: */ for(it=filters;it!=NULL;it=it->next) ms_filter_preprocess((MSFilter*)it->data,ticker); ms_list_free(filters); total_sources=ms_list_concat(total_sources,sources); }else ms_message("Filter %s is already being scheduled; nothing to do.",f->desc->name); }while ((f=va_arg(l,MSFilter*))!=NULL); va_end(l); if (total_sources){ ms_mutex_lock(&ticker->lock); ticker->execution_list=ms_list_concat(ticker->execution_list,total_sources); ms_mutex_unlock(&ticker->lock); } return 0; }
int ms_ticker_attach(MSTicker *ticker,MSFilter *f) { MSList *sources=NULL; MSList *filters=NULL; MSList *it; if (f->ticker!=NULL) { ms_message("Filter %s is already being scheduled; nothing to do.",f->desc->name); return 0; } find_filters(&filters,f); sources=get_sources(filters); if (sources==NULL){ ms_fatal("No sources found around filter %s",f->desc->name); ms_list_free(filters); return -1; } /*run preprocess on each filter: */ for(it=filters;it!=NULL;it=it->next) ms_filter_preprocess((MSFilter*)it->data,ticker); ms_mutex_lock(&ticker->lock); ticker->execution_list=ms_list_concat(ticker->execution_list,sources); ms_mutex_unlock(&ticker->lock); ms_list_free(filters); return 0; }
/*this function must be called from the MSTicker thread: it replaces one filter by another one. This is a dirty hack that works anyway. It would be interesting to have something that does the job simplier within the MSTicker api */ void video_stream_change_decoder(VideoStream *stream, int payload){ RtpSession *session=stream->session; RtpProfile *prof=rtp_session_get_profile(session); PayloadType *pt=rtp_profile_get_payload(prof,payload); if (pt!=NULL){ MSFilter *dec=ms_filter_create_decoder(pt->mime_type); if (dec!=NULL){ ms_filter_unlink(stream->rtprecv, 0, stream->decoder, 0); ms_filter_unlink(stream->decoder,0,stream->output,0); ms_filter_postprocess(stream->decoder); ms_filter_destroy(stream->decoder); stream->decoder=dec; if (pt->recv_fmtp!=NULL) ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp); ms_filter_link (stream->rtprecv, 0, stream->decoder, 0); ms_filter_link (stream->decoder,0 , stream->output, 0); ms_filter_preprocess(stream->decoder,stream->ticker); }else{ ms_warning("No decoder found for %s",pt->mime_type); } }else{ ms_warning("No payload defined with number %i",payload); } }
/** * This function must be called from the MSTicker thread: * it replaces one filter by another one. * This is a dirty hack that works anyway. * It would be interesting to have something that does the job * more easily within the MSTicker API. */ static void media_stream_change_decoder(MediaStream *stream, int payload) { RtpSession *session = stream->sessions.rtp_session; RtpProfile *prof = rtp_session_get_profile(session); PayloadType *pt = rtp_profile_get_payload(prof, payload); if (stream->decoder == NULL){ ms_message("media_stream_change_decoder(): ignored, no decoder."); return; } if (pt != NULL){ MSFilter *dec; if (stream->type == VideoStreamType){ /* Q: why only video ? this optimization seems relevant for audio too.*/ if ((stream->decoder != NULL) && (stream->decoder->desc->enc_fmt != NULL) && (strcasecmp(pt->mime_type, stream->decoder->desc->enc_fmt) == 0)) { /* Same formats behind different numbers, nothing to do. */ return; } } dec = ms_filter_create_decoder(pt->mime_type); if (dec != NULL) { MSFilter *nextFilter = stream->decoder->outputs[0]->next.filter; ms_filter_unlink(stream->rtprecv, 0, stream->decoder, 0); ms_filter_unlink(stream->decoder, 0, nextFilter, 0); ms_filter_postprocess(stream->decoder); ms_filter_destroy(stream->decoder); stream->decoder = dec; if (pt->recv_fmtp != NULL) ms_filter_call_method(stream->decoder, MS_FILTER_ADD_FMTP, (void *)pt->recv_fmtp); ms_filter_link(stream->rtprecv, 0, stream->decoder, 0); ms_filter_link(stream->decoder, 0, nextFilter, 0); ms_filter_preprocess(stream->decoder,stream->sessions.ticker); } else { ms_warning("No decoder found for %s", pt->mime_type); } } else { ms_warning("No payload defined with number %i", payload); } }
/*this function must be called from the MSTicker thread: it replaces one filter by another one. This is a dirty hack that works anyway. It would be interesting to have something that does the job simplier within the MSTicker api */ void video_stream_change_decoder(VideoStream *stream, int payload){ RtpSession *session=stream->session; RtpProfile *prof=rtp_session_get_profile(session); PayloadType *pt=rtp_profile_get_payload(prof,payload); if (pt!=NULL){ MSFilter *dec; if (stream->decoder!=NULL && stream->decoder->desc->enc_fmt!=NULL && strcasecmp(pt->mime_type,stream->decoder->desc->enc_fmt)==0){ /* same formats behind different numbers, nothing to do */ return; } dec=ms_filter_create_decoder(pt->mime_type); if (dec!=NULL){ ms_filter_unlink(stream->rtprecv, 0, stream->decoder, 0); if (stream->tee2) ms_filter_unlink(stream->decoder,0,stream->tee2,0); else if(stream->output) ms_filter_unlink(stream->decoder,0,stream->output,0); ms_filter_postprocess(stream->decoder); ms_filter_destroy(stream->decoder); stream->decoder=dec; if (pt->recv_fmtp!=NULL) ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp); ms_filter_link (stream->rtprecv, 0, stream->decoder, 0); if (stream->tee2) ms_filter_link(stream->decoder,0,stream->tee2,0); else if(stream->output) ms_filter_link (stream->decoder,0 , stream->output, 0); ms_filter_preprocess(stream->decoder,stream->ticker); ms_filter_set_notify_callback(dec, event_cb, stream); }else{ ms_warning("No decoder found for %s",pt->mime_type); } }else{ ms_warning("No payload defined with number %i",payload); } }