Beispiel #1
0
int
media_data_create(media_data **ppmd, int nrep)
{
        media_data *pmd;
        int i;

        *ppmd = NULL;
        pmd   = (media_data*)block_alloc(sizeof(media_data));

        if (pmd) {
                memset(pmd, 0, sizeof(media_data));
                for(i = 0; i < nrep; i++) {
                        pmd->rep[i] = block_alloc(sizeof(coded_unit));
                        if (pmd->rep[i] == NULL) {
                                pmd->nrep = i;
                                media_data_destroy(&pmd, sizeof(media_data));
                                return FALSE;
                        }
                        memset(pmd->rep[i], 0, sizeof(coded_unit));
                }
                pmd->nrep    = nrep;
                *ppmd = pmd;
                return TRUE;
        }
        return FALSE;
}
Beispiel #2
0
int
vanilla_encoder_reset(u_char *state)
{
        ve_state *ve = (ve_state*)state;
        uint32_t   i;

        for(i = 0; i < ve->nelem; i++) {
                media_data_destroy(&ve->elem[i], sizeof(media_data));
        }
        ve->nelem = 0;

        return TRUE;
}
Beispiel #3
0
int
layered_encoder_reset(u_char *state)
{
        lay_state *le = (lay_state*)state;
        uint32_t   i;

        for(i = 0; i < le->nelem; i++) {
                media_data_destroy(&le->elem[i], sizeof(media_data));
        }
        le->nelem = 0;

       /* Should we be resetting the number of layers? *
        * This is only called in tx_stop().            */
        /*le->n_layers = 1; */

        debug_msg("layered_encoder_reset!\n");

        return TRUE;
}
Beispiel #4
0
static void
vanilla_encoder_output(ve_state *ve, struct s_pb *out)
{
        uint32_t i, used;
        channel_data *cd;

        /* We have state for first unit and data for all others */
        channel_data_create(&cd, ve->nelem + 1);

        /* Fill in payload */
        cd->elem[0]->pt           = codec_get_payload(ve->codec_id);

        used = 0;

        /* Get state for first unit if there */
        if (ve->elem[0]->rep[0]->state) {
                cd->elem[0]->data     = ve->elem[0]->rep[0]->state;
                cd->elem[0]->data_len = ve->elem[0]->rep[0]->state_len;
                ve->elem[0]->rep[0]->state     = NULL;
                ve->elem[0]->rep[0]->state_len = 0;
                used++;
        }

        /* Transfer coded data to channel_data */
        for(i = 0; i < ve->nelem; i++) {
                cd->elem[used]->data     = ve->elem[i]->rep[0]->data;
                cd->elem[used]->data_len = ve->elem[i]->rep[0]->data_len;
                ve->elem[i]->rep[0]->data = NULL;
                ve->elem[i]->rep[0]->data_len = 0;
                used++;
                media_data_destroy(&ve->elem[i], sizeof(media_data));
        }
        ve->nelem = 0;

        assert(used <= cd->nelem);

        pb_add(out,
               (u_char*)cd,
               sizeof(channel_data),
               ve->playout);
}
Beispiel #5
0
static void
vanilla_decoder_output(channel_unit *cu, struct s_pb *out, timestamp_t playout)
{
        const codec_format_t *cf;
        codec_id_t            id;
        uint32_t              data_len;
        u_char               *p, *end;
        media_data           *m;
        timestamp_t                  unit_dur;

        id       = codec_get_by_payload(cu->pt);
        cf       = codec_get_format(id);
        unit_dur = ts_map32(cf->format.sample_rate, codec_get_samples_per_frame(id));
        p        = cu->data;
        end      = cu->data + cu->data_len;

        while(p < end) {
                media_data_create(&m, 1);
                m->rep[0]->id       = id;
                if (p == cu->data && cf->mean_per_packet_state_size) {
                        /* First unit out of packet may have state */
                        m->rep[0]->state_len = cf->mean_per_packet_state_size;
                        m->rep[0]->state     = (u_char*)block_alloc(m->rep[0]->state_len);
                        memcpy(m->rep[0]->state, p, cf->mean_per_packet_state_size);
                        p += cf->mean_per_packet_state_size;
                }
                /* Now do data section */
                data_len            = codec_peek_frame_size(id, p, (uint16_t)(end - p));
                m->rep[0]->data     = (u_char*)block_alloc(data_len);
                m->rep[0]->data_len = (uint16_t)data_len;
                memcpy(m->rep[0]->data, p, data_len);
                if (pb_add(out, (u_char *)m, sizeof(media_data), playout) == FALSE) {
                        debug_msg("Vanilla decode failed\n");
                        media_data_destroy(&m, sizeof(media_data));
                        return;
                }
                p += data_len;
                playout = ts_add(playout, unit_dur);
        }
        assert(p == end);
}
Beispiel #6
0
/* new unit dst.  Returns TRUE on success.                                   */
int
media_data_dup(media_data **dst, media_data *src)
{
        media_data *m;
        uint8_t    i;

        if (media_data_create(&m, src->nrep) == FALSE) {
                *dst = NULL;
                return FALSE;
        }

        for(i = 0; i < src->nrep; i++) {
                if (coded_unit_dup(m->rep[i], src->rep[i]) == FALSE) {
                        goto media_dup_failure;
                }
        }
        *dst = m;
        return TRUE;

media_dup_failure:
        media_data_destroy(&m, sizeof(media_data));
        return FALSE;
}
static void
test_repair(struct s_sndfile *sf_out, 
            codec_id_t        cid,
            repair_id_t       repair_type,
            struct s_sndfile *sf_in)
{
        codec_state                *encoder;        
        struct s_codec_state_store *decoder_states;
        media_data                 *md_prev, *md_cur;
        coded_unit                 *cu;
        int32_t                     consec_lost = 0, total_lost, total_done;
        const codec_format_t       *cf;
        uint16_t                    i;
        repair_id_t                 repair_none;

