/* Copyright (c) 2011 Xiph.Org Foundation
Written by Jean-Marc Valin */ /* Redistributionanduseinsourceandbinaryforms,withorwithout modification,arepermittedprovidedthatthefollowingconditions aremet:
int opus_multistream_decoder_init(
OpusMSDecoder *st,
opus_int32 Fs, int channels, int streams, int coupled_streams, constunsignedchar *mapping
)
{ int coupled_size; int mono_size; int i, ret; char *ptr;
OpusMSDecoder *opus_multistream_decoder_create(
opus_int32 Fs, int channels, int streams, int coupled_streams, constunsignedchar *mapping, int *error
)
{ int ret;
OpusMSDecoder *st; if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
(streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
{ if (error)
*error = OPUS_BAD_ARG; return NULL;
}
st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams)); if (st==NULL)
{ if (error)
*error = OPUS_ALLOC_FAIL; return NULL;
}
ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping); if (error)
*error = ret; if (ret != OPUS_OK)
{
opus_free(st);
st = NULL;
} return st;
}
staticint opus_multistream_packet_validate(constunsignedchar *data,
opus_int32 len, int nb_streams, opus_int32 Fs)
{ int s; int count; unsignedchar toc;
opus_int16 size[48]; int samples=0;
opus_int32 packet_offset;
for (s=0;s<nb_streams;s++)
{ int tmp_samples; if (len<=0) return OPUS_INVALID_PACKET;
count = opus_packet_parse_impl(data, len, s!=nb_streams-1, &toc, NULL,
size, NULL, &packet_offset, NULL, NULL); if (count<0) return count;
tmp_samples = opus_packet_get_nb_samples(data, packet_offset, Fs); if (s!=0 && samples != tmp_samples) return OPUS_INVALID_PACKET;
samples = tmp_samples;
data += packet_offset;
len -= packet_offset;
} return samples;
}
int opus_multistream_decode_native(
OpusMSDecoder *st, constunsignedchar *data,
opus_int32 len, void *pcm,
opus_copy_channel_out_func copy_channel_out, int frame_size, int decode_fec, int soft_clip, void *user_data
)
{
opus_int32 Fs; int coupled_size; int mono_size; int s, c; char *ptr; int do_plc=0;
VARDECL(opus_res, buf);
ALLOC_STACK;
int opus_multistream_decode(
OpusMSDecoder *st, constunsignedchar *data,
opus_int32 len,
opus_int16 *pcm, int frame_size, int decode_fec
)
{ return opus_multistream_decode_native(st, data, len,
pcm, opus_copy_channel_out_short, frame_size, decode_fec, OPTIONAL_CLIP, NULL);
}
int opus_multistream_decode24(
OpusMSDecoder *st, constunsignedchar *data,
opus_int32 len,
opus_int32 *pcm, int frame_size, int decode_fec
)
{ return opus_multistream_decode_native(st, data, len,
pcm, opus_copy_channel_out_int24, frame_size, decode_fec, 0, NULL);
}
#ifndef DISABLE_FLOAT_API int opus_multistream_decode_float(OpusMSDecoder *st, constunsignedchar *data,
opus_int32 len, float *pcm, int frame_size, int decode_fec)
{ return opus_multistream_decode_native(st, data, len,
pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0, NULL);
} #endif
int opus_multistream_decoder_ctl_va_list(OpusMSDecoder *st, int request,
va_list ap)
{ int coupled_size, mono_size; char *ptr; int ret = OPUS_OK;
coupled_size = opus_decoder_get_size(2);
mono_size = opus_decoder_get_size(1);
ptr = (char*)st + align(sizeof(OpusMSDecoder)); switch (request)
{ case OPUS_GET_BANDWIDTH_REQUEST: case OPUS_GET_SAMPLE_RATE_REQUEST: case OPUS_GET_GAIN_REQUEST: case OPUS_GET_LAST_PACKET_DURATION_REQUEST: case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: case OPUS_GET_COMPLEXITY_REQUEST:
{
OpusDecoder *dec; /* For int32* GET params, just query the first stream */
opus_int32 *value = va_arg(ap, opus_int32*);
dec = (OpusDecoder*)ptr;
ret = opus_decoder_ctl(dec, request, value);
} break; case OPUS_GET_FINAL_RANGE_REQUEST:
{ int s;
opus_uint32 *value = va_arg(ap, opus_uint32*);
opus_uint32 tmp; if (!value)
{ goto bad_arg;
}
*value = 0; for (s=0;s<st->layout.nb_streams;s++)
{
OpusDecoder *dec;
dec = (OpusDecoder*)ptr; if (s < st->layout.nb_coupled_streams)
ptr += align(coupled_size); else
ptr += align(mono_size);
ret = opus_decoder_ctl(dec, request, &tmp); if (ret != OPUS_OK) break;
*value ^= tmp;
}
} break; case OPUS_RESET_STATE:
{ int s; for (s=0;s<st->layout.nb_streams;s++)
{
OpusDecoder *dec;
dec = (OpusDecoder*)ptr; if (s < st->layout.nb_coupled_streams)
ptr += align(coupled_size); else
ptr += align(mono_size);
ret = opus_decoder_ctl(dec, OPUS_RESET_STATE); if (ret != OPUS_OK) break;
}
} break; case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST:
{ int s;
opus_int32 stream_id;
OpusDecoder **value;
stream_id = va_arg(ap, opus_int32); if (stream_id<0 || stream_id >= st->layout.nb_streams) goto bad_arg;
value = va_arg(ap, OpusDecoder**); if (!value)
{ goto bad_arg;
} for (s=0;s<stream_id;s++)
{ if (s < st->layout.nb_coupled_streams)
ptr += align(coupled_size); else
ptr += align(mono_size);
}
*value = (OpusDecoder*)ptr;
} break; case OPUS_SET_GAIN_REQUEST: case OPUS_SET_COMPLEXITY_REQUEST: case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
{ int s; /* This works for int32 params */
opus_int32 value = va_arg(ap, opus_int32); for (s=0;s<st->layout.nb_streams;s++)
{
OpusDecoder *dec;
dec = (OpusDecoder*)ptr; if (s < st->layout.nb_coupled_streams)
ptr += align(coupled_size); else
ptr += align(mono_size);
ret = opus_decoder_ctl(dec, request, value); if (ret != OPUS_OK) break;
}
} break; default:
ret = OPUS_UNIMPLEMENTED; break;
} return ret;
bad_arg: return OPUS_BAD_ARG;
}
int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
{ int ret;
va_list ap;
va_start(ap, request);
ret = opus_multistream_decoder_ctl_va_list(st, request, ap);
va_end(ap); return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.