Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
void
pktbuf_destroy(struct s_pktbuf **ppb)
{
        struct s_pktbuf *pb = *ppb;
	pb_iterator_destroy(pb->rtp_buffer, &pb->rtp_iterator);
	pb_destroy(&pb->rtp_buffer);
        xfree(pb);
        *ppb = NULL;
}
Example #5
0
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;
}
Example #6
0
void
redundancy_encoder_destroy(u_char **state, uint32_t len)
{
        red_enc_state *re = *((red_enc_state**)state);

        assert(len == sizeof(red_enc_state));

        pb_iterator_destroy(re->media_buffer,
                            &re->media_pos);

        pb_destroy(&re->media_buffer);

        xfree(*state);
        *state = NULL;
}
Example #7
0
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;
}
Example #8
0
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;
}
Example #9
0
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;
}