static media_data * red_media_data_create_or_get(struct s_pb *p, timestamp_t playout) { struct s_pb_iterator *pi; u_char *md_get; media_data *md; uint32_t md_len, success; timestamp_t md_playout; pb_iterator_create(p, &pi); /* iterator is attached to sentinel - can move back or forwards */ while(pb_iterator_retreat(pi)) { success = pb_iterator_get_at(pi, &md_get, &md_len, &md_playout); md = (media_data*)md_get; assert(success); if (ts_eq(md_playout, playout)) { goto done; } else if (ts_gt(playout, md_playout)) { /* we have gone too far back */ break; } } /* Not found in playout buffer */ media_data_create(&md, 0); success = pb_add(p, (u_char*)md, sizeof(media_data), playout); assert(success); done: pb_iterator_destroy(p, &pi); return md; }
int layered_decoder_decode(u_char *state, struct s_pb *in, struct s_pb *out, timestamp_t now) { struct s_pb_iterator *pi; u_char *c_get; channel_data *c; uint32_t clen; timestamp_t playout; UNUSED(state); pb_iterator_create(in, &pi); assert(pi != NULL); while(pb_iterator_get_at(pi, &c_get, &clen, &playout)) { c = (channel_data*)c_get; assert(c != NULL); assert(clen == sizeof(channel_data)); if (ts_gt(playout, now)) { /* Playout point of unit is after now. Stop! */ break; } pb_iterator_detach_at(pi, &c_get, &clen, &playout); layered_decoder_reorganise(c, out, playout); } pb_iterator_destroy(in, &pi); return TRUE; }
int redundancy_decoder_decode(u_char *state, struct s_pb *in, struct s_pb *out, timestamp_t now) { struct s_pb_iterator *pi; u_char *c_get; channel_data *c; uint32_t clen; timestamp_t cplayout; pb_iterator_create(in, &pi); assert(pi != NULL); assert(state == NULL); /* No decoder state necesssary */ UNUSED(state); while(pb_iterator_get_at(pi, &c_get, &clen, &cplayout)) { c = (channel_data*)c_get; assert(c != NULL); assert(clen == sizeof(channel_data)); if (ts_gt(cplayout, now)) { break; } pb_iterator_detach_at(pi, &c_get, &clen, &cplayout); c = (channel_data*)c_get; assert(c->nelem == 1); redundancy_decoder_output(c->elem[0], out, cplayout); channel_data_destroy(&c, sizeof(channel_data)); } pb_iterator_destroy(in, &pi); return TRUE; }
int pktbuf_create(struct s_pktbuf **ppb, uint16_t size) { struct s_pktbuf *pb; pb = (struct s_pktbuf*)xmalloc(sizeof(struct s_pktbuf)); if (pb == NULL) { return FALSE; } if (pb_create(&pb->rtp_buffer, pktbuf_free_rtp) == FALSE) { xfree(pb); return FALSE; } if (pb_iterator_create(pb->rtp_buffer, &pb->rtp_iterator) == FALSE) { pb_destroy(&pb->rtp_buffer); xfree(pb); return FALSE; } pb->max_packets = size; *ppb = pb; return TRUE; }
int pb_iterator_dup(pb_iterator_t **pb_dst, pb_iterator_t *pb_src) { pb_validate(pb_src->buffer); if (pb_iterator_create(pb_src->buffer, pb_dst)) { (*pb_dst)->node = pb_src->node; return TRUE; } return FALSE; }
int vanilla_decoder_decode(u_char *state, struct s_pb *in, struct s_pb *out, timestamp_t now) { struct s_pb_iterator *pi; channel_unit *cu; u_char *c_get; channel_data *c; uint32_t clen; timestamp_t playout; assert(state == NULL); /* No decoder state needed */ UNUSED(state); pb_iterator_create(in, &pi); assert(pi != NULL); while(pb_iterator_get_at(pi, &c_get, &clen, &playout)) { c = (channel_data*)c_get; assert(c != NULL); assert(clen == sizeof(channel_data)); if (ts_gt(playout, now)) { /* Playout point of unit is after now. Stop! */ break; } pb_iterator_detach_at(pi, &c_get, &clen, &playout); c = (channel_data*)c_get; assert(c != NULL); assert(c->nelem == 1); cu = c->elem[0]; vanilla_decoder_output(cu, out, playout); channel_data_destroy(&c, sizeof(channel_data)); } pb_iterator_destroy(in, &pi); return TRUE; }
int redundancy_encoder_create(u_char **state, uint32_t *len) { red_enc_state *re = (red_enc_state*)xmalloc(sizeof(red_enc_state)); if (re == NULL) { debug_msg("Failed to allocate encoder\n"); goto fail_alloc; } memset(re, 0, sizeof(red_enc_state)); *state = (u_char*)re; *len = sizeof(red_enc_state); if (pb_create(&re->media_buffer, (playoutfreeproc)media_data_destroy) == FALSE) { debug_msg("Gailed to create media buffer\n"); goto fail_pb; } if (pb_iterator_create(re->media_buffer, &re->media_pos) == FALSE) { debug_msg("failed to create iterator\n"); goto fail_pb_iterator; } re->n_layers = 0; re->units_ready = 0; return TRUE; fail_pb_iterator: pb_destroy(&re->media_buffer); fail_pb: xfree(re); fail_alloc: *state = NULL; return FALSE; }
int layered_encoder_encode (u_char *state, struct s_pb *in, struct s_pb *out, uint32_t upp) { uint32_t m_len; timestamp_t playout; struct s_pb_iterator *pi; u_char *m_get; media_data *m; lay_state *le = (lay_state*)state; assert(upp != 0 && upp <= MAX_UNITS_PER_PACKET); pb_iterator_create(in, &pi); pb_iterator_advance(pi); /* Move to first element */ while(pb_iterator_detach_at(pi, &m_get, &m_len, &playout)) { /* Remove element from playout buffer - it belongs to * the layered encoder now. */ m = (media_data*)m_get; assert(m != NULL); if (le->nelem == 0) { /* If it's the first unit make a note of it's * playout */ le->playout = playout; if (m->nrep == 0) { /* We have no data ready to go and no data * came off on incoming queue. */ media_data_destroy(&m, sizeof(media_data)); continue; } } else { /* Check for early send required: * (a) if this unit has no media respresentations * e.g. end of talkspurt. * (b) codec type of incoming unit is different * from what is on queue. */ if (m->nrep == 0) { layered_encoder_output(le, out); media_data_destroy(&m, sizeof(media_data)); continue; } else if (m->rep[0]->id != le->codec_id) { layered_encoder_output(le, out); } } assert(m_len == sizeof(media_data)); le->codec_id = m->rep[0]->id; le->elem[le->nelem] = m; le->nelem++; if (le->nelem >= (uint32_t)upp) { layered_encoder_output(le, out); } } pb_iterator_destroy(in, &pi); xmemchk(); return TRUE; }
int redundancy_encoder_encode (u_char *state, struct s_pb *in, struct s_pb *out, uint32_t upp) { uint32_t m_len; timestamp_t playout; struct s_pb_iterator *pi; u_char *m_get; media_data *m; red_enc_state *re = (red_enc_state*)state; assert(upp != 0 && upp <= MAX_UNITS_PER_PACKET); pb_iterator_create(in, &pi); assert(pi != NULL); pb_iterator_advance(pi); while(pb_iterator_detach_at(pi, &m_get, &m_len, &playout)) { m = (media_data*)m_get; /* Remove element from playout buffer - it belongs to * the redundancy encoder now. */ #ifdef DEBUG_REDUNDANCY debug_msg("claimed %d, prev %d\n", playout.ticks, re->last_in.ticks); #endif /* DEBUG_REDUNDANCY */ assert(m != NULL); if (re->units_ready == 0) { re->last_in = playout; re->last_in.ticks--; } assert(ts_gt(playout, re->last_in)); re->last_in = playout; if (m->nrep > 0) { pb_add(re->media_buffer, (u_char*)m, m_len, playout); re->units_ready++; } else { /* Incoming unit has no data so transmission is * not happening. */ #ifdef DEBUG_REDUNDANCY debug_msg("No incoming data\n"); #endif /* DEBUG_REDUNDANCY */ media_data_destroy(&m, sizeof(media_data)); pb_flush(re->media_buffer); re->units_ready = 0; continue; } if (re->units_ready && (re->units_ready % upp) == 0) { channel_data *cd; int s; cd = redundancy_encoder_output(re, upp); assert(cd != NULL); s = pb_add(out, (u_char*)cd, sizeof(channel_data), playout); #ifdef DEBUG_REDUNDANCY debug_msg("Ready %d, Added %d\n", re->units_ready, playout.ticks); #endif /* DEBUG_REDUNDANCY */ assert(s); } } pb_iterator_destroy(in, &pi); return TRUE; }