Exemplo n.º 1
0
static void receiver_process(MSFilter * f)
{
	ReceiverData *d = (ReceiverData *) f->data;
	mblk_t *m;
	uint32_t timestamp;
	if (d->session == NULL)
		return;
	
	if (d->reset_jb){
		ms_message("Reseting jitter buffer");
		rtp_session_resync(d->session);
		d->reset_jb=FALSE;
	}

	if (d->starting){
		PayloadType *pt=rtp_profile_get_payload(
			rtp_session_get_profile(d->session),
			rtp_session_get_recv_payload_type(d->session));
		if (pt && pt->type!=PAYLOAD_VIDEO)
			rtp_session_flush_sockets(d->session);
		d->starting=FALSE;
	}

	timestamp = (uint32_t) (f->ticker->time * (d->rate/1000));
	while ((m = rtp_session_recvm_with_ts(d->session, timestamp)) != NULL) {
		mblk_set_timestamp_info(m, rtp_get_timestamp(m));
		mblk_set_marker_info(m, rtp_get_markbit(m));
		mblk_set_cseq(m, rtp_get_seqnumber(m));
		rtp_get_payload(m,&m->b_rptr);		
		ms_queue_put(f->outputs[0], m);
	}
}
Exemplo n.º 2
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);
	}
}
Exemplo n.º 3
0
static int get_receiver_output_fmt(MSFilter *f, void *arg) {
	ReceiverData *d = (ReceiverData *) f->data;
	MSPinFormat *pinFmt = (MSPinFormat *)arg;
	PayloadType *pt = rtp_profile_get_payload(rtp_session_get_profile(d->session), rtp_session_get_send_payload_type(d->session));
	pinFmt->fmt = ms_factory_get_audio_format(f->factory, pt->mime_type, pt->clock_rate, pt->channels, NULL);
	return 0;
}
Exemplo n.º 4
0
/*returns TRUE if the packet is ok to be sent to output queue*/
static bool_t receiver_check_payload_type(MSFilter *f, ReceiverData *d, mblk_t *m){
	int ptn=rtp_get_payload_type(m);
	PayloadType *pt;
	if (ptn==d->current_pt) return TRUE;
	pt=rtp_profile_get_payload(rtp_session_get_profile(d->session), ptn);
	if (pt==NULL){
		ms_warning("Discarding packet with unknown payload type %i",ptn);
		return FALSE;
	}
	if (strcasecmp(pt->mime_type,"CN")==0){
		MSCngData cngdata;
		uint8_t *data=NULL;
		int datasize=rtp_get_payload(m, &data);
		if (data){
			if (datasize<= sizeof(cngdata.data)){
				memcpy(cngdata.data, data, datasize);
				cngdata.datasize=datasize;
				ms_filter_notify(f, MS_RTP_RECV_GENERIC_CN_RECEIVED, &cngdata);
			}else{
				ms_warning("CN packet has unexpected size %i", datasize);
			}
		}
		return FALSE;
	}
	d->current_pt = ptn;
	return TRUE;
}
Exemplo n.º 5
0
bool myAudioStream::init_filters(const QString & payload)
{
    /** Init filters **/
    stream->soundwrite = ms_snd_card_create_writer(playcard);
    RtpProfile *profile = rtp_session_get_profile(stream->session);
    PayloadType *pt;

    /* List all available payloads */
    QMap<QString,int> payloads;
    for (int i = 0; i < RTP_PROFILE_MAX_PAYLOADS; i++) {
        pt = rtp_profile_get_payload(profile,i);
        if (pt != 0) {
            QString payload(pt->mime_type);
            if (payloads.contains(payload)) {
                payload.append(" " + QString::number(pt->clock_rate));
            }
            payloads.insert(payload,i);
        }
    }

    if (!payloads.contains(payload)) {
        ms_error("Could not find payload %s", payload.toStdString().c_str());
        return false;
    }

    int payload_type_number = payloads.value(payload);
    /* Create filters */
    pt = rtp_profile_get_payload(profile,payload_type_number);
    stream->decoder = ms_filter_create_decoder(pt->mime_type);
    stream->rtprecv = ms_filter_new(MS_RTP_RECV_ID);
    stream->dtmfgen = ms_filter_new(MS_DTMF_GEN_ID);

    /** Configure filter options **/
    /* Set payload type to use when receiving */
    rtp_session_set_payload_type(stream->session, payload_type_number);
    /* Set session used by rtprecv */
    ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,stream->session);
    /* Setup soundwrite and decoder parameters */
    int sr = pt->clock_rate;
    int chan = pt->channels;
    if (ms_filter_call_method(stream->soundwrite, MS_FILTER_SET_SAMPLE_RATE, &sr) !=0 ) {
        ms_error("Problem setting sample rate on soundwrite filter!");
        return false;
    }
    if (ms_filter_call_method(stream->soundwrite, MS_FILTER_SET_NCHANNELS, &chan) != 0) {
        ms_error("Failed to set sample rate on soundwrite filter!");
        return false;
    }

    if (ms_filter_call_method(stream->decoder, MS_FILTER_SET_SAMPLE_RATE, &sr) != 0) {
        ms_error("Problem setting sample rate on decoder filter!");
        return false;
    }
    return true;
}
Exemplo n.º 6
0
static void receiver_preprocess(MSFilter * f){
	ReceiverData *d = (ReceiverData *) f->data;
	if (d->session){
		PayloadType *pt=rtp_profile_get_payload(
			rtp_session_get_profile(d->session),
			rtp_session_get_recv_payload_type(d->session));
		if (pt){
			if (pt->type!=PAYLOAD_VIDEO)
				rtp_session_flush_sockets(d->session);
		}
	}
}
Exemplo n.º 7
0
static int receiver_get_ch(MSFilter *f, void *arg) {
	ReceiverData *d = (ReceiverData *)f->data;
	PayloadType *pt;
	if (d->session==NULL) {
		ms_warning("MSRtpRecv: Could not obtain sample rate, session is not set.");
		return -1;
	}
	pt=rtp_profile_get_payload(rtp_session_get_profile(d->session), rtp_session_get_recv_payload_type(d->session));
	if (pt == NULL) {
		ms_warning("MSRtpRecv: could not obtain number of channels, payload type is unknown.");
		return -1;
	}
	*(int *)arg = pt->channels;
	return 0;
}
Exemplo n.º 8
0
static int sender_set_session(MSFilter * f, void *arg)
{
	SenderData *d = (SenderData *) f->data;
	RtpSession *s = (RtpSession *) arg;
	PayloadType *pt =
		rtp_profile_get_payload(rtp_session_get_profile(s),
								rtp_session_get_send_payload_type(s));
	if (pt != NULL) {
		d->rate = pt->clock_rate;
	} else {
		ms_warning("Sending undefined payload type ?");
	}
	d->session = s;
	return 0;
}
Exemplo n.º 9
0
static int receiver_set_session(MSFilter * f, void *arg)
{
	ReceiverData *d = (ReceiverData *) f->data;
	RtpSession *s = (RtpSession *) arg;
	PayloadType *pt;
	d->current_pt=rtp_session_get_recv_payload_type(s);
	pt = rtp_profile_get_payload(rtp_session_get_profile(s),d->current_pt);
	if (pt != NULL) {
		d->rate = pt->clock_rate;
	} else {
		ms_warning("receiver_set_session(): receiving undefined payload type %i ?",
		    rtp_session_get_recv_payload_type(s));
	}
	d->session = s;

	return 0;
}
Exemplo n.º 10
0
static int sender_set_session(MSFilter * f, void *arg)
{
	SenderData *d = (SenderData *) f->data;
	RtpSession *s = (RtpSession *) arg;
	PayloadType *pt =
		rtp_profile_get_payload(rtp_session_get_profile(s),
								rtp_session_get_send_payload_type(s));
	if (pt != NULL) {
		d->rate = pt->clock_rate;
		d->dtmf_duration=(default_dtmf_duration_ms*d->rate)/1000;
		d->dtmf_ts_step=(20*d->rate)/1000;
		send_stun_packet(s);
	} else {
		ms_warning("Sending undefined payload type ?");
	}
	d->session = s;
	return 0;
}
Exemplo n.º 11
0
static int receiver_get_sr(MSFilter *f, void *arg){
	ReceiverData *d = (ReceiverData *) f->data;
	PayloadType *pt;
	if (d->session==NULL) {
		ms_warning("Could not obtain sample rate, session is not set.");
		return -1;
	}
	pt=rtp_profile_get_payload(rtp_session_get_profile(d->session), rtp_session_get_recv_payload_type(d->session));
	if (pt != NULL) {
		if (strcasecmp(pt->mime_type,"G722")==0)
			*(int*)arg=16000;
		else
			*(int*)arg=pt->clock_rate;
	}else{
		ms_warning("Could not obtain sample rate, payload type is unknown.");
		return -1;
	}
	return 0;
}
Exemplo n.º 12
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
 * 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);
	}
}
Exemplo n.º 13
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;

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