示例#1
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;
}
示例#2
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;
}
示例#3
0
static void
decode_and_write(struct s_sndfile           *sf_out,
                 struct s_codec_state_store *decoder_states,
                 media_data                 *md)
{
        codec_state *decoder;
        coded_unit  *cu;
        int          i;

        assert(md->nrep > 0);
        for(i = 0; i < md->nrep; i++) {
                if (codec_is_native_coding(md->rep[i]->id)) {
                        break;
                }
        }
                
        if (i == md->nrep) {
                /* no decoded audio available for frame */
                cu = (coded_unit*)block_alloc(sizeof(coded_unit));
                assert(cu != NULL);
                memset(cu, 0, sizeof(coded_unit));
                decoder = codec_state_store_get(decoder_states, md->rep[0]->id);
                codec_decode(decoder, md->rep[0], cu);
                assert(md->rep[md->nrep] == NULL);
                md->rep[md->nrep] = cu;
                md->nrep++;
        }
        
        assert(codec_is_native_coding(md->rep[md->nrep - 1]->id));
        assert(sf_out != NULL);

        snd_write_audio(&sf_out, 
                        (sample*)md->rep[md->nrep - 1]->data,        
                        md->rep[md->nrep - 1]->data_len / sizeof(sample));        
     
}       
示例#4
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;
}
示例#5
0
int 
codec_get_native_info(codec_id_t cid, 
                      uint16_t   *p_rate, 
                      uint16_t   *p_channels)
{
        uint32_t i, c, index;

        if (codec_is_native_coding(cid)) {
                index = CODEC_GET_FMT_INDEX(cid);
                /* Calculate and verify index in table of acceptable rates */
                i = index / max_channels;
                if (p_rate != NULL) {
                        *p_rate = sampling_rates[i];
                }
                /* Calculate and verify number of channels */
                c = (index % max_channels) + 1;
                if (p_channels != NULL) {
                        *p_channels = (uint16_t)c;
                }
                return TRUE;
        }
        return FALSE;
}
示例#6
0
int
codec_id_is_valid(codec_id_t id)
{
        uint32_t ifs, fmt;

        if (codec_is_native_coding(id)) {
                /* Native codings should be tested with
                 * codec_is_native_coding */
                debug_msg("Coding is invalid because it is a native coding\n");
                return FALSE;
        }
        
        if (!CODEC_VALID_PAD(id) || 
            !CODEC_VALID_IFS(id) ||
            !CODEC_VALID_FMT(id)) {
                debug_msg("Codec id (0x%08x) invalid (pad %x, ifs %x, fmt %x)",
                          id, CODEC_VALID_PAD(id), CODEC_VALID_IFS(id),
                          CODEC_VALID_FMT(id));
                return FALSE;
        }

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

        if (ifs >= NUM_CODEC_INTERFACES) {
                /* Table index too large */
                debug_msg("Codec index outside table\n");
                return FALSE; 
        }

        if (fmt >= num_fmts_supported[ifs]) {
                /* Format index too large */
                debug_msg("Format index outside table %d / %d\n", fmt, num_fmts_supported[ifs]);
                return FALSE;
        }
        return TRUE;
}
示例#7
0
int
repair(repair_id_t                 r,
       int                         consec_lost,
       struct s_codec_state_store *states,
       media_data                 *prev,
       coded_unit                 *missing)
{
        int          src, success;

        r = REPAIR_ID_TO_IDX(r);
        assert((unsigned)r < REPAIR_NUM_SCHEMES);

        if (prev->nrep == 0) {
                debug_msg("No data to repair from\n");
                return FALSE;
        }

        assert(missing->state == 0);
        assert(missing->data  == 0);

        /* check if first encoding has repair routine, test does
         * not make sense with a native (raw) encoding so check
         * that first
         */
        if (codec_specific_repair_allowed &&
            codec_is_native_coding(prev->rep[0]->id) == FALSE &&
            codec_decoder_can_repair(prev->rep[0]->id) &&
            prev->rep[0]->id == missing->id) {
                codec_state *st;

                st = codec_state_store_get(states, prev->rep[0]->id);
                success = codec_decoder_repair(prev->rep[0]->id,
                                               st,
                                               (uint16_t)consec_lost,
                                               prev->rep[0],
                                               missing,
                                               NULL);
                return success;
        }

/* If native (waveform) audio is available, the last entry is device
 * compatible if it is native.  We use this as it means we don't have to
 * re-apply 3d rendering and sample rate conversion if they are in use.
 */
        src = prev->nrep - 1;
        if (src >= 0 && codec_is_native_coding(prev->rep[src]->id)) {
                const audio_format *pfmts[2];
                audio_format        fmt;
                coded_unit  *p;
                uint32_t      rate;
		uint16_t      channels;
                sample      *bufs[2];

                p = prev->rep[src];
                /* set up missing block */
                missing->id       = p->id;
                missing->data     = (u_char*)block_alloc(p->data_len);
                missing->data_len = p->data_len;

                /* set up format */
                codec_get_native_info(p->id, &rate, &channels);
                fmt.encoding        = DEV_S16;
                fmt.sample_rate     = (int)rate;
                fmt.bits_per_sample = 16;
                fmt.channels        = channels;
                fmt.bytes_per_block = p->data_len;

                /* Pointer tweaking to get data in format repair function
                 * expects.
                 */
                pfmts[0] = &fmt;
                pfmts[1] = &fmt;

                bufs[0] = (sample*) p->data;
                bufs[1] = (sample*) missing->data;

                schemes[r].action(bufs, pfmts, 2, 1, consec_lost);
                return TRUE;
        } else {
                debug_msg("No native audio in previous unit to use for repair\n");
        }
        return FALSE;
}