mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avcodec/siren: MSN Siren decoder
Reviewed-by: Paul B Mahol <onemda@gmail.com> Signed-off-by: Peter Ross <pross@xvid.org>
This commit is contained in:
parent
b9426f371a
commit
c655a734b1
@ -17,6 +17,7 @@ version <next>:
|
||||
- grayworld video filter
|
||||
- AV1 Low overhead bitstream format muxer
|
||||
- swscale slice threading
|
||||
- MSN Siren decoder
|
||||
|
||||
|
||||
version 4.4:
|
||||
|
@ -508,6 +508,7 @@ OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSMPEG4V3_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_MSNSIREN_DECODER) += siren.o
|
||||
OBJS-$(CONFIG_MSP2_DECODER) += msp2dec.o
|
||||
OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o
|
||||
OBJS-$(CONFIG_MSS1_DECODER) += mss1.o mss12.o
|
||||
|
@ -479,6 +479,7 @@ extern const AVCodec ff_mp3on4float_decoder;
|
||||
extern const AVCodec ff_mp3on4_decoder;
|
||||
extern const AVCodec ff_mpc7_decoder;
|
||||
extern const AVCodec ff_mpc8_decoder;
|
||||
extern const AVCodec ff_msnsiren_decoder;
|
||||
extern const AVCodec ff_nellymoser_encoder;
|
||||
extern const AVCodec ff_nellymoser_decoder;
|
||||
extern const AVCodec ff_on2avc_decoder;
|
||||
|
@ -3222,6 +3222,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
||||
.long_name = NULL_IF_CONFIG_SMALL("MobiClip FastAudio"),
|
||||
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
|
||||
},
|
||||
{
|
||||
.id = AV_CODEC_ID_MSNSIREN,
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.name = "msnsiren",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("MSN Siren"),
|
||||
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
|
||||
},
|
||||
|
||||
/* subtitle codecs */
|
||||
{
|
||||
|
@ -514,6 +514,7 @@ enum AVCodecID {
|
||||
AV_CODEC_ID_SIREN,
|
||||
AV_CODEC_ID_HCA,
|
||||
AV_CODEC_ID_FASTAUDIO,
|
||||
AV_CODEC_ID_MSNSIREN,
|
||||
|
||||
/* subtitle codecs */
|
||||
AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs.
|
||||
|
@ -359,11 +359,13 @@ static const float noise_category6[21] = {
|
||||
typedef struct SirenContext {
|
||||
GetBitContext gb;
|
||||
|
||||
int microsoft;
|
||||
int rate_control_possibilities;
|
||||
int esf_adjustment;
|
||||
int number_of_regions;
|
||||
int scale_factor;
|
||||
int sample_rate_bits;
|
||||
int checksum_bits;
|
||||
|
||||
unsigned dw1, dw2, dw3, dw4;
|
||||
|
||||
@ -421,6 +423,15 @@ static av_cold int siren_init(AVCodecContext *avctx)
|
||||
if (!s->fdsp)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
s->microsoft = avctx->codec->id == AV_CODEC_ID_MSNSIREN;
|
||||
if (s->microsoft) {
|
||||
s->esf_adjustment = -2;
|
||||
s->number_of_regions = 14;
|
||||
s->scale_factor = 1;
|
||||
s->sample_rate_bits = 2;
|
||||
s->checksum_bits = 4;
|
||||
}
|
||||
|
||||
return av_tx_init(&s->tx_ctx, &s->tx_fn, AV_TX_FLOAT_MDCT, 1, FRAME_SIZE, &scale, 0);
|
||||
}
|
||||
|
||||
@ -626,6 +637,20 @@ static int decode_vector(SirenContext *s, int number_of_regions,
|
||||
|
||||
coefs_ptr = coefs + (region * REGION_SIZE);
|
||||
|
||||
if (category == 5 && s->microsoft) {
|
||||
i = 0;
|
||||
for (j = 0; j < REGION_SIZE; j++) {
|
||||
if (*coefs_ptr != 0) {
|
||||
i++;
|
||||
if (fabs(*coefs_ptr) > 2.0 * decoder_standard_deviation[region]) {
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
coefs_ptr++;
|
||||
}
|
||||
|
||||
noise = decoder_standard_deviation[region] * noise_category5[i];
|
||||
} else
|
||||
if (category == 5 || category == 6) {
|
||||
i = 0;
|
||||
for (j = 0; j < REGION_SIZE; j++) {
|
||||
@ -675,10 +700,22 @@ static int siren_decode(AVCodecContext *avctx, void *data,
|
||||
AVFrame *frame = data;
|
||||
int ret, number_of_valid_coefs = 20 * s->number_of_regions;
|
||||
int frame_error = 0, rate_control = 0;
|
||||
int bits_per_frame;
|
||||
|
||||
if (s->microsoft) {
|
||||
bits_per_frame = avctx->sample_rate / 50;
|
||||
|
||||
if (avpkt->size < bits_per_frame / 8)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if ((ret = init_get_bits(gb, avpkt->data, bits_per_frame - s->checksum_bits)) < 0)
|
||||
return ret;
|
||||
} else
|
||||
if ((ret = init_get_bits8(gb, avpkt->data, avpkt->size)) < 0)
|
||||
return ret;
|
||||
|
||||
skip_bits(gb, s->sample_rate_bits);
|
||||
|
||||
decode_envelope(s, gb, s->number_of_regions,
|
||||
s->decoder_standard_deviation,
|
||||
s->absolute_region_power_index, s->esf_adjustment);
|
||||
@ -697,7 +734,7 @@ static int siren_decode(AVCodecContext *avctx, void *data,
|
||||
ret = decode_vector(s, s->number_of_regions, get_bits_left(gb),
|
||||
s->decoder_standard_deviation, s->power_categories,
|
||||
s->imdct_in, s->scale_factor);
|
||||
if (ret < 0)
|
||||
if (ret < 0 && !s->microsoft)
|
||||
return ret;
|
||||
|
||||
if (get_bits_left(gb) > 0) {
|
||||
@ -715,6 +752,8 @@ static int siren_decode(AVCodecContext *avctx, void *data,
|
||||
frame_error = 1;
|
||||
}
|
||||
|
||||
skip_bits(gb, s->checksum_bits);
|
||||
|
||||
if (frame_error) {
|
||||
memcpy(s->imdct_in, s->backup_frame, number_of_valid_coefs * sizeof(float));
|
||||
memset(s->backup_frame, 0, number_of_valid_coefs * sizeof(float));
|
||||
@ -738,7 +777,7 @@ static int siren_decode(AVCodecContext *avctx, void *data,
|
||||
|
||||
*got_frame = 1;
|
||||
|
||||
return avpkt->size;
|
||||
return s->microsoft ? bits_per_frame / 8 : avpkt->size;
|
||||
}
|
||||
|
||||
static av_cold void siren_flush(AVCodecContext *avctx)
|
||||
@ -775,3 +814,19 @@ const AVCodec ff_siren_decoder = {
|
||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
|
||||
FF_CODEC_CAP_INIT_CLEANUP,
|
||||
};
|
||||
|
||||
const AVCodec ff_msnsiren_decoder = {
|
||||
.name = "msnsiren",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("MSN Siren"),
|
||||
.priv_data_size = sizeof(SirenContext),
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = AV_CODEC_ID_MSNSIREN,
|
||||
.init = siren_init,
|
||||
.close = siren_close,
|
||||
.decode = siren_decode,
|
||||
.flush = siren_flush,
|
||||
.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
|
||||
AV_CODEC_CAP_DR1,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
|
||||
FF_CODEC_CAP_INIT_CLEANUP,
|
||||
};
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#define LIBAVCODEC_VERSION_MAJOR 59
|
||||
#define LIBAVCODEC_VERSION_MINOR 7
|
||||
#define LIBAVCODEC_VERSION_MICRO 101
|
||||
#define LIBAVCODEC_VERSION_MICRO 102
|
||||
|
||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||
LIBAVCODEC_VERSION_MINOR, \
|
||||
|
@ -560,6 +560,7 @@ const AVCodecTag ff_codec_wav_tags[] = {
|
||||
{ AV_CODEC_ID_DVAUDIO, 0x0215 },
|
||||
{ AV_CODEC_ID_DVAUDIO, 0x0216 },
|
||||
{ AV_CODEC_ID_ATRAC3, 0x0270 },
|
||||
{ AV_CODEC_ID_MSNSIREN, 0x028E },
|
||||
{ AV_CODEC_ID_ADPCM_G722, 0x028F },
|
||||
{ AV_CODEC_ID_IMC, 0x0401 },
|
||||
{ AV_CODEC_ID_IAC, 0x0402 },
|
||||
|
Loading…
Reference in New Issue
Block a user