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 pb_add (pb_t *pb, u_char *data, uint32_t data_len, timestamp_t playout) { pb_node_t *curr, *stop, *made; assert(data != NULL); assert(data_len > 0); pb_validate(pb); /* Assuming that addition will be at the end of list (or near it) */ stop = pb->psentinel; curr = stop->prev; /* list tail */ while (curr != stop && ts_gt(curr->playout, playout)) { curr = curr->prev; } /* Check if unit already exists */ if (curr != stop && ts_eq(curr->playout, playout)) { debug_msg("Add failed - unit already exists\n"); return FALSE; } made = (pb_node_t*)block_alloc(sizeof(pb_node_t)); if (made) { made->playout = playout; made->data = data; made->data_len = data_len; made->prev = curr; made->next = curr->next; made->next->prev = made; made->prev->next = made; made->magic = PB_NODE_MAGIC; pb->n_nodes++; pb_validate(pb); return TRUE; } debug_msg("Insufficient memory\n"); return FALSE; }