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 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; }
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; }
static uint32_t make_pdu(struct s_pb_iterator *pbi, uint32_t upp, codec_id_t cid, channel_data *out) { struct s_pb_iterator *p; uint32_t i, j, md_len, used; u_char *md_get; media_data *md; timestamp_t playout; int success; pb_iterator_dup(&p, pbi); used = 0; for (i = 0; i < upp; i++) { success = pb_iterator_get_at(p, &md_get, &md_len, &playout); md = (media_data*)md_get; assert(success); /* We could rewind this far so must be able to get something! */ /* Find first compatible coding */ for(j = 0; j < md->nrep && md->rep[j]->id != cid; j++); if (j == md->nrep) { /* could not find coding */ debug_msg("coding not found\n"); break; } if (i == 0 && md->rep[j]->state != NULL) { /* This is first unit in block so we want state */ assert(out->elem[used]->data == NULL); out->elem[used]->data = md->rep[j]->state; out->elem[used]->data_len = md->rep[j]->state_len; md->rep[j]->state = NULL; md->rep[j]->state_len = 0; used++; } assert(used < out->nelem); assert(out->elem[used]->data == NULL); out->elem[used]->data = md->rep[j]->data; out->elem[used]->data_len = md->rep[j]->data_len; md->rep[j]->data = NULL; md->rep[j]->data_len = 0; md->rep[j]->id = 0; /* nobble this unit since we have taken it's data */ used++; assert(used <= out->nelem); pb_iterator_advance(p); } pb_iterator_destroy(pb_iterator_get_playout_buffer(pbi), &p); xmemchk(); return used; }
int pktbuf_peak_last(pktbuf_t *pb, rtp_packet **pp) { timestamp_t playout; uint32_t psize; if (pb_iterator_ffwd(pb->rtp_iterator) == FALSE) { return FALSE; } pb_iterator_get_at(pb->rtp_iterator, (u_char**)pp, &psize, &playout); return TRUE; }
int pb_iterator_detach_at (pb_iterator_t *pi, u_char **data, uint32_t *data_len, timestamp_t *playout) { pb_iterator_t *iterators; pb_node_t *curr_node, *next_node; uint16_t i, n_iterators; pb_validate(pi->buffer); if (pb_iterator_get_at(pi, data, data_len, playout) == FALSE) { /* There is no data to get */ return FALSE; } /* Check we are not attempting to remove * data that another iterator is pointing to */ iterators = &pi->buffer->iterators[0]; n_iterators = pi->buffer->n_iterators; for(i = 0; i < n_iterators; i++) { if (iterators[i].node == pi->node && iterators + i != pi) { debug_msg("Eek removing node that another iterator is using...danger!\n"); iterators[i].node = iterators[i].node->prev; } } /* Relink list of nodes */ curr_node = pi->node; next_node = curr_node->next; curr_node->next->prev = curr_node->prev; curr_node->prev->next = curr_node->next; #ifdef DEBUG curr_node->next = NULL; curr_node->prev = NULL; curr_node->magic = 0; curr_node->data = NULL; curr_node->data_len = 0; #endif block_free(curr_node, sizeof(pb_node_t)); pi->node = next_node; pi->buffer->n_nodes--; pb_validate(pi->buffer); return TRUE; }
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; }