        for (i = 0; i < repair_get_count(); i++) {
                const repair_details_t *rd;
                rd = repair_get_details(i);
                if (strcasecmp(rd->name, "none") == 0) {
                        repair_none = rd->id;
                        break;
                }
        }

        codec_encoder_create(cid, &encoder);
        codec_state_store_create(&decoder_states, DECODER);
        cf = codec_get_format(cid);

        /* Read and write one unit to kick off with */
        media_data_create(&md_cur, 1);
        read_and_encode(md_cur->rep[0], encoder, sf_in);
        decode_and_write(sf_out, decoder_states, md_cur);

        /* Initialize next reading cycle */
        md_prev = md_cur;
        md_cur  = NULL;
        media_data_create(&md_cur, 1);

        total_lost = total_done = 0;

        while(read_and_encode(md_cur->rep[0], encoder, sf_in)) {
                total_done++;
                if (do_drop()) {
                        total_lost++;
                        media_data_destroy(&md_cur, sizeof(media_data));
                        media_data_create(&md_cur, 0);
                        
                        cu = (coded_unit*)block_alloc(sizeof(coded_unit));
                        assert(cu != NULL);
                        memset(cu, 0, sizeof(coded_unit));

                        /* Loss happens - invoke repair */
                        if (repair_type != repair_none) {
                                cu->id = cid;
                                repair(repair_type,
                                       consec_lost,
                                       decoder_states,
                                       md_prev,
                                       cu);
                        } else {
                                
                                /* Create a silent unit */
                                cu->id = codec_get_native_coding((uint16_t)cf->format.sample_rate,
                                                                 (uint16_t)cf->format.channels);
                                cu->state     = NULL;
                                cu->state_len = 0;
                                cu->data      = (u_char*)block_alloc(cf->format.bytes_per_block);
                                cu->data_len  = cf->format.bytes_per_block;
                                memset(cu->data, 0, cu->data_len);
                        }
                        
                        /* Add repaired audio to frame */
                        md_cur->rep[md_cur->nrep] = cu;
                        md_cur->nrep++;
                        
                        consec_lost++;
                } else {
                        consec_lost = 0;
                }
                
                decode_and_write(sf_out, decoder_states, md_cur);

                media_data_destroy(&md_prev, sizeof(media_data));
                md_prev = md_cur;
                md_cur  = NULL;
                media_data_create(&md_cur, 1);
        }

        printf("# Dropped %d frames out of %d (%f loss %%)\n", total_lost, total_done, 100.0 * total_lost / (double)total_done);
        
        media_data_destroy(&md_cur, sizeof(media_data));
        media_data_destroy(&md_prev, sizeof(media_data));
        
        codec_encoder_destroy(&encoder);
        codec_state_store_destroy(&decoder_states);
}
Beispiel #8
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;
}
Beispiel #9
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;
}
Beispiel #10
0
static void
layered_encoder_output(lay_state *le, struct s_pb *out)
{
        uint32_t i, used;
        channel_data *cd;
        uint8_t j;
        uint16_t cd_len[LAY_MAX_LAYERS], markers[LAY_MAX_LAYERS];
        coded_unit *lu;

        /* We have state for first unit and data for all others */
        channel_data_create(&cd, (le->nelem + 2)*(le->n_layers));

        /* Fill in payload */
        cd->elem[0]->pt           = codec_get_payload(le->codec_id);

        used = 0;

        /* leave space for headers */
        used += le->n_layers;

        /* Get state for first unit if there */
        if (le->elem[0]->rep[0]->state) {
                for(j=0; j<le->n_layers; j++) {
                        cd->elem[used]->data_len = le->elem[0]->rep[0]->state_len;
                        //SV-XXX cd->elem[used]->data = (char *)block_alloc(le->elem[0]->rep[0]->state_len);
			cd->elem[used]->data = (unsigned char*)block_alloc(le->elem[0]->rep[0]->state_len);
                        memcpy(cd->elem[used]->data, le->elem[0]->rep[0]->state, le->elem[0]->rep[0]->state_len);
                        used++;
                }
        }

        for(j = 0; j < le->n_layers; j++) {
                cd_len[j] = 0;
        }

        lu = (coded_unit*)block_alloc(sizeof(coded_unit));

        /* Transfer coded data to channel_data */
        for(i = 0; i < le->nelem; i++) {
                for(j = 0; j < le->n_layers; j++) {
                        codec_get_layer(le->codec_id, le->elem[i]->rep[0], j, markers, lu);
                        cd->elem[used]->data_len = lu->data_len;
			//SV-XXX cd->elem[used]->data = (char*)block_alloc(lu->data_len);
                        cd->elem[used]->data = (unsigned char*)block_alloc(lu->data_len);
                        memcpy(cd->elem[used]->data, lu->data, lu->data_len);
                        used++;
                        if(i==0) cd_len[j] = (uint16_t)lu->data_len;
                        if(lu->state_len) {
			  block_free(lu->state, lu->state_len);
			  lu->state = NULL;
			  lu->state_len = 0;
			}
			if(lu->data_len) {
			  block_free(lu->data, lu->data_len);
			  lu->data     = NULL;
			  lu->data_len = 0;
			}
                }
		block_free(le->elem[i]->rep[0]->data, le->elem[i]->rep[0]->data_len);
                le->elem[i]->rep[0]->data = NULL;
                le->elem[i]->rep[0]->data_len = 0;
                media_data_destroy(&le->elem[i], sizeof(media_data));
        }

        le->nelem = 0;
        assert(lu->data_len == 0);
        block_free(lu, sizeof(coded_unit));

        for(j=0; j<le->n_layers; j++) {
                add_hdr(cd->elem[j], cd->elem[0]->pt, markers[j], cd_len[j]);
        }

        assert(used <= cd->nelem);

        pb_add(out,
                (u_char*)cd,
                sizeof(channel_data),
                le->playout);
}
Beispiel #11
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;
}