int tdav_consumer_video_put(tdav_consumer_video_t* self, const void* data, tsk_size_t data_size, const tsk_object_t* proto_hdr) { const trtp_rtp_header_t* rtp_hdr = TRTP_RTP_HEADER(proto_hdr); int ret; if(!self || !data || !self->jitterbuffer || !rtp_hdr){ TSK_DEBUG_ERROR("Invalid parameter"); return -1; } tsk_safeobj_lock(self); if(!TMEDIA_JITTER_BUFFER(self->jitterbuffer)->opened){ uint32_t frame_duration = (1000 / TMEDIA_CONSUMER(self)->video.fps); static uint32_t rate = 90000; static uint32_t channels = 1; if((ret = tmedia_jitterbuffer_open(TMEDIA_JITTER_BUFFER(self->jitterbuffer), frame_duration, rate, channels))){ TSK_DEBUG_ERROR("Failed to open jitterbuffer (%d)", ret); tsk_safeobj_unlock(self); return ret; } } ret = tmedia_jitterbuffer_put(TMEDIA_JITTER_BUFFER(self->jitterbuffer), (void*)data, data_size, proto_hdr); tsk_safeobj_unlock(self); return ret; }
static int tdav_speex_jitterbuffer_put(tmedia_jitterbuffer_t* self, void* data, tsk_size_t data_size, const tsk_object_t* proto_hdr) { tdav_speex_jitterbuffer_t *jb = (tdav_speex_jitterbuffer_t *)self; const trtp_rtp_header_t* rtp_hdr; JitterBufferPacket jb_packet; static uint16_t seq_num = 0; if(!data || !data_size || !proto_hdr){ TSK_DEBUG_ERROR("Invalid parameter"); return -1; } if(!jb->state){ TSK_DEBUG_ERROR("Invalid state"); return -2; } rtp_hdr = TRTP_RTP_HEADER(proto_hdr); jb_packet.user_data = 0; jb_packet.span = jb->frame_duration; jb_packet.len = jb->x_data_size; if(jb->x_data_size == data_size){ /* ptime match */ jb_packet.data = data; jb_packet.sequence = rtp_hdr->seq_num; jb_packet.timestamp = (rtp_hdr->seq_num * jb_packet.span); jitter_buffer_put(jb->state, &jb_packet); } else{ /* ptime mismatch */ tsk_size_t i; jb_packet.sequence = 0; // Ignore if((jb->buff.index + data_size) > jb->buff.size){ if(!(jb->buff.ptr = tsk_realloc(jb->buff.ptr, (jb->buff.index + data_size)))){ jb->buff.size = 0; jb->buff.index = 0; return 0; } jb->buff.size = (jb->buff.index + data_size); } memcpy(&jb->buff.ptr[jb->buff.index], data, data_size); jb->buff.index += data_size; if(jb->buff.index >= jb->x_data_size){ tsk_size_t copied = 0; for(i = 0; (i + jb->x_data_size) <= jb->buff.index; i += jb->x_data_size){ jb_packet.data = (char*)&jb->buff.ptr[i]; jb_packet.timestamp = (++jb->fake_seqnum * jb_packet.span);// reassembled pkt will have fake seqnum jitter_buffer_put(jb->state, &jb_packet); copied += jb->x_data_size; } if(copied == jb->buff.index){ // all copied jb->buff.index = 0; } else{ memmove(&jb->buff.ptr[0], &jb->buff.ptr[copied], (jb->buff.index - copied)); jb->buff.index -= copied; } } } return 0; }