Esempio n. 1
0
static int
place_unit(media_data *md, coded_unit *cu)
{
        int16_t i;
#ifdef DEBUG_REDUNDANCY
        const codec_format_t *cf;
        cf = codec_get_format(cu->id);
        debug_msg("%d %s\n", md->nrep, cf->long_name);
#endif /* DEBUG_REDUNDANCY */
        assert(md->nrep < MAX_MEDIA_UNITS);

        for (i = 0; i < md->nrep; i++) {
                if (md->rep[i]->id == cu->id) {
                        return FALSE;
                }
        }

        if (md->nrep > 0 && codec_is_native_coding(md->rep[md->nrep - 1]->id)) {
                /* Buffer shifts can mean redundancy is received after primary decoded.  */
                /* Just discard. i.e. pkt 1 (t1 t0) pkt2 (t2 t1), if pkt2 arrives after  */
                /* pkt1 decoded we don't want to append redundant t1 data as it confuses */
                /* decoder.                                                              */
                /* XXX Should check for packet re-ordering i.e. pkt2 arrives and is      */
                /* decoded before pkt 1 then should use pkt 1's data as this will be     */
                /* higher quality under normal circumstances.                            */
                return FALSE;
        }

        md->rep[md->nrep] = cu;
        md->nrep++;
        return TRUE;
}
Esempio n. 2
0
int
codec_encode(codec_state *cs,
             coded_unit  *in_native,
             coded_unit  *cu)
{
        uint16_t    ifs, fmt;
        int        success;

        assert(cs        != NULL);
        assert(in_native != NULL);
        assert(cu        != NULL);

        assert(codec_is_native_coding(in_native->id));
        assert (in_native->state == NULL);
#ifdef DEBUG
        {
                const codec_format_t *cf = codec_get_format(cs->id);
                assert (cf->format.bytes_per_block == in_native->data_len);
        }
#endif
        cu->id = cs->id;
        ifs = CODEC_GET_IFS_INDEX(cu->id);
        fmt = CODEC_GET_FMT_INDEX(cu->id);

        xmemchk();
        success = codec_table[ifs].cx_encode(fmt, cs->state, (sample*)in_native->data, cu);
        xmemchk();

        return success;
}
Esempio n. 3
0
static int
sanity_check_payloads(void)
{
        uint32_t i, j, n_codecs, n_channels;
        codec_id_t cid;
        const codec_format_t *cf  = NULL;
        const cc_details_t   *ccd = NULL;
        cc_id_t    ccid;

        u_char pt;

        n_codecs = codec_get_number_of_codecs();
        n_channels = channel_get_coder_count();
        for(i = 0; i < n_codecs; i++) {
                cid = codec_get_codec_number(i);
                cf  = codec_get_format(cid);
                pt  = codec_get_payload(cid);
                if (pt != CODEC_PAYLOAD_DYNAMIC) {
                        ccid = channel_coder_get_by_payload(pt);
                        for(j = 0; j < n_channels; j++) {
                                ccd = channel_get_coder_details(j);
                                if (ccd == channel_get_null_coder()) {
                                        continue;
                                }
                                if (ccd->descriptor == ccid) {
                                        debug_msg("clash with %s %s payload (%d)\n", cf->long_name, ccd->name, pt);
                                        return FALSE;
                                }
                        }
                } else {
                        /* codec is not mapped into codec space so ignore */
                }
        }
        return TRUE;
}
Esempio n. 4
0
int
layered_encoder_get_parameters(u_char *state, char *cmd, uint32_t cmd_len)
{
        const codec_format_t *cf;
        lay_state *l;
        uint32_t flen;

        char frag[CODEC_LONG_NAME_LEN+5]; /* XXX/nn/\0 + 1*/

        assert(cmd_len > 0);
        assert(cmd != NULL);

        l = (lay_state*)state;
        if (l->n_layers < 2) {
                debug_msg("Using layered coder with %d layers?\n", l->n_layers);
                return FALSE;
        }

        *cmd = '\0';
		flen = 0;

        cf = codec_get_format(l->codec_id);
        assert(cf!=NULL);
        sprintf(frag, "%s/%d", cf->long_name, l->n_layers);
        flen += strlen(frag);
        if (flen>cmd_len) {
                debug_msg("buffer overflow would have occurred.\n");
                *cmd = '\0';
                return FALSE;
        }
        strcat(cmd, frag);
        cmd[flen] = '\0';
        debug_msg("layered parameters: %s\n", cmd);
        return TRUE;
}
Esempio n. 5
0
int
vanilla_decoder_describe (uint8_t   pkt_pt,
                          u_char  *data,
                          uint32_t  data_len,
                          char    *out,
                          uint32_t  out_len)
{
	codec_id_t            pri_id;
        const codec_format_t *pri_cf;

        pri_id = codec_get_by_payload(pkt_pt);
        if (pri_id) {
                pri_cf = codec_get_format(pri_id);
                strncpy(out, pri_cf->long_name, out_len);
        } else {
                strncpy(out, "Unknown", out_len);
        }

        /* string safety - strncpy not always safe */
        out[out_len - 1] = '\0';

        UNUSED(data);
        UNUSED(data_len);

        return TRUE;
}
Esempio n. 6
0
int
codec_audio_formats_compatible(codec_id_t id1, codec_id_t id2)
{
        const codec_format_t *cf1, *cf2;
        int match;
        
        assert(codec_id_is_valid(id1));
        assert(codec_id_is_valid(id2));
        
        cf1 = codec_get_format(id1);
        cf2 = codec_get_format(id2);

        match = !memcmp(&cf1->format, &cf2->format, sizeof(audio_format)); 

        return match;
}
Esempio n. 7
0
static int
audio_device_attempt_config(session_t *sp, audio_config *config)
{
        audio_format *inf, *ouf;
        const codec_format_t *incf;
        int success;

        incf = codec_get_format(config->primary);
        assert(incf);
        
        inf = audio_format_dup(&incf->format);
        ouf = audio_format_dup(&incf->format);

        if (inf->channels != 2 && config->render_3d) {
                /* If 3d rendering is enabled we need stereo output
                 * format. 
                 */
                ouf->channels = 2;
        }

        success = audio_open(config->device, inf, ouf);
        if (success) {
                mixer_info_t  mi;
                uint16_t unit_len;
                assert(sp->ms           == NULL);
                assert(sp->tb           == NULL);
                assert(sp->cushion      == NULL);

                audio_non_block(config->device);

                /* Initialize read and write components */
                sp->meter_period = inf->sample_rate / 15;
                unit_len         = inf->bytes_per_block * 8 / (inf->bits_per_sample*inf->channels); 
                tx_create(&sp->tb, sp, (uint16_t)inf->sample_rate, (uint16_t)inf->channels, (uint16_t)unit_len);
                cushion_create(&sp->cushion, (uint16_t)inf->sample_rate);
		sp->cur_ts = ts_convert(inf->sample_rate, sp->cur_ts);
                mi.sample_rate   = ouf->sample_rate;
                mi.channels      = ouf->channels;
                mi.buffer_length = 32640;
                mix_create(&sp->ms, &mi, sp->cur_ts);

                if (zero_buf == NULL) {
                        zero_buf = (sample*)xmalloc(unit_len * sizeof(sample));
                        audio_zero(zero_buf, unit_len, DEV_S16);
                }
        }

        audio_format_free(&inf);
        audio_format_free(&ouf);

        return success;
}
Esempio n. 8
0
uint32_t
codec_get_samples_per_frame(codec_id_t id)
{
        const codec_format_t *cf;
        uint32_t spf;

        assert(codec_id_is_valid(id));
        cf = codec_get_format(id);
        spf = cf->format.bytes_per_block * 8 / 
                (cf->format.channels * cf->format.bits_per_sample);

        return spf;
}
Esempio n. 9
0
uint32_t 
codec_peek_frame_size(codec_id_t id, u_char *data, uint16_t blk_len)
{
        uint16_t    ifs, fmt;

        assert(codec_id_is_valid(id));

        ifs = CODEC_GET_IFS_INDEX(id);
        fmt = CODEC_GET_FMT_INDEX(id);        

        if (codec_table[ifs].cx_peek_size) {
                return codec_table[ifs].cx_peek_size(fmt, data, (int)blk_len);
        } else {
                const codec_format_t *cf = codec_get_format(id);
                return cf->mean_coded_frame_size;
        }
}
Esempio n. 10
0
static int
file_and_codec_compatible(const sndfile_fmt_t *sff, codec_id_t cid)
{
        const codec_format_t *cf;
        cf = codec_get_format(cid);
        
        if (cf == NULL) {
                return FALSE;
        }

        if (sff->sample_rate == (uint32_t)cf->format.sample_rate &&
            sff->channels    == (uint32_t)cf->format.channels) {
                return TRUE;
        } 

        return FALSE;
}
Esempio n. 11
0
static void
list_codecs(void)
{
        uint32_t i, cnt;
        codec_id_t cid;
        const codec_format_t *cf;

        cnt = codec_get_number_of_codecs();

        for(i = 0; i < cnt; i++) {
                cid = codec_get_codec_number(i);
                cf  = codec_get_format(cid);
                printf("%s\n", cf->long_name);
        }

        return;
}
Esempio n. 12
0
int
vanilla_decoder_peek(uint8_t   pkt_pt,
                     u_char  *buf,
                     uint32_t  len,
                     uint16_t  *upp,
                     uint8_t   *pt)
{
        codec_id_t cid;

        assert(buf != NULL);
        assert(upp != NULL);
        assert(pt  != NULL);

        cid = codec_get_by_payload(pkt_pt);
        if (cid) {
                const codec_format_t *cf;
                uint32_t               unit, done, step;
                /* Vanilla coding does nothing but group
                 * units.
                 */
                cf   = codec_get_format(cid);
                unit = 0;
                done = cf->mean_per_packet_state_size;
                while(done < len) {
                        step = codec_peek_frame_size(cid, buf+done, (uint16_t)(len - done));
                        if (step == 0) {
                                debug_msg("Zero data len for audio unit ?\n");
                                goto fail;
                        }
                        done += step;
                        unit ++;
                }

                assert(done >= len);

                if (done != len) goto fail;
                *upp = (uint16_t)unit;
                *pt  = pkt_pt;
                return TRUE;
        }
fail:
        *upp = 0;
        *pt  = 255;
        return FALSE;
}
Esempio n. 13
0
/* For compatibility only */
codec_id_t 
codec_get_first_mapped_with(uint16_t sample_rate, uint16_t channels)
{
        const codec_format_t *cf;
        int pt;
        
        for(pt = 0; pt < NUM_PAYLOADS; pt++) {
                if (payload_map[pt]) {
                        cf = codec_get_format(payload_map[pt]);
                        if (cf->format.sample_rate == sample_rate &&
                            cf->format.channels    == channels) {
                                return payload_map[pt];
                        }
                }
        }
        debug_msg("No mapped codecs compatible (%d, %d)\n",
                  sample_rate, channels);
        return 0;
}
Esempio n. 14
0
int
codec_map_payload(codec_id_t id, u_char pt)
{
        if (payload_is_valid(pt) && codec_id_is_valid(id)) {
                if (payload_map[pt] != 0) {
                        codec_unmap_payload(id, pt);
                }
                payload_map[pt] = id;
                codec_map[CODEC_GET_IFS_INDEX(id)][CODEC_GET_FMT_INDEX(id)] = pt;
                return TRUE;
        }
#ifdef DEBUG
        {
                const codec_format_t *cf;
                cf = codec_get_format(id);
                debug_msg("Failed to map payload for %s\n", cf->long_name);
        }
#endif /* DEBUG */
        return FALSE;
}
Esempio n. 15
0
int
redundancy_encoder_get_parameters(u_char *state, char *buf, uint32_t blen)
{
        const codec_format_t *cf;
        red_enc_state *r;
        uint32_t i, used, flen;

        char frag[CODEC_LONG_NAME_LEN+5]; /* XXX/nn/\0 + 1*/

        assert(blen > 0);
        assert(buf != NULL);

        r = (red_enc_state*)state;
        if (r->n_layers < 2) {
                debug_msg("Redundancy encoder has not had parameters set!\n");
                return FALSE;
        }

        *buf = '\0';
	flen = 0;

        for(i = 0, used = 0; i < r->n_layers; i++) {
                cf = codec_get_format(r->layer[i].cid);
                assert(cf != NULL);
                sprintf(frag,
                        "%s/%d/",
                        cf->long_name,
                        r->layer[i].pkts_off);
                flen += strlen(frag);
                if (used+flen > blen) {
                        debug_msg("buffer overflow would have occured.\n");
                        *buf = '\0';
                        return FALSE;
                }
                strcat(buf + used, frag);
                used += flen;
        }
        buf[used - 1] = '\0';
        debug_msg("red parameters: %s\n", buf);
        return TRUE;
}
Esempio n. 16
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);
}
Esempio n. 17
0
/* Just returns the long name of the codec.
 * Could display number of layers if really bothered.
 */
