예제 #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;
}
예제 #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;
}
예제 #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;
}
예제 #4
0
파일: pktbuf.c 프로젝트: uclmediatools/rat
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;
}
예제 #5
0
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;
}
예제 #6
0
파일: cc_vanilla.c 프로젝트: JensenSung/rat
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;
}
예제 #7
0
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;
}
예제 #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;
}
예제 #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;
}