static void sender_process(MSFilter * f) { SenderData *d = (SenderData *) f->data; RtpSession *s = d->session; mblk_t *im; uint32_t timestamp; if (s == NULL){ ms_queue_flush(f->inputs[0]); return; } if (d->relay_session_id_size>0 && ( (f->ticker->time-d->last_rsi_time)>5000 || d->last_rsi_time==0) ) { ms_message("relay session id sent in RTCP APP"); rtp_session_send_rtcp_APP(s,0,"RSID",(const uint8_t *)d->relay_session_id,d->relay_session_id_size); d->last_rsi_time=f->ticker->time; } while ((im = ms_queue_get(f->inputs[0])) != NULL) { mblk_t *header; timestamp = get_cur_timestamp(f, mblk_get_timestamp_info(im)); ms_filter_lock(f); if (d->skip) { ms_debug("skipping.."); send_dtmf(f, d->skip_until-d->dtmf_duration, timestamp); d->dtmf_start = FALSE; if (!RTP_TIMESTAMP_IS_NEWER_THAN(timestamp, d->skip_until)) { freemsg(im); ms_filter_unlock(f); continue; } d->skip = FALSE; d->dtmf = 0; } if (d->skip == FALSE && d->mute_mic==FALSE){ int pt = mblk_get_payload_type(im); header = rtp_session_create_packet(s, 12, NULL, 0); if (pt>0) rtp_set_payload_type(header, pt); rtp_set_markbit(header, mblk_get_marker_info(im)); header->b_cont = im; rtp_session_sendm_with_ts(s, header, timestamp); } else{ freemsg(im); } if (d->dtmf != 0) { ms_debug("prepare to send RFC2833 dtmf."); d->skip_until = timestamp + d->dtmf_duration; d->skip = TRUE; d->dtmf_start = TRUE; } ms_filter_unlock(f); } }
static void _sender_process(MSFilter * f) { SenderData *d = (SenderData *) f->data; RtpSession *s = d->session; mblk_t *im; uint32_t timestamp; if (d->relay_session_id_size>0 && ( (f->ticker->time-d->last_rsi_time)>5000 || d->last_rsi_time==0) ) { ms_message("relay session id sent in RTCP APP"); rtp_session_send_rtcp_APP(s,0,"RSID",(const uint8_t *)d->relay_session_id,d->relay_session_id_size); d->last_rsi_time=f->ticker->time; } ms_filter_lock(f); im = ms_queue_get(f->inputs[0]); do { mblk_t *header; timestamp = get_cur_timestamp(f, im); if (d->dtmf != 0 && !d->skip) { ms_debug("prepare to send RFC2833 dtmf."); d->skip_until = timestamp + d->dtmf_duration; d->dtmf_ts_cur=timestamp; d->skip = TRUE; } if (d->skip) { uint32_t origin_ts=d->skip_until-d->dtmf_duration; if (RTP_TIMESTAMP_IS_NEWER_THAN(timestamp,d->dtmf_ts_cur)){ ms_debug("Sending RFC2833 packet, start_timestamp=%u, dtmf_ts_cur=%u",origin_ts,d->dtmf_ts_cur); send_dtmf(f, origin_ts); } } if (im){ if (d->skip == FALSE && d->mute_mic==FALSE){ header = rtp_session_create_packet(s, 12, NULL, 0); rtp_set_markbit(header, mblk_get_marker_info(im)); header->b_cont = im; rtp_session_sendm_with_ts(s, header, timestamp); }else{ freemsg(im); } } }while ((im = ms_queue_get(f->inputs[0])) != NULL); if (d->last_sent_time == -1) { if ((d->last_stun_sent_time == -1) || ((f->ticker->time - d->last_stun_sent_time) >= 500)) { d->last_stun_sent_time = f->ticker->time; } if (d->last_stun_sent_time == f->ticker->time) { send_stun_packet(s); } } ms_filter_unlock(f); }
/* remove payload header and aggregates fragmented packets */ static void dec_unpacketize(MSFilter *f, DecState *s, mblk_t *im, MSQueue *out){ int xbit = (im->b_rptr[0] & 0x80) >> 7; im->b_rptr++; if (xbit) { /* Ignore extensions if some are present */ int ibit = (im->b_rptr[0] & 0x80) >> 7; int lbit = (im->b_rptr[0] & 0x40) >> 6; int tbit = (im->b_rptr[0] & 0x20) >> 5; int kbit = (im->b_rptr[0] & 0x10) >> 4; int mbit = 0; if (ibit) { mbit = (im->b_rptr[1] & 0x80) >> 7; } im->b_rptr += (ibit + lbit + (tbit | kbit) + mbit); } /* end of frame bit ? */ if (mblk_get_marker_info(im)) { /* should be aggregated with previous packet ? */ if (s->curframe!=NULL){ /* same timestamp ? */ if (mblk_get_timestamp_info(im) == mblk_get_timestamp_info(s->curframe)) { concatb(s->curframe,im); msgpullup(s->curframe,-1); /* transmit complete frame */ ms_queue_put(out, s->curframe); s->curframe=NULL; } else { /* transmit partial frame */ ms_queue_put(out, s->curframe); s->curframe = NULL; /* transmit new one (be it complete or not) */ ms_queue_put(out, im); } } else { /* transmit new one (be it complete or not) */ ms_queue_put(out, im); } } else { if (s->curframe!=NULL) { /* append if same timestamp */ if (mblk_get_timestamp_info(im) == mblk_get_timestamp_info(s->curframe)) { concatb(s->curframe,im); } else { /* transmit partial frame */ ms_queue_put(out, s->curframe); s->curframe = im; } } else { s->curframe = im; } } }
/*process incoming rtp data and output NALUs, whenever possible*/ void rfc3984_unpack(Rfc3984Context *ctx, mblk_t *im, MSQueue *out){ uint8_t type=nal_header_get_type(im->b_rptr); uint8_t *p; if (im->b_cont) msgpullup(im,-1); if (type==TYPE_STAP_A){ ms_message("Receiving STAP-A"); /*split into nalus*/ uint16_t sz; uint8_t *buf=(uint8_t*)&sz; mblk_t *nal; for(p=im->b_rptr+1;p<im->b_wptr;){ buf[0]=p[0]; buf[1]=p[1]; sz=ntohs(sz); nal=dupb(im); p+=2; nal->b_rptr=p; p+=sz; nal->b_wptr=p; if (p>im->b_wptr){ ms_error("Malformed STAP-A packet"); freemsg(nal); break; } ms_queue_put(&ctx->q,nal); } freemsg(im); }else if (type==TYPE_FU_A){ ms_message("Receiving FU-A"); mblk_t *o=aggregate_fua(ctx,im); if (o) ms_queue_put(&ctx->q,o); }else{ /*single nal unit*/ ms_message("Receiving single NAL"); ms_queue_put(&ctx->q,im); } if (mblk_get_marker_info(im)){ /*end of frame, output everything*/ while(!ms_queue_empty(&ctx->q)){ ms_queue_put(out,ms_queue_get(&ctx->q)); } } }
/* remove payload header and aggregates fragmented packets */ static void dec_unpacketize(MSFilter *f, DecState *s, mblk_t *im, MSQueue *out){ im->b_rptr++; /* end of frame bit ? */ if (mblk_get_marker_info(im)) { /* should be aggregated with previous packet ? */ if (s->curframe!=NULL){ /* same timestamp ? */ if (mblk_get_timestamp_info(im) == mblk_get_timestamp_info(s->curframe)) { concatb(s->curframe,im); msgpullup(s->curframe,-1); /* transmit complete frame */ ms_queue_put(out, s->curframe); s->curframe=NULL; } else { /* transmit partial frame */ ms_queue_put(out, s->curframe); s->curframe = NULL; /* transmit new one (be it complete or not) */ ms_queue_put(out, im); } } else { /* transmit new one (be it complete or not) */ ms_queue_put(out, im); } } else { if (s->curframe!=NULL) { /* append if same timestamp */ if (mblk_get_timestamp_info(im) == mblk_get_timestamp_info(s->curframe)) { concatb(s->curframe,im); } else { /* transmit partial frame */ ms_queue_put(out, s->curframe); s->curframe = im; } } else { s->curframe = im; } } }
static void dec_process(MSFilter *f) { DecState *s = (DecState *)f->data; mblk_t *im; vpx_codec_err_t err; vpx_image_t *img; vpx_codec_iter_t iter = NULL; MSQueue frame; MSQueue mtofree_queue; Vp8RtpFmtFrameInfo frame_info; if (!s->ready){ ms_queue_flush(f->inputs[0]); return; } ms_filter_lock(f); ms_queue_init(&frame); ms_queue_init(&mtofree_queue); /* Unpack RTP payload format for VP8. */ vp8rtpfmt_unpacker_feed(&s->unpacker, f->inputs[0]); /* Decode unpacked VP8 frames. */ while (vp8rtpfmt_unpacker_get_frame(&s->unpacker, &frame, &frame_info) == 0) { while ((im = ms_queue_get(&frame)) != NULL) { err = vpx_codec_decode(&s->codec, im->b_rptr, (unsigned int)(im->b_wptr - im->b_rptr), NULL, 0); if ((s->flags & VPX_CODEC_USE_INPUT_FRAGMENTS) && mblk_get_marker_info(im)) { err = vpx_codec_decode(&s->codec, NULL, 0, NULL, 0); } if (err) { ms_warning("vp8 decode failed : %d %s (%s)\n", err, vpx_codec_err_to_string(err), vpx_codec_error_detail(&s->codec)?vpx_codec_error_detail(&s->codec):"no details"); } ms_queue_put(&mtofree_queue, im); } /* Get decoded frame */ if ((img = vpx_codec_get_frame(&s->codec, &iter))) { int i, j; int reference_updates = 0; if (vpx_codec_control(&s->codec, VP8D_GET_LAST_REF_UPDATES, &reference_updates) == 0) { if (frame_info.pictureid_present && ((reference_updates & VP8_GOLD_FRAME) || (reference_updates & VP8_ALTR_FRAME))) { vp8rtpfmt_send_rpsi(&s->unpacker, frame_info.pictureid); } } if (s->yuv_width != img->d_w || s->yuv_height != img->d_h) { if (s->yuv_msg) freemsg(s->yuv_msg); s->yuv_msg = ms_yuv_buf_alloc(&s->outbuf, img->d_w, img->d_h); ms_message("MSVp8Dec: video is %ix%i", img->d_w, img->d_h); s->yuv_width = img->d_w; s->yuv_height = img->d_h; ms_filter_notify_no_arg(f, MS_FILTER_OUTPUT_FMT_CHANGED); } /* scale/copy frame to destination mblk_t */ for (i = 0; i < 3; i++) { uint8_t *dest = s->outbuf.planes[i]; uint8_t *src = img->planes[i]; int h = img->d_h >> ((i > 0) ? 1 : 0); for (j = 0; j < h; j++) { memcpy(dest, src, s->outbuf.strides[i]); dest += s->outbuf.strides[i]; src += img->stride[i]; } } ms_queue_put(f->outputs[0], dupmsg(s->yuv_msg)); ms_average_fps_update(&s->fps, (uint32_t)f->ticker->time); if (!s->first_image_decoded) { s->first_image_decoded = TRUE; ms_filter_notify_no_arg(f, MS_VIDEO_DECODER_FIRST_IMAGE_DECODED); } } while ((im = ms_queue_get(&mtofree_queue)) != NULL) { freemsg(im); } }
static void _sender_process(MSFilter * f) { SenderData *d = (SenderData *) f->data; RtpSession *s = d->session; mblk_t *im; uint32_t timestamp; if (d->relay_session_id_size>0 && ( (f->ticker->time-d->last_rsi_time)>5000 || d->last_rsi_time==0) ) { ms_message("relay session id sent in RTCP APP"); rtp_session_send_rtcp_APP(s,0,"RSID",(const uint8_t *)d->relay_session_id,d->relay_session_id_size); d->last_rsi_time=f->ticker->time; } ms_filter_lock(f); im = ms_queue_get(f->inputs[0]); do { mblk_t *header; timestamp = get_cur_timestamp(f, im); if (d->dtmf != 0 && !d->skip) { ms_debug("prepare to send RFC2833 dtmf."); d->skip_until = timestamp + d->dtmf_duration; d->dtmf_ts_cur=timestamp; d->skip = TRUE; } if (d->skip) { uint32_t origin_ts=d->skip_until-d->dtmf_duration; if (RTP_TIMESTAMP_IS_NEWER_THAN(timestamp,d->dtmf_ts_cur)){ ms_debug("Sending RFC2833 packet, start_timestamp=%u, dtmf_ts_cur=%u",origin_ts,d->dtmf_ts_cur); send_dtmf(f, origin_ts); } } if (im){ if (d->skip == FALSE && d->mute==FALSE){ header = rtp_session_create_packet(s, 12, NULL, 0); rtp_set_markbit(header, mblk_get_marker_info(im)); header->b_cont = im; mblk_meta_copy(im, header); rtp_session_sendm_with_ts(s, header, timestamp); } else if (d->mute==TRUE && d->skip == FALSE) { process_cn(f, d, timestamp, im); freemsg(im); //Send STUN packet as RTP keep alive check_stun_sending(f); }else{ freemsg(im); } } else if (d->skip == FALSE) { // Send STUN packet as RTP keep alive even if there is no input check_stun_sending(f); } }while ((im = ms_queue_get(f->inputs[0])) != NULL); if (d->last_sent_time == -1) { check_stun_sending(f); } /*every second, compute output bandwidth*/ if (f->ticker->time % 1000 == 0) rtp_session_compute_send_bandwidth(d->session); ms_filter_unlock(f); }