int
layered_decoder_describe (uint8_t   pkt_pt,
                          u_char  *data,
                          uint32_t  data_len,
                          char    *out,
                          uint32_t  out_len)
{
        uint32_t hdr32, slen;
        uint8_t hdrpt;
		uint16_t blen, mrk;
		codec_id_t            pri_id;
        const codec_format_t *pri_cf;

		UNUSED(pkt_pt);

        hdr32 = ntohl(*(uint32_t*)data);
        if(hdr32 & LAY_HDR32_PAT) {
                hdrpt = (uint8_t)(LAY_HDR32_GET_PT(hdr32));
                mrk = (uint16_t)(LAY_HDR32_GET_MRK(hdr32));
                blen = (uint16_t)(LAY_HDR32_GET_LEN(hdr32));

                pri_id = codec_get_by_payload(hdrpt);
                if(pri_id) {
                        pri_cf = codec_get_format(pri_id);
                        slen = strlen(pri_cf->long_name);
                        strncpy(out, pri_cf->long_name, out_len);
                        goto done;
                }
        }
        strncpy(out, "Unknown", out_len);

done:
        /* string safety - strncpy not always safe */
        out[out_len - 1] = '\0';

        UNUSED(data_len);

        return TRUE;
}
Esempio n. 18
0
static int
read_and_encode(coded_unit        *out,
                codec_state       *encoder, 
                struct s_sndfile  *sf_in)
{
        const codec_format_t *cf;
        coded_unit           dummy;
        sample               *buf;
        uint16_t req_samples, act_samples;

        req_samples = codec_get_samples_per_frame(encoder->id);
        buf         = (sample*)block_alloc(sizeof(sample) * req_samples);

        act_samples = (uint16_t)snd_read_audio(&sf_in, buf, req_samples);

        if (req_samples != act_samples) {
                memset(buf + act_samples, 0, sizeof(short) * (req_samples - act_samples));
        }

        cf = codec_get_format(encoder->id);
        assert(cf != NULL);
        dummy.id = codec_get_native_coding((uint16_t)cf->format.sample_rate, 
                                            (uint16_t)cf->format.channels);
        dummy.state     = NULL;
        dummy.state_len = 0;
        dummy.data      = (u_char*)buf;
        dummy.data_len  = req_samples * sizeof(short);

        assert(out != NULL);

        if (codec_encode(encoder, &dummy, out) == FALSE) {
                abort();
        }

        block_free(dummy.data, dummy.data_len);

        return (sf_in != NULL);
}
Esempio n. 19
0
int
codec_decode(codec_state *cs,
             coded_unit  *in,
             coded_unit  *out)
{
        const codec_format_t *cf;
        codec_id_t           id;
        uint16_t              ifs, fmt, rate, channels;
        int                  success;

        assert(cs  != NULL);
        assert(out != NULL);
        assert(in  != NULL);
        
        id = cs->id;
        assert(in->id == cs->id);
        assert(codec_is_native_coding(in->id) == FALSE);

        ifs = CODEC_GET_IFS_INDEX(id);
        fmt = CODEC_GET_FMT_INDEX(id);

        /* Setup outgoing data block */
        cf = codec_get_format(id);
        assert(out->state == NULL);
        assert(out->data  == NULL);
        rate     = (uint16_t)cf->format.sample_rate;
        channels = (uint16_t)cf->format.channels;
        out->id       = codec_get_native_coding(rate, channels);
        out->data_len = cf->format.bytes_per_block;
        out->data     = (u_char*)block_alloc(out->data_len);

        /* Decode */
        xmemchk();
        success = codec_table[ifs].cx_decode(fmt, cs->state, in, (sample*)out->data);
        xmemchk();

        return success;
}
Esempio n. 20
0
int
codec_can_decode(codec_id_t id)
{
        uint32_t ifs;

        ifs = CODEC_GET_IFS_INDEX(id);

        assert(codec_id_is_valid(id));        
        assert(ifs < NUM_CODEC_INTERFACES);

        if (codec_table[ifs].cx_can_decode) {
                /* cx_can_encode only needs to exist if encoder and decoder are asymmetric */
                return codec_table[ifs].cx_can_decode(CODEC_GET_FMT_INDEX(id));
        }  else {
                const codec_format_t *cf;
                cf = codec_get_format(id);
                if (cf->format.sample_rate % 8000) {
                        return FALSE; /* Only m * 8k at moment */
                }
        }
        
        return TRUE;
}
Esempio n. 21
0
static void
redundancy_decoder_output(channel_unit *chu, struct s_pb *out, timestamp_t playout)
{
        const codec_format_t *cf;
        codec_id_t cid;
        u_char  *hp, *dp, *de, ppt, bpt;
        uint32_t hdr32, blen, boff;
        timestamp_t ts_max_off, ts_blk_off, this_playout;

        hp = dp = chu->data;
        de = chu->data + chu->data_len;

        /* move data pointer past header */
        while (ntohl(*((uint32_t*)dp)) & RED_HDR32_PAT) {
                dp += 4;
        }

        if (dp == hp) {
                debug_msg("Not a redundant block\n");
                return;
        }

        /* At this point dp points to primary payload type.
         * This is a most useful quantity... */
        ppt   = *dp;
        dp += 1;
        assert(dp < de);

        /* Max offset should be in first header.  Want max offset
         * as we nobble timestamps to be:
         *              playout + max_offset - this_offset
         */

        cid   = codec_get_by_payload(ppt);
        if (codec_id_is_valid(cid) == FALSE) {
                debug_msg("Primary not recognized.\n");
                return;
        }

        cf = codec_get_format(cid);
        assert(cf != NULL);

        hdr32 = ntohl(*(uint32_t*)hp);
        ts_max_off = ts_map32(cf->format.sample_rate, RED_HDR32_GET_OFF(hdr32));
	blen = 0;

        while (hdr32 & RED_HDR32_PAT) {
                boff  = RED_HDR32_GET_OFF(hdr32);
                blen  = RED_HDR32_GET_LEN(hdr32);
                bpt   = (u_char)RED_HDR32_GET_PT(hdr32);

                /* Calculate playout point = playout + max_offset - offset */
                ts_blk_off = ts_map32(cf->format.sample_rate, boff);
                this_playout = ts_add(playout, ts_max_off);
                this_playout = ts_sub(this_playout, ts_blk_off);
                hp += 4; /* hdr */
                red_split_unit(ppt, bpt, dp, blen, this_playout, out);
                xmemchk();
                dp += blen;
                hdr32 = ntohl(*(uint32_t*)hp);
        }

        this_playout = ts_add(playout, ts_max_off);
        hp += 1;
        blen = (uint32_t) (de - dp);
        red_split_unit(ppt, ppt, dp, blen, this_playout, out);
        xmemchk();
}
Esempio n. 22
0
static void
red_split_unit(u_char  ppt,        /* Primary payload type */
               u_char  bpt,        /* Block payload type   */
               u_char *b,          /* Block pointer        */
               uint32_t blen,       /* Block len            */
               timestamp_t    playout,    /* Block playout time   */
               struct s_pb *out)   /* media buffer         */
{
        const codec_format_t *cf;
        media_data *md;
        codec_id_t  cid, pid;
        coded_unit *cu;
        u_char     *p,*pe;
        timestamp_t        step;

        pid = codec_get_by_payload(ppt);
        if (!pid) {
                debug_msg("Payload not recognized\n");
                return;
        }

        cid = codec_get_by_payload(bpt);
        if (!cid) {
                debug_msg("Payload not recognized\n");
                return;
        }

        if (!codec_audio_formats_compatible(pid, cid)) {
                debug_msg("Primary (%d) and redundant (%d) not compatible\n", ppt, bpt);
                return;
        }

        cf = codec_get_format(cid);
        assert(cf != NULL);
        step = ts_map32(cf->format.sample_rate, codec_get_samples_per_frame(cid));

        p  = b;
        pe = b + blen;
        while(p < pe) {
                cu = (coded_unit*)block_alloc(sizeof(coded_unit));
                cu->id = cid;
                if (p == b && cf->mean_per_packet_state_size) {
                        cu->state_len = cf->mean_per_packet_state_size;
                        cu->state     = block_alloc(cu->state_len);
                        memcpy(cu->state, p, cu->state_len);
                        p            += cu->state_len;
                } else {
                        cu->state     = NULL;
                        cu->state_len = 0;
                }

                cu->data_len = (uint16_t)codec_peek_frame_size(cid, p, (uint16_t)(pe - p));
                cu->data     = block_alloc(cu->data_len);
                memcpy(cu->data, p, cu->data_len);
                p += cu->data_len;
                md = red_media_data_create_or_get(out, playout);
                if (md->nrep == MAX_MEDIA_UNITS) continue;
                if (place_unit(md, cu) == TRUE) {
                        playout = ts_add(playout, step);
                } else {
                        /* unit could not be placed - destroy */
                        if (cu->state_len) {
                                block_free(cu->state, cu->state_len);
                        }
                        block_free(cu->data, cu->data_len);
                        block_free(cu, sizeof(coded_unit));
                }
        }
}
Esempio n. 23
0
int
redundancy_decoder_describe (uint8_t   pkt_pt,
                             u_char  *data,
                             uint32_t  data_len,
                             char    *out,
                             uint32_t  out_len)
{
        const codec_format_t *cf;
        codec_id_t            cid;
        uint32_t hdr32, slen, blksz, off, nlen;
        u_char  *p, pt;

        UNUSED(pkt_pt);

        *out = '\0';
        slen = 0;

        p   = data;
        hdr32 = ntohl(*((uint32_t*)p));
        while (hdr32 & RED_HDR32_PAT) {
                pt    = (u_char)RED_HDR32_GET_PT(hdr32);
                off   = RED_HDR32_GET_OFF(hdr32);
                blksz = RED_HDR32_GET_LEN(hdr32);
                cid   = codec_get_by_payload(pt);

                if (cid == 0) {
                        p += 4;
                        hdr32 = ntohl(*((uint32_t*)p));
                        continue;
                }

                cf = codec_get_format(cid);
                assert(cf != NULL);

                nlen = strlen(cf->long_name);

                if (slen + nlen >=  out_len) {
                        debug_msg("Out of buffer space\n");
                        return FALSE;
                }
                if (slen != 0) {
                        memmove(out + nlen + 1, out, slen);
                }
                strncpy(out, cf->long_name, nlen);
                slen += nlen;
                out[nlen] = '/';
                slen++;
                out[nlen+1] = '\0';
                p += 4;
                assert((uint32_t)(p - data) < data_len);
                hdr32 = ntohl(*((uint32_t*)p));
        }

        pt  = *p;
        cid = codec_get_by_payload(pt);
        if (cid == 0) {
                return FALSE;
        }

        cf = codec_get_format(cid);
        assert(cf != NULL);

        nlen = strlen(cf->long_name);

        if (slen + nlen >=  out_len) {
                debug_msg("Out of buffer space\n");
                return FALSE;
        }
        memmove(out + nlen + 1, out, slen);
        strncpy(out, cf->long_name, nlen);
        out[nlen] = '/';
        slen += nlen + 1;

        /* Axe trailing separator */
        out[slen-1] = '\0';

        return TRUE;
}
Esempio n. 24
0
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);
}
Esempio n. 25
0
int
layered_decoder_peek(uint8_t   pkt_pt,
                     u_char  *buf,
                     uint32_t  len,
                     uint16_t  *upp,
                     uint8_t   *pt)
{
        codec_id_t cid;
        u_char               *p, *data;
        uint32_t hdr32;
        uint8_t hdrpt;
        uint16_t blen, mrk;
        assert(buf != NULL);
        assert(upp != NULL);
        assert(pt  != NULL);
        UNUSED(pkt_pt);

        p = data = buf;

        hdr32 = ntohl(*(uint32_t*)p);

        if(hdr32 & LAY_HDR32_PAT) {
                hdrpt = (uint8_t)(LAY_HDR32_GET_PT(hdr32));
                mrk = (uint16_t)(LAY_HDR32_GET_MRK(hdr32));
                blen = (uint16_t)(LAY_HDR32_GET_LEN(hdr32));
                p+=4;
                data += 4 + blen;
                hdr32 = ntohl(*(uint32_t*)p);
/*                assert(((uint32_t)data - (uint32_t)buf) <= blen); */
        }
        else {
                debug_msg("Invalid layered header\n");
                goto fail;
        }

        /* I'm haven't decided what exactly to do here yet, so for
         * the time being if the header seems OK we return TRUE. The
         * options are:
         * (i) have a new function codec_peek_layer_frame_size
         * (ii) work out length of total frame from length in header
         * (iii) just check that length of packet matches what is in
         *       the header
         * But what to do about *upp?
         * The problem is that codec_peek_frame_size, if used with
         * codec_vdvi, calls vdvi_decode, assuming a complete frame.
         * Of course we only have one layer at this stage, so the
         * decode function will fail. I am going to ignore this for
         * the time being.
         */

        *pt = hdrpt;
        cid = codec_get_by_payload(*pt);
        if (cid) {
                const codec_format_t *cf;
                uint32_t               unit, done, step;
                /* extra check since the header check seems
                 * to fail quite a lot (why?)
                */
                if(codec_can_layer(cid)==1) goto fail;
                cf   = codec_get_format(cid);
                unit = 0;
                done = cf->mean_per_packet_state_size;
                done += 4; /* step over header */
                while(done < len) {
                        step = codec_peek_frame_size(cid, buf+done, (uint16_t)(len));
                        if (step == 0) {
                                debug_msg("Zero data len for audio unit ?\n");
                                goto fail;
                        }
                        done += blen;
                        unit ++;
                }

/*                assert(done <= len);*/

                if (done != len) goto fail;
                *upp = (uint16_t)unit;
                return TRUE;
        }

        debug_msg("layered_decoder_peek - codec not found\n");
fail:
        debug_msg("layered_decoder_peek error (len = %d)\n", len);
        *upp = 0;
        *pt  = 255;
        return FALSE;
}
Esempio n. 26
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. 27
0
int
redundancy_encoder_set_parameters(u_char *state, char *cmd)
{
        u_char *encbuf;
        red_enc_state *n, *cur;
        const codec_format_t *cf;
        uint32_t nl, po;
        codec_id_t  cid;
        char *s;
        int success = FALSE;

        assert(state != NULL);
        assert(cmd   != NULL);

        /* Create a temporary encoder, try to set it's params */
        redundancy_encoder_create(&encbuf, &nl);
        n = (red_enc_state*)encbuf;
        assert(n != NULL);

        s = (char *) strtok(cmd, "/");
        cid = codec_get_by_name(s);
        if (!codec_id_is_valid(cid)) {
                debug_msg("codec not recognized\n");
                goto done;
        }

        s = (char *) strtok(NULL, "/");
        po = atoi(s);

        if (po > 20) {
                debug_msg("offset too big\n");
                goto done;
        }

        n->layer[0].cid       = cid;
        n->layer[0].pkts_off  = po;
        n->n_layers           = 1;

        while (n->n_layers < RED_MAX_LAYERS) {
                s = (char *) strtok(NULL, "/");
                if (s == NULL) break;
                cid = codec_get_by_name(s);
                if (!codec_id_is_valid(cid)) {
                        debug_msg("codec not recognized\n");
                        goto done;
                }

                s = (char *) strtok(NULL, "/");
                if (s == NULL) {
                        debug_msg("Incomplete layer info\n");
                        goto done;
                }
                po = atoi(s);
                if (po > 20) {
                        debug_msg("offset too big\n");
                        goto done;
                }

                n->layer[n->n_layers].cid      = cid;
                n->layer[n->n_layers].pkts_off = po;
                n->n_layers ++;
        }


        redundancy_encoder_reset(state);
        /* Take bits from temporary encoder state we want */
        cur = (red_enc_state*)state;
        memcpy(cur->layer, n->layer, sizeof(red_layer)*RED_MAX_LAYERS);
        cur->n_layers = n->n_layers;

        /* work out history = duration of audio frame * maximum offset */
        cf = codec_get_format(cur->layer[cur->n_layers - 1].cid);
        cur->history = ts_map32(cf->format.sample_rate,
                                codec_get_samples_per_frame(cur->layer[cur->n_layers - 1].cid) *
                                cur->layer[cur->n_layers - 1].pkts_off);

        success = TRUE;
done:
        encbuf = (u_char*)n;
        redundancy_encoder_destroy(&encbuf, nl);
        return success;
}
Esempio n. 28
0
void
session_init(session_t *sp, int index, int mode)
{
	codec_id_t                 cid;
        const codec_format_t      *cf   = NULL;
        const converter_details_t *conv = NULL;
        const cc_details_t        *ccd  = NULL;
        uint8_t                    i;

	memset(sp, 0, sizeof(session_t));

	codec_init();
        sanity_check_payloads();
        vu_table_init();

	cid = codec_get_by_name("DVI-8K-Mono");
        assert(cid);
        cf  = codec_get_format(cid);
	sp->cur_ts                      = ts_map32(8000,0);
        sp->encodings[0]		= codec_get_payload(cid);           	/* user chosen encoding for primary */
	sp->num_encodings		= 1;                                	/* Number of encodings applied */

        ccd = channel_get_null_coder();
        channel_encoder_create(ccd->descriptor, &sp->channel_coder);

        conv                            = converter_get_details(0);
        sp->converter                   = conv->id;
	sp->other_session		= NULL;				/* Completed in main_engine.c if we're a transoder */
	sp->id				= index;
	sp->mode         		= mode;
        sp->rtp_session_count           = 0;
	for (i = 0; i < MAX_LAYERS; i++) {
		sp->rx_rtp_port[i] = sp->tx_rtp_port[i] = sp->rx_rtcp_port[i] = sp->tx_rtcp_port[i] = PORT_UNINIT;
                sp->rtp_session[i] = NULL;
	}
	sp->rx_rtp_port[0] 		= 5004; /* Default ports per:             */
	sp->tx_rtp_port[0] 		= 5004; /* draft-ietf-avt-profile-new-00  */
        sp->rx_rtcp_port[0]   		= 5005;
        sp->tx_rtcp_port[0]   		= 5005;
	sp->ttl				= 127;
        sp->filter_loopback             = TRUE;
	sp->playing_audio		= TRUE;
	sp->lecture			= FALSE;
	sp->auto_lecture		= 0;
 	sp->receive_audit_required	= FALSE;
	sp->silence_detection		= SILENCE_DETECTION_OFF;
	sp->sync_on			= FALSE;
	sp->agc_on			= FALSE;
        sp->ui_on                       = FALSE;
	sp->meter			= TRUE;					/* Powermeter operation */
	sp->in_file 			= NULL;
	sp->out_file  			= NULL;
	sp->local_file_player		= NULL;
	sp->mbus_engine_addr		= NULL;
	sp->mbus_engine			= NULL;
	sp->mbus_ui_addr		= NULL;
	sp->mbus_video_addr		= xstrdup("(media:video module:engine)");
	sp->min_playout			= 0;
	sp->max_playout			= 1000;
        sp->last_depart_ts              = 0;
	sp->loopback_gain		= 0;
	sp->layers                      = 1;
	sp->ui_activated		= FALSE;
	sp->encrkey			= NULL;
	sp->logger                      = NULL;
	sp->mbus_waiting		= FALSE;
	sp->mbus_waiting_token		= NULL;
	sp->mbus_go 			= FALSE;
	sp->mbus_go_token		= NULL;
	sp->magic			= 0xcafebabe;				/* Magic number for debugging */

        source_list_create(&sp->active_sources);

	sp->title = "Untitled session";
	strncpy(sp->asc_address[0], "127.0.0.3", MAXHOSTNAMELEN);	/* Yeuch! This value should never be used! */
}
Esempio n. 29
0
codec_id_t
codec_get_matching(const char *short_name, uint16_t freq, uint16_t channels)
{
        /* This has been changed to try really hard to find a matching codec.
         * The reason is that it's now called as part of the command-line      
         * parsing, and so has to cope with user entered codec names. Also, it 
         * should recognise the names sdr gives the codecs, for compatibility 
         * with rat-v3.0.                                                [csp] 
         */

        /* This is not quite as inefficient as it looks, since stage 1 will
         * almost always find a match.                                     
         */

        const codec_format_t  *cf = NULL;
        codec_id_t             cid = 0; 
        uint32_t                i, codecs;
        char                  *long_name;

        /* Stage 1: Try the designated short names... */
        codecs = codec_get_number_of_codecs();
        for(i = 0; i < codecs; i++) {
                cid = codec_get_codec_number(i);
                cf  = codec_get_format(cid);
                if (cf->format.sample_rate == freq  && 
                    cf->format.channels == channels && 
                    !strcasecmp(short_name, cf->short_name)) {
                        return cid;
                }
        }

        /* Stage 2: Try to generate a matching name... */
        long_name = (char *) xmalloc(strlen(short_name) + 12);
        sprintf(long_name, "%s-%dK-%s", short_name, freq/1000, channels==1?"MONO":"STEREO");
        for(i = 0; i < codecs; i++) {
                cid = codec_get_codec_number(i);
                cf  = codec_get_format(cid);
                if (cf->format.sample_rate == freq  && 
                    cf->format.channels == channels && 
                    !strcasecmp(long_name, cf->long_name)) {
                        xfree(long_name);
                        return cid;
                }
        }

        /* Stage 3: Nasty hack... PCM->PCMU for compatibility with sdr 
         * and old rat versions 
         */
        if (strncasecmp(short_name, "pcm", 3) == 0) {
                sprintf(long_name, "PCMU-%dK-%s", freq/1000, channels==1?"MONO":"STEREO");
                for(i = 0; i < codecs; i++) {
                        cid = codec_get_codec_number(i);
                        cf  = codec_get_format(cid);
                        if (cf->format.sample_rate == freq  && 
                            cf->format.channels == channels && 
                            !strcasecmp(long_name, cf->long_name)) {
                                xfree(long_name);
                                return cid;
                        }
                }
        }

        xfree(long_name);

        debug_msg("Unable to find codec \"%s\" at rate %d channels %d\n", short_name, freq, channels);
        return 0;
}
Esempio n. 30
0
int
redundancy_decoder_peek(uint8_t   pkt_pt,
                        u_char  *buf,
                        uint32_t  len,
                        uint16_t  *upp,
                        uint8_t   *pt)
{
        const codec_format_t *cf;
        codec_id_t            cid;
        u_char               *p, *data;
        uint32_t               hdr32, dlen, blen;
        uint16_t               units;
        assert(buf != NULL);
        assert(upp != NULL);
        assert(pt  != NULL);

        /* Just check primary, so skip over other headers and
         * advance data pointer past them.
         */
        p = data = buf;
        hdr32 = ntohl(*(uint32_t*)p);
        while ((hdr32 & RED_HDR32_PAT)) {
                blen = RED_HDR32_GET_LEN(hdr32);
                p    += 4; /* goto next hdr */
                data += 4 + blen;
                hdr32 = ntohl(*(uint32_t*)p);
                assert(((unsigned long)data - (unsigned long)buf) <= len);
        }

        *pt = *p;
        data += 1; /* step over payload field of primary */

        cid = codec_get_by_payload(*pt);

        if (!cid) {
                debug_msg("Codec not found\n");
                return FALSE;
        }

        /* Primary data length */
        dlen = len - (uint32_t)(data - buf);

        cf = codec_get_format(cid);
        assert(cf);

        data += cf->mean_per_packet_state_size;
        dlen -= cf->mean_per_packet_state_size;

        assert(((unsigned long)data - (unsigned long)buf) <= len);

        units = 0;
        while (dlen != 0) {
                blen = codec_peek_frame_size(cid, p, (uint16_t)dlen);
                assert(blen != 0);
                data += blen;
                dlen -= blen;
                units ++;
                assert(((unsigned long)data - (unsigned long)buf) <= len);
        }

        *upp = units;
        assert(*upp < 50);

        UNUSED(pkt_pt);

        return TRUE;
}