Esempio n. 1
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;
}
Esempio n. 2
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;
}
Esempio n. 3
0
static int
layered_decoder_reorganise(channel_data *in, struct s_pb *out, timestamp_t playout)
{
        const codec_format_t *cf;
        codec_id_t            id;
        coded_unit           *cu;
        u_char               *p[LAY_MAX_LAYERS], *end;
        uint32_t               hdr32, data_len;
        uint8_t hdrpt, i;
        uint16_t len[LAY_MAX_LAYERS], mrk[LAY_MAX_LAYERS];
        media_data           *m;
        timestamp_t                  playout_step;

        media_data_create(&m, 1);
        assert(m->nrep == 1);

        if(in->nelem > LAY_MAX_LAYERS) {
                debug_msg("Too many layers to reorganise\n");
		goto done;
        }


       /* Since layer_decoder_peek checks all the headers, we can
        * assume they are OK. We still need to check that they match
        * up, however, i.e. that all the layers are intact, and that
        * they are all using the same codec. Layers need to be sorted
        * into order as well. We use the markers to determine how to
        * join the layers together into one media_data, and then get
        * out of here.
        */

        p[0] = in->elem[0]->data;
        hdr32 = ntohl(*(uint32_t*)p[0]);
        if(hdr32 & LAY_HDR32_PAT) {
                hdrpt = (uint8_t)(LAY_HDR32_GET_PT(hdr32));
                mrk[0] = (uint8_t)(LAY_HDR32_GET_MRK(hdr32));
                len[0] = (uint8_t)(LAY_HDR32_GET_LEN(hdr32));
                p[0] += 4;
        }
        else {
                debug_msg("Invalid layered header\n");
		goto done;
        }

        for(i=1; i<in->nelem; i++) {
                p[i] = in->elem[i]->data;

                hdr32 = ntohl(*(uint32_t*)p[i]);
                if(hdr32 & LAY_HDR32_PAT) {
                        if(hdrpt != (uint8_t)(LAY_HDR32_GET_PT(hdr32))) {
                                debug_msg("layered headers do not match!\n");
                                goto done;
                        }
                        mrk[i] = (uint16_t)(LAY_HDR32_GET_MRK(hdr32));
                        len[i] = (uint16_t)(LAY_HDR32_GET_LEN(hdr32));
                        p[i] += 4;
                }
                else {
                        debug_msg("Invalid layered header\n");
                        goto done;
                }
        }
        end  = in->elem[in->nelem-1]->data + in->elem[in->nelem-1]->data_len;

        /* if layers missing say so */
        if(in->nelem!=LAY_MAX_LAYERS) {
                debug_msg("Not all layers arrived:\n");
                for(i=0; i<in->nelem; i++) {
                        debug_msg("marker[%d] = %d\n", i, mrk[i]);
                }
        }

        /* Everything matches, so we'll use the first layer's details */

        cu = (coded_unit*)block_alloc(sizeof(coded_unit));
        memset(cu, 0, sizeof(coded_unit));

        id = codec_get_by_payload(hdrpt);
        if (codec_id_is_valid(id) == FALSE) {
                debug_msg("Layered channel coder - codec_id not recognised.\n");
                goto fail;
        }
        cf = codec_get_format(id);
        assert(cf != NULL);

       /* Do first unit separately as that may have state */
        if (cf->mean_per_packet_state_size) {
                cu->state_len = cf->mean_per_packet_state_size;
                cu->state     = (u_char*)block_alloc(cu->state_len);
                memcpy(cu->state, p[0], cf->mean_per_packet_state_size);
                for(i=0; i<in->nelem; i++)
                        p[i] += cf->mean_per_packet_state_size;
        }

        data_len = codec_peek_frame_size(id, p[0], (uint16_t)(len[0]));
        m->rep[0]->id = cu->id = id;
        cu->data = (u_char*)block_alloc(data_len);
        cu->data_len = (uint16_t)data_len;
        memset(cu->data, 0, data_len);

        /* join the layers up here */

        for(i=0; i<in->nelem; i++) {
                memcpy(cu->data + mrk[i], p[i], len[i]);
                p[i] += len[i];
        }

        codec_combine_layer(id, cu, m->rep[0], in->nelem, mrk);

        if (cu->state_len) {
                block_free(cu->state, cu->state_len);
                cu->state     = NULL;
                cu->state_len = 0;
        }
        assert(cu->state_len == 0);
        if (cu->data_len) {
                block_free(cu->data, cu->data_len);
                cu->data     = NULL;
                cu->data_len = 0;
        }
        assert(cu->data_len == 0);

        if (pb_add(out, (u_char *)m, sizeof(media_data), playout) == FALSE) {
                debug_msg("layered decode failed\n");
                goto fail;
        }

        /* Now do other units which do not have state*/
        playout_step = ts_map32(cf->format.sample_rate, codec_get_samples_per_frame(id));
        while(p[in->nelem - 1] < end) {
                playout = ts_add(playout, playout_step);
                media_data_create(&m, 1);
                m->rep[0]->id = id;
                assert(m->nrep == 1);

                cu->data            = (u_char*)block_alloc(data_len);
                cu->data_len        = (uint16_t)data_len;
                memset(cu->data, 0, data_len);

                for(i=0; i<in->nelem; i++) {
                        memcpy(cu->data + mrk[i], p[i], len[i]);
                        p[i] += len[i];
                }

                codec_combine_layer(id, cu, m->rep[0], in->nelem, mrk);

                block_free(cu->data, cu->data_len);
                cu->data     = 0;
                cu->data_len = 0;

                if (pb_add(out, (u_char *)m, sizeof(media_data), playout) == FALSE) {
                        debug_msg("layered decode failed\n");
                        goto fail;
                }
        }
        assert(p[in->nelem - 1] == end);

        block_free(cu, sizeof(coded_unit));
	channel_data_destroy(&in, sizeof(channel_data));
        xmemchk();
        return TRUE;

fail:
        if (cu->state) {
                block_free(cu->state, cu->state_len);
                cu->state     = 0;
                cu->state_len = 0;
        }
        assert(cu->state_len == 0);
        if (cu->data) {
                block_free(cu->data, cu->data_len);
                cu->data     = 0;
                cu->data_len = 0;
        }
        assert(cu->data_len == 0);
        block_free(cu, sizeof(coded_unit));
done:
	media_data_destroy(&m, sizeof(media_data));
	channel_data_destroy(&in, sizeof(channel_data));
        xmemchk();
        return FALSE;
}
Esempio n. 4
0
static channel_data *
redundancy_encoder_output(red_enc_state *re, uint32_t upp)
{
        struct s_pb_iterator *pbm;
        channel_data         *cd_coded[RED_MAX_LAYERS], *cd_out;
        uint32_t               offset ;
        int                   i, j, layers, success = 0,  used = 0;

        pbm = re->media_pos;
        pb_iterator_ffwd(pbm);

        /*** Stage 1: Packing coded audio units ******************************/

        /* Rewind iterator to start of first pdu */
        for(i = 1; (uint32_t)i < upp; i++) {
                success = pb_iterator_retreat(pbm);
                assert(success);
        }

        offset = 0;
        layers = 0;
        for (i = 0; (uint32_t)i < re->n_layers; i++) {
                if (re->units_ready <= re->layer[i].pkts_off * upp) {
                        break;
                }
                /* Move back to start of this layer */
                while (offset < re->layer[i].pkts_off * upp) {
                        success = pb_iterator_retreat(pbm);
                        if (success == FALSE) break;
                        offset++;
                }
                xmemchk();
                /* need upp data elements + 1 for state */
                channel_data_create(&cd_coded[i], upp + 1);
                success = make_pdu(pbm, upp, re->layer[i].cid, cd_coded[i]);
                /* make_pdu may fail because coding not available */
                if (success == FALSE) {
                        channel_data_destroy(&cd_coded[i], sizeof(channel_data));
                        break;
                }
                layers++;
        }

#ifdef DEBUG_REDUNDANCY
        debug_msg("end of data collection\n");
#endif /* DEBUG_REDUNDANCY */
        assert(layers != 0);

        /* Create channel_data unit that will get output */
        channel_data_create(&cd_out, layers * (upp + 1) + re->n_layers);

        /*** Stage 2: Packing redundancy headers *****************************/
        used = 0;
        if ((uint32_t)layers != re->n_layers) {
                /* Add max offset if we didn't make all units */
                add_hdr(cd_out->elem[used],
                        RED_EXTRA,
                        re->layer[re->n_layers - 1].cid,
                        re->layer[re->n_layers - 1].pkts_off * upp,
                        0);
                used++;
        }

        i = layers - 1;
        while (i > 0) {
                add_hdr(cd_out->elem[used],
                        RED_EXTRA,
                        re->layer[re->n_layers - 1].cid,
                        re->layer[re->n_layers - 1].pkts_off * upp,
                        channel_data_bytes(cd_coded[i]));
                used++;
                i--;
        }

        add_hdr(cd_out->elem[used],
                RED_PRIMARY,
                re->layer[0].cid,
                re->layer[0].pkts_off * upp,
                0);
        used++;

        /*** Stage 3: Transfering coded units into output unit ***************/

        for(i = layers - 1; i >= 0; i--) {
                for (j = 0; j < cd_coded[i]->nelem && cd_coded[i]->elem[j]->data != NULL; j++) {
                        cd_out->elem[used]->data       =  cd_coded[i]->elem[j]->data;
                        cd_out->elem[used]->data_len   =  cd_coded[i]->elem[j]->data_len;
                        cd_coded[i]->elem[j]->data     = NULL;
                        cd_coded[i]->elem[j]->data_len = 0;
                        used++;
                        assert(used <= cd_out->nelem);
                }
                assert(used <= cd_out->nelem);
                channel_data_destroy(&cd_coded[i], sizeof(channel_data));
        }

        pb_iterator_audit(pbm, re->history); /* Clear old rubbish */

        return  cd_out;
}