diff --git a/Changelog b/Changelog index 69ed8cccbb..e64dca688b 100644 --- a/Changelog +++ b/Changelog @@ -125,6 +125,7 @@ easier to use. The changes are: - pan audio filter - IFF Amiga Continuous Bitmap (ACBM) decoder - ass filter +- CRI ADX audio format demuxer version 0.8: diff --git a/doc/general.texi b/doc/general.texi index 1e8fc80e5e..15b9401a84 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -79,6 +79,8 @@ library: @item Brute Force & Ignorance @tab @tab X @tab Used in the game Flash Traffic: City of Angels. @item BWF @tab X @tab X +@item CRI ADX @tab @tab X + @tab Audio-only format used in console video games. @item Discworld II BMV @tab @tab X @item Interplay C93 @tab @tab X @tab Used in the game Cyberia from Interplay. diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 07f7739738..77662d8f0b 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -519,7 +519,7 @@ OBJS-$(CONFIG_PCM_U32LE_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_ZORK_DECODER) += pcm.o OBJS-$(CONFIG_ADPCM_4XM_DECODER) += adpcm.o adpcm_data.o -OBJS-$(CONFIG_ADPCM_ADX_DECODER) += adxdec.o +OBJS-$(CONFIG_ADPCM_ADX_DECODER) += adxdec.o adx.o OBJS-$(CONFIG_ADPCM_ADX_ENCODER) += adxenc.o OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o @@ -558,6 +558,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o # libavformat dependencies OBJS-$(CONFIG_ADTS_MUXER) += mpeg4audio.o +OBJS-$(CONFIG_ADX_DEMUXER) += adx.o OBJS-$(CONFIG_CAF_DEMUXER) += mpeg4audio.o mpegaudiodata.o OBJS-$(CONFIG_DV_DEMUXER) += dvdata.o OBJS-$(CONFIG_DV_MUXER) += dvdata.o timecode.o @@ -632,6 +633,7 @@ OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o \ aacadtsdec.o mpeg4audio.o OBJS-$(CONFIG_AC3_PARSER) += ac3_parser.o ac3tab.o \ aac_ac3_parser.o +OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o diff --git a/libavcodec/adx.c b/libavcodec/adx.c new file mode 100644 index 0000000000..aa90fd89c3 --- /dev/null +++ b/libavcodec/adx.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011 Justin Ruggles + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/intreadwrite.h" +#include "libavutil/mathematics.h" +#include "adx.h" + +void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff) +{ + double a, b, c; + + a = M_SQRT2 - cos(2.0 * M_PI * cutoff / sample_rate); + b = M_SQRT2 - 1.0; + c = (a - sqrt((a + b) * (a - b))) / b; + + coeff[0] = lrintf(c * 2.0 * (1 << bits)); + coeff[1] = lrintf(-(c * c) * (1 << bits)); +} + +int avpriv_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, + int bufsize, int *header_size, int *coeff) +{ + int offset, cutoff; + + if (bufsize < 24) + return AVERROR_INVALIDDATA; + + if (AV_RB16(buf) != 0x8000) + return AVERROR_INVALIDDATA; + offset = AV_RB16(buf + 2) + 4; + + /* if copyright string is within the provided data, validate it */ + if (bufsize >= offset && memcmp(buf + offset - 6, "(c)CRI", 6)) + return AVERROR_INVALIDDATA; + + /* check for encoding=3 block_size=18, sample_size=4 */ + if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) { + av_log_ask_for_sample(avctx, "unsupported ADX format\n"); + return AVERROR_PATCHWELCOME; + } + + /* channels */ + avctx->channels = buf[7]; + if (avctx->channels > 2) + return AVERROR_INVALIDDATA; + + /* sample rate */ + avctx->sample_rate = AV_RB32(buf + 8); + if (avctx->sample_rate < 1 || + avctx->sample_rate > INT_MAX / (avctx->channels * BLOCK_SIZE * 8)) + return AVERROR_INVALIDDATA; + + /* bit rate */ + avctx->bit_rate = avctx->sample_rate * avctx->channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES; + + /* LPC coefficients */ + if (coeff) { + cutoff = AV_RB16(buf + 16); + ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, coeff); + } + + *header_size = offset; + return 0; +} diff --git a/libavcodec/adx.h b/libavcodec/adx.h index 0fa1003ffc..572483d28f 100644 --- a/libavcodec/adx.h +++ b/libavcodec/adx.h @@ -31,19 +31,50 @@ #ifndef AVCODEC_ADX_H #define AVCODEC_ADX_H +#include + +#include "avcodec.h" + typedef struct { int s1,s2; -} PREV; +} ADXChannelState; typedef struct { - PREV prev[2]; + int channels; + ADXChannelState prev[2]; int header_parsed; - unsigned char dec_temp[18*2]; - int in_temp; + int eof; + int cutoff; + int coeff[2]; } ADXContext; -#define BASEVOL 0x4000 -#define SCALE1 0x7298 -#define SCALE2 0x3350 +#define COEFF_BITS 12 + +#define BLOCK_SIZE 18 +#define BLOCK_SAMPLES 32 + +/** + * Calculate LPC coefficients based on cutoff frequency and sample rate. + * + * @param cutoff cutoff frequency + * @param sample_rate sample rate + * @param bits number of bits used to quantize coefficients + * @param[out] coeff 2 quantized LPC coefficients + */ +void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff); + +/** + * Decode ADX stream header. + * Sets avctx->channels and avctx->sample_rate. + * + * @param avctx codec context + * @param buf header data + * @param bufsize data size, should be at least 24 bytes + * @param[out] header_size size of ADX header + * @param[out] coeff 2 LPC coefficients, can be NULL + * @return data offset or negative error code if header is invalid + */ +int avpriv_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, + int bufsize, int *header_size, int *coeff); #endif /* AVCODEC_ADX_H */ diff --git a/libavcodec/adx_parser.c b/libavcodec/adx_parser.c new file mode 100644 index 0000000000..ebcb1370e5 --- /dev/null +++ b/libavcodec/adx_parser.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011 Justin Ruggles + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * ADX audio parser + * + * Reads header to extradata and splits packets into individual blocks. + */ + +#include "libavutil/intreadwrite.h" +#include "parser.h" +#include "adx.h" + +typedef struct ADXParseContext { + ParseContext pc; + int header_size; + int block_size; + int buf_pos; +} ADXParseContext; + +#define MIN_HEADER_SIZE 24 + +static int adx_parse(AVCodecParserContext *s1, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + ADXParseContext *s = s1->priv_data; + ParseContext *pc = &s->pc; + int next = END_NOT_FOUND; + + if (!avctx->extradata_size) { + int ret; + + ff_combine_frame(pc, END_NOT_FOUND, &buf, &buf_size); + + if (!s->header_size && pc->index >= MIN_HEADER_SIZE) { + if (ret = avpriv_adx_decode_header(avctx, pc->buffer, pc->index, + &s->header_size, NULL)) + return AVERROR_INVALIDDATA; + s->block_size = BLOCK_SIZE * avctx->channels; + } + if (s->header_size && s->header_size <= pc->index) { + avctx->extradata = av_mallocz(s->header_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return AVERROR(ENOMEM); + avctx->extradata_size = s->header_size; + memcpy(avctx->extradata, pc->buffer, s->header_size); + memmove(pc->buffer, pc->buffer + s->header_size, s->header_size); + pc->index -= s->header_size; + } + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + + if (pc->index - s->buf_pos >= s->block_size) { + *poutbuf = &pc->buffer[s->buf_pos]; + *poutbuf_size = s->block_size; + s->buf_pos += s->block_size; + return 0; + } + if (pc->index && s->buf_pos) { + memmove(pc->buffer, &pc->buffer[s->buf_pos], pc->index - s->buf_pos); + pc->index -= s->buf_pos; + s->buf_pos = 0; + } + if (buf_size + pc->index >= s->block_size) + next = s->block_size - pc->index; + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +AVCodecParser ff_adx_parser = { + .codec_ids = { CODEC_ID_ADPCM_ADX }, + .priv_data_size = sizeof(ADXParseContext), + .parser_parse = adx_parse, + .parser_close = ff_parse_close, +}; diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index df3e8dd355..0fed1220ef 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -22,6 +22,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "adx.h" +#include "get_bits.h" /** * @file @@ -34,136 +35,105 @@ static av_cold int adx_decode_init(AVCodecContext *avctx) { + ADXContext *c = avctx->priv_data; + int ret, header_size; + + if (avctx->extradata_size < 24) + return AVERROR_INVALIDDATA; + + if ((ret = avpriv_adx_decode_header(avctx, avctx->extradata, + avctx->extradata_size, &header_size, + c->coeff)) < 0) { + av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n"); + return AVERROR_INVALIDDATA; + } + c->channels = avctx->channels; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; return 0; } -/* 18 bytes <-> 32 samples */ - -static void adx_decode(short *out,const unsigned char *in,PREV *prev) +/** + * Decode 32 samples from 18 bytes. + * + * A 16-bit scalar value is applied to 32 residuals, which then have a + * 2nd-order LPC filter applied to it to form the output signal for a single + * channel. + */ +static int adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) { + ADXChannelState *prev = &c->prev[ch]; + GetBitContext gb; int scale = AV_RB16(in); int i; - int s0,s1,s2,d; + int s0, s1, s2, d; -// printf("%x ",scale); + /* check if this is an EOF packet */ + if (scale & 0x8000) + return -1; - in+=2; + init_get_bits(&gb, in + 2, (BLOCK_SIZE - 2) * 8); s1 = prev->s1; s2 = prev->s2; - for(i=0;i<16;i++) { - d = in[i]; - // d>>=4; if (d&8) d-=16; - d = ((signed char)d >> 4); - s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; - s2 = s1; - s1 = av_clip_int16(s0); - *out++=s1; - - d = in[i]; - //d&=15; if (d&8) d-=16; - d = ((signed char)(d<<4) >> 4); - s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; + for (i = 0; i < BLOCK_SAMPLES; i++) { + d = get_sbits(&gb, 4); + s0 = ((d << COEFF_BITS) * scale + c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS; s2 = s1; s1 = av_clip_int16(s0); - *out++=s1; + *out = s1; + out += c->channels; } prev->s1 = s1; prev->s2 = s2; + return 0; } -static void adx_decode_stereo(short *out,const unsigned char *in,PREV *prev) -{ - short tmp[32*2]; - int i; - - adx_decode(tmp ,in ,prev); - adx_decode(tmp+32,in+18,prev+1); - for(i=0;i<32;i++) { - out[i*2] = tmp[i]; - out[i*2+1] = tmp[i+32]; - } -} - -/* return data offset or 0 */ -static int adx_decode_header(AVCodecContext *avctx,const unsigned char *buf,size_t bufsize) -{ - int offset; - - if (buf[0]!=0x80) return 0; - offset = (AV_RB32(buf)^0x80000000)+4; - if (bufsizechannels = buf[7]; - avctx->sample_rate = AV_RB32(buf+8); - avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; - - return offset; -} - -static int adx_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) +static int adx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, + AVPacket *avpkt) { - const uint8_t *buf0 = avpkt->data; - int buf_size = avpkt->size; - ADXContext *c = avctx->priv_data; - short *samples = data; - const uint8_t *buf = buf0; - int rest = buf_size; - - if (!c->header_parsed) { - int hdrsize = adx_decode_header(avctx,buf,rest); - if (hdrsize==0) return -1; - c->header_parsed = 1; - buf += hdrsize; - rest -= hdrsize; + int buf_size = avpkt->size; + ADXContext *c = avctx->priv_data; + int16_t *samples = data; + const uint8_t *buf = avpkt->data; + int num_blocks, ch; + + if (c->eof) { + *data_size = 0; + return buf_size; } /* 18 bytes of data are expanded into 32*2 bytes of audio, so guard against buffer overflows */ - if(rest/18 > *data_size/64) - rest = (*data_size/64) * 18; - - if (c->in_temp) { - int copysize = 18*avctx->channels - c->in_temp; - memcpy(c->dec_temp+c->in_temp,buf,copysize); - rest -= copysize; - buf += copysize; - if (avctx->channels==1) { - adx_decode(samples,c->dec_temp,c->prev); - samples += 32; - } else { - adx_decode_stereo(samples,c->dec_temp,c->prev); - samples += 32*2; - } + num_blocks = buf_size / (BLOCK_SIZE * c->channels); + if (num_blocks > *data_size / (BLOCK_SAMPLES * c->channels)) { + buf_size = (*data_size / (BLOCK_SAMPLES * c->channels)) * BLOCK_SIZE; + num_blocks = buf_size / (BLOCK_SIZE * c->channels); } - // - if (avctx->channels==1) { - while(rest>=18) { - adx_decode(samples,buf,c->prev); - rest-=18; - buf+=18; - samples+=32; - } - } else { - while(rest>=18*2) { - adx_decode_stereo(samples,buf,c->prev); - rest-=18*2; - buf+=18*2; - samples+=32*2; + if (!buf_size || buf_size % (BLOCK_SIZE * avctx->channels)) { + if (buf_size >= 4 && (AV_RB16(buf) & 0x8000)) { + c->eof = 1; + *data_size = 0; + return avpkt->size; } + return AVERROR_INVALIDDATA; } - // - c->in_temp = rest; - if (rest) { - memcpy(c->dec_temp,buf,rest); - buf+=rest; + + while (num_blocks--) { + for (ch = 0; ch < c->channels; ch++) { + if (adx_decode(c, samples + ch, buf, ch)) { + c->eof = 1; + buf = avpkt->data + avpkt->size; + break; + } + buf_size -= BLOCK_SIZE; + buf += BLOCK_SIZE; + } + samples += BLOCK_SAMPLES * c->channels; } + *data_size = (uint8_t*)samples - (uint8_t*)data; -// printf("%d:%d ",buf-buf0,*data_size); fflush(stdout); - return buf-buf0; + return buf - avpkt->data; } AVCodec ff_adpcm_adx_decoder = { @@ -173,6 +143,5 @@ AVCodec ff_adpcm_adx_decoder = { .priv_data_size = sizeof(ADXContext), .init = adx_decode_init, .decode = adx_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), + .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), }; - diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c index 893afe0981..51545fa06c 100644 --- a/libavcodec/adxenc.c +++ b/libavcodec/adxenc.c @@ -22,6 +22,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "adx.h" +#include "put_bits.h" /** * @file @@ -34,8 +35,10 @@ /* 18 bytes <-> 32 samples */ -static void adx_encode(unsigned char *adx,const short *wav,PREV *prev) +static void adx_encode(ADXContext *c, unsigned char *adx, const short *wav, + ADXChannelState *prev) { + PutBitContext pb; int scale; int i; int s0,s1,s2,d; @@ -47,7 +50,7 @@ static void adx_encode(unsigned char *adx,const short *wav,PREV *prev) s2 = prev->s2; for(i=0;i<32;i++) { s0 = wav[i]; - d = ((s0<<14) - SCALE1*s1 + SCALE2*s2)/BASEVOL; + d = ((s0 << COEFF_BITS) - c->coeff[0] * s1 - c->coeff[1] * s2) >> COEFF_BITS; data[i]=d; if (maxd) min=d; @@ -71,9 +74,10 @@ static void adx_encode(unsigned char *adx,const short *wav,PREV *prev) AV_WB16(adx, scale); - for(i=0;i<16;i++) { - adx[i+2] = ((data[i*2]/scale)<<4) | ((data[i*2+1]/scale)&0xf); - } + init_put_bits(&pb, adx + 2, 16); + for (i = 0; i < 32; i++) + put_sbits(&pb, 4, av_clip(data[i]/scale, -8, 7)); + flush_put_bits(&pb); } static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t bufsize) @@ -101,19 +105,24 @@ static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t buf } adxhdr; /* big endian */ /* offset-6 "(c)CRI" */ #endif + ADXContext *c = avctx->priv_data; + AV_WB32(buf+0x00,0x80000000|0x20); AV_WB32(buf+0x04,0x03120400|avctx->channels); AV_WB32(buf+0x08,avctx->sample_rate); AV_WB32(buf+0x0c,0); /* FIXME: set after */ - AV_WB32(buf+0x10,0x01040300); - AV_WB32(buf+0x14,0x00000000); - AV_WB32(buf+0x18,0x00000000); - memcpy(buf+0x1c,"\0\0(c)CRI",8); + AV_WB16(buf + 0x10, c->cutoff); + AV_WB32(buf + 0x12, 0x03000000); + AV_WB32(buf + 0x16, 0x00000000); + AV_WB32(buf + 0x1a, 0x00000000); + memcpy (buf + 0x1e, "(c)CRI", 6); return 0x20+4; } static av_cold int adx_encode_init(AVCodecContext *avctx) { + ADXContext *c = avctx->priv_data; + if (avctx->channels > 2) return -1; /* only stereo or mono =) */ avctx->frame_size = 32; @@ -123,6 +132,10 @@ static av_cold int adx_encode_init(AVCodecContext *avctx) // avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; + /* the cutoff can be adjusted, but this seems to work pretty well */ + c->cutoff = 500; + ff_adx_calculate_coeffs(c->cutoff, avctx->sample_rate, COEFF_BITS, c->coeff); + av_log(avctx, AV_LOG_DEBUG, "adx encode init\n"); return 0; @@ -158,7 +171,7 @@ static int adx_encode_frame(AVCodecContext *avctx, if (avctx->channels==1) { while(rest>=32) { - adx_encode(dst,samples,c->prev); + adx_encode(c, dst, samples, c->prev); dst+=18; samples+=32; rest-=32; @@ -173,8 +186,8 @@ static int adx_encode_frame(AVCodecContext *avctx, tmpbuf[i+32] = samples[i*2+1]; } - adx_encode(dst,tmpbuf,c->prev); - adx_encode(dst+18,tmpbuf+32,c->prev+1); + adx_encode(c, dst, tmpbuf, c->prev); + adx_encode(c, dst + 18, tmpbuf + 32, c->prev + 1); dst+=18*2; samples+=32*2; rest-=32*2; diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 88fad5e936..dc78333a57 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -414,6 +414,7 @@ void avcodec_register_all(void) REGISTER_PARSER (AAC, aac); REGISTER_PARSER (AAC_LATM, aac_latm); REGISTER_PARSER (AC3, ac3); + REGISTER_PARSER (ADX, adx); REGISTER_PARSER (CAVSVIDEO, cavsvideo); REGISTER_PARSER (DCA, dca); REGISTER_PARSER (DIRAC, dirac); diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 9285472245..10f75212ff 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -690,7 +690,7 @@ static void do_apply_filter(APEContext *ctx, int version, APEFilter *f, /* Update the adaption coefficients */ absres = FFABS(res); if (absres) - *f->adaptcoeffs = ((res & (1<<31)) - (1<<30)) >> + *f->adaptcoeffs = ((res & (-1<<31)) ^ (-1<<30)) >> (25 + (absres <= f->avg*3) + (absres <= f->avg*4/3)); else *f->adaptcoeffs = 0; diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 2fb200f047..c9165ad25e 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1259,7 +1259,7 @@ struct AVCodecInternal; typedef struct AVCodecContext { /** * information on struct for av_log - * - set by avcodec_alloc_context + * - set by avcodec_alloc_context3 */ const AVClass *av_class; /** @@ -2959,8 +2959,8 @@ typedef struct AVCodecContext { * For SUBTITLE_ASS subtitle type, it should contain the whole ASS * [Script Info] and [V4+ Styles] section, plus the [Events] line and * the Format line following. It shouldn't include any Dialogue line. - * - encoding: Set/allocated/freed by user (before avcodec_open()) - * - decoding: Set/allocated/freed by libavcodec (by avcodec_open()) + * - encoding: Set/allocated/freed by user (before avcodec_open2()) + * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2()) */ uint8_t *subtitle_header; int subtitle_header_size; @@ -3853,7 +3853,7 @@ AVCodecContext *avcodec_alloc_context2(enum AVMediaType); * resulting struct can be deallocated by simply calling av_free(). * * @param codec if non-NULL, allocate private data and initialize defaults - * for the given codec. It is illegal to then call avcodec_open() + * for the given codec. It is illegal to then call avcodec_open2() * with a different codec. * * @return An AVCodecContext filled with default values or NULL on failure. @@ -3864,7 +3864,7 @@ AVCodecContext *avcodec_alloc_context3(AVCodec *codec); /** * Copy the settings of the source AVCodecContext into the destination * AVCodecContext. The resulting destination codec context will be - * unopened, i.e. you are required to call avcodec_open() before you + * unopened, i.e. you are required to call avcodec_open2() before you * can use this AVCodecContext to decode/encode video/audio data. * * @param dest target codec context, should be initialized with @@ -3928,7 +3928,7 @@ enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum #if FF_API_THREAD_INIT /** - * @deprecated Set s->thread_count before calling avcodec_open() instead of calling this. + * @deprecated Set s->thread_count before calling avcodec_open2() instead of calling this. */ attribute_deprecated int avcodec_thread_init(AVCodecContext *s, int thread_count); @@ -3974,7 +3974,7 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec); /** * Initialize the AVCodecContext to use the given AVCodec. Prior to using this - * function the context has to be allocated with avcodec_alloc_context(). + * function the context has to be allocated with avcodec_alloc_context3(). * * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for @@ -3989,9 +3989,9 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec); * if (!codec) * exit(1); * - * context = avcodec_alloc_context(); + * context = avcodec_alloc_context3(codec); * - * if (avcodec_open(context, codec, opts) < 0) + * if (avcodec_open2(context, codec, opts) < 0) * exit(1); * @endcode * diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 4c750134d0..6a076d9310 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -273,6 +273,10 @@ static av_cold void init_cplscales_table (COOKContext *q) { */ static inline int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){ + static const uint32_t tab[4] = { + AV_BE2NE32C(0x37c511f2), AV_BE2NE32C(0xf237c511), + AV_BE2NE32C(0x11f237c5), AV_BE2NE32C(0xc511f237), + }; int i, off; uint32_t c; const uint32_t* buf; @@ -285,7 +289,7 @@ static inline int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes) off = (intptr_t)inbuffer & 3; buf = (const uint32_t*) (inbuffer - off); - c = av_be2ne32((0x37c511f2 >> (off*8)) | (0x37c511f2 << (32-(off*8)))); + c = tab[off]; bytes += 3 + off; for (i = 0; i < bytes/4; i++) obuf[i] = c ^ buf[i]; @@ -1075,7 +1079,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->subpacket[s].subbands = bytestream_get_be16(&edata_ptr); extradata_size -= 8; } - if (extradata_size >= 8){ + if (extradata_size >= 8) { bytestream_get_be32(&edata_ptr); //Unknown unused q->subpacket[s].js_subband_start = bytestream_get_be16(&edata_ptr); q->subpacket[s].js_vlc_bits = bytestream_get_be16(&edata_ptr); diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index e1f99706f7..7021a70650 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -680,7 +680,8 @@ static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx) int qscale = 1; int mb = y*ctx->m.mb_width+x; for (q = 1; q < avctx->qmax; q++) { - unsigned score = ctx->mb_rc[q][mb].bits*lambda+(ctx->mb_rc[q][mb].ssd<mb_rc[q][mb].bits*lambda+ + ((unsigned)ctx->mb_rc[q][mb].ssd<>1; else lambda -= down_step; - down_step *= 5; // XXX tune ? + down_step = FFMIN((int64_t)down_step*5, INT_MAX); up_step = 1< 0) { - re_cache = ((unsigned)re_cache >> partial_bit_count) | - (mb->partial_bit_buffer << (sizeof(re_cache) * 8 - partial_bit_count)); + re_cache = re_cache >> partial_bit_count | mb->partial_bit_buffer; re_index -= partial_bit_count; mb->partial_bit_count = 0; } @@ -416,7 +415,7 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) if (re_index + vlc_len > last_index) { /* should be < 16 bits otherwise a codeword could have been parsed */ mb->partial_bit_count = last_index - re_index; - mb->partial_bit_buffer = NEG_USR32(re_cache, mb->partial_bit_count); + mb->partial_bit_buffer = re_cache & ~(-1u >> mb->partial_bit_count); re_index = last_index; break; } diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index bcce97cb75..de98da72ea 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -112,9 +112,9 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, */ if(j) dst[i] += dst[i - stride]; else if(Uoff) dst[i] += 0x80; - if(get_bits_left(&gb) < 0){ + if (get_bits_left(&gb) < 0) { free_vlc(&vlc); - return -1; + return AVERROR_INVALIDDATA; } } dst += stride; diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c index 7a22fa702f..83cb36831b 100644 --- a/libavcodec/gifdec.c +++ b/libavcodec/gifdec.c @@ -96,11 +96,11 @@ static int gif_read_image(GifState *s) n = (1 << bits_per_pixel); spal = palette; for(i = 0; i < n; i++) { - s->image_palette[i] = (0xff << 24) | AV_RB24(spal); + s->image_palette[i] = (0xffu << 24) | AV_RB24(spal); spal += 3; } for(; i < 256; i++) - s->image_palette[i] = (0xff << 24); + s->image_palette[i] = (0xffu << 24); /* handle transparency */ if (s->transparent_color_index >= 0) s->image_palette[s->transparent_color_index] = 0; diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c index b10b8db248..7f8dc7501b 100644 --- a/libavcodec/nuv.c +++ b/libavcodec/nuv.c @@ -193,7 +193,7 @@ retry: int w, h, q, res; if (buf[0] != 'V' || buf_size < 12) { av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame (wrong codec_tag?)\n"); - return -1; + return AVERROR_INVALIDDATA; } w = AV_RL16(&buf[6]); h = AV_RL16(&buf[8]); diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index e3815ba6d3..75168e4598 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -658,7 +658,7 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count) pthread_cond_signal(&p->input_cond); pthread_mutex_unlock(&p->mutex); - if(p->thread) + if (p->thread) pthread_join(p->thread, NULL); if (codec->close) diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c index bf3e5db062..c7a04c0520 100644 --- a/libavcodec/qtrle.c +++ b/libavcodec/qtrle.c @@ -332,7 +332,6 @@ static void qtrle_decode_32bpp(QtrleContext *s, int stream_ptr, int row_ptr, int int rle_code; int pixel_ptr; int row_inc = s->frame.linesize[0]; - unsigned char a, r, g, b; unsigned int argb; unsigned char *rgb = s->frame.data[0]; int pixel_limit = s->frame.linesize[0] * s->avctx->height; @@ -352,16 +351,13 @@ static void qtrle_decode_32bpp(QtrleContext *s, int stream_ptr, int row_ptr, int /* decode the run length code */ rle_code = -rle_code; CHECK_STREAM_PTR(4); - a = s->buf[stream_ptr++]; - r = s->buf[stream_ptr++]; - g = s->buf[stream_ptr++]; - b = s->buf[stream_ptr++]; - argb = (a << 24) | (r << 16) | (g << 8) | (b << 0); + argb = AV_RB32(s->buf + stream_ptr); + stream_ptr += 4; CHECK_PIXEL_PTR(rle_code * 4); while (rle_code--) { - *(unsigned int *)(&rgb[pixel_ptr]) = argb; + AV_WN32A(rgb + pixel_ptr, argb); pixel_ptr += 4; } } else { @@ -370,13 +366,10 @@ static void qtrle_decode_32bpp(QtrleContext *s, int stream_ptr, int row_ptr, int /* copy pixels directly to output */ while (rle_code--) { - a = s->buf[stream_ptr++]; - r = s->buf[stream_ptr++]; - g = s->buf[stream_ptr++]; - b = s->buf[stream_ptr++]; - argb = (a << 24) | (r << 16) | (g << 8) | (b << 0); - *(unsigned int *)(&rgb[pixel_ptr]) = argb; - pixel_ptr += 4; + argb = AV_RB32(s->buf + stream_ptr); + AV_WN32A(rgb + pixel_ptr, argb); + stream_ptr += 4; + pixel_ptr += 4; } } } diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index 7df6a61eb9..2e2de85044 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -933,7 +933,7 @@ static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int if(itype == VERT_LEFT_PRED) itype = VERT_LEFT_PRED_RV40_NODOWN; } if(!right && up){ - topleft = dst[-stride + 3] * 0x01010101; + topleft = dst[-stride + 3] * 0x01010101u; prev = (uint8_t*)&topleft; } r->h.pred4x4[itype](dst, prev, stride); diff --git a/libavcodec/s3tc.c b/libavcodec/s3tc.c index 546ee2156f..8e979a84ac 100644 --- a/libavcodec/s3tc.c +++ b/libavcodec/s3tc.c @@ -28,7 +28,7 @@ static inline void dxt1_decode_pixels(const uint8_t *s, uint32_t *d, unsigned int qstride, unsigned int flag, uint64_t alpha) { - unsigned int x, y, c0, c1, a = (!flag * 255) << 24; + unsigned int x, y, c0, c1, a = (!flag * 255u) << 24; unsigned int rb0, rb1, rb2, rb3, g0, g1, g2, g3; uint32_t colors[4], pixels; diff --git a/libavcodec/snow.c b/libavcodec/snow.c index 87b3a8f402..0ce9b28479 100644 --- a/libavcodec/snow.c +++ b/libavcodec/snow.c @@ -290,8 +290,8 @@ static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){ if(block->type & BLOCK_INTRA){ int x, y; - const int color = block->color[plane_index]; - const int color4= color*0x01010101; + const unsigned color = block->color[plane_index]; + const unsigned color4 = color*0x01010101; if(b_w==32){ for(y=0; y < b_h; y++){ *(uint32_t*)&dst[0 + y*stride]= color4; diff --git a/libavcodec/snow.h b/libavcodec/snow.h index b1589ca52e..3a5cdc7175 100644 --- a/libavcodec/snow.h +++ b/libavcodec/snow.h @@ -154,8 +154,8 @@ typedef struct SnowContext{ Plane plane[MAX_PLANES]; BlockNode *block; #define ME_CACHE_SIZE 1024 - int me_cache[ME_CACHE_SIZE]; - int me_cache_generation; + unsigned me_cache[ME_CACHE_SIZE]; + unsigned me_cache_generation; slice_buffer sb; int memc_only; diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index 6f00941389..ab31533f6d 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -958,7 +958,8 @@ static av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int const int b_stride= s->b_width << s->block_max_depth; BlockNode *block= &s->block[mb_x + mb_y * b_stride]; BlockNode backup= *block; - int rd, index, value; + unsigned value; + int rd, index; assert(mb_x>=0 && mb_y>=0); assert(mb_xb_width << s->block_max_depth; BlockNode *block= &s->block[mb_x + mb_y * b_stride]; BlockNode backup[4]= {block[0], block[1], block[b_stride], block[b_stride+1]}; - int rd, index, value; + unsigned value; + int rd, index; assert(mb_x>=0 && mb_y>=0); assert(mb_xy = ((diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y)) << 26) >> 26; + mv->y = sign_extend(diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y), 6); else - mv->x = ((diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x)) << 26) >> 26; + mv->x = sign_extend(diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x), 6); } return 0; diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index d9af5d80cc..9e6111a3c9 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -113,10 +113,6 @@ static void svq1_write_header(SVQ1Context *s, int frame_type) #define QUALITY_THRESHOLD 100 #define THRESHOLD_MULTIPLIER 0.6 -#if HAVE_ALTIVEC -#undef vector -#endif - static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *decoded, int stride, int level, int threshold, int lambda, int intra){ int count, y, x, i, j, split, best_mean, best_score, best_count; int best_vector[6]; @@ -160,7 +156,7 @@ static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *dec } best_count=0; - best_score -= ((block_sum[0]*block_sum[0])>>(level+3)); + best_score -= (int)(((unsigned)block_sum[0]*block_sum[0])>>(level+3)); best_mean= (block_sum[0] + (size>>1)) >> (level+3); if(level<4){ diff --git a/libavcodec/version.h b/libavcodec/version.h index 98eb48086c..31145db362 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -21,7 +21,7 @@ #define AVCODEC_VERSION_H #define LIBAVCODEC_VERSION_MAJOR 53 -#define LIBAVCODEC_VERSION_MINOR 37 +#define LIBAVCODEC_VERSION_MINOR 38 #define LIBAVCODEC_VERSION_MICRO 1 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavformat/Makefile b/libavformat/Makefile index b597a65fd2..3581a3d2d5 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -25,6 +25,7 @@ OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o OBJS-$(CONFIG_AC3_MUXER) += rawenc.o OBJS-$(CONFIG_ACT_DEMUXER) += act.o OBJS-$(CONFIG_ADF_DEMUXER) += bintext.o sauce.o +OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o pcm.o isom.o diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c new file mode 100644 index 0000000000..eff26982ea --- /dev/null +++ b/libavformat/adxdec.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 Justin Ruggles + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * CRI ADX demuxer + */ + +#include "libavutil/intreadwrite.h" +#include "libavcodec/adx.h" +#include "avformat.h" + +#define BLOCK_SIZE 18 +#define BLOCK_SAMPLES 32 + +typedef struct ADXDemuxerContext { + int header_size; +} ADXDemuxerContext; + +static int adx_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + ADXDemuxerContext *c = s->priv_data; + AVCodecContext *avctx = s->streams[0]->codec; + int ret, size; + + size = BLOCK_SIZE * avctx->channels; + + pkt->pos = avio_tell(s->pb); + pkt->stream_index = 0; + + ret = av_get_packet(s->pb, pkt, size); + if (ret != size) { + av_free_packet(pkt); + return ret < 0 ? ret : AVERROR(EIO); + } + if (AV_RB16(pkt->data) & 0x8000) { + av_free_packet(pkt); + return AVERROR_EOF; + } + pkt->size = size; + pkt->duration = 1; + pkt->pts = (pkt->pos - c->header_size) / size; + + return 0; +} + +static int adx_read_header(AVFormatContext *s, AVFormatParameters *ap) +{ + ADXDemuxerContext *c = s->priv_data; + AVCodecContext *avctx; + int ret; + + AVStream *st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + avctx = s->streams[0]->codec; + + if (avio_rb16(s->pb) != 0x8000) + return AVERROR_INVALIDDATA; + c->header_size = avio_rb16(s->pb) + 4; + avio_seek(s->pb, -4, SEEK_CUR); + + avctx->extradata = av_mallocz(c->header_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return AVERROR(ENOMEM); + if (avio_read(s->pb, avctx->extradata, c->header_size) < c->header_size) { + av_freep(&avctx->extradata); + return AVERROR(EIO); + } + avctx->extradata_size = c->header_size; + + ret = avpriv_adx_decode_header(avctx, avctx->extradata, + avctx->extradata_size, &c->header_size, + NULL); + if (ret) + return ret; + + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->codec->codec_id = s->iformat->value; + + av_set_pts_info(st, 64, BLOCK_SAMPLES, avctx->sample_rate); + + return 0; +} + +AVInputFormat ff_adx_demuxer = { + .name = "adx", + .long_name = NULL_IF_CONFIG_SMALL("CRI ADX"), + .priv_data_size = sizeof(ADXDemuxerContext), + .read_header = adx_read_header, + .read_packet = adx_read_packet, + .extensions = "adx", + .value = CODEC_ID_ADPCM_ADX, +}; diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 31fa5060f7..9ba459dd92 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -54,6 +54,7 @@ void av_register_all(void) REGISTER_DEMUXER (ACT, act); REGISTER_DEMUXER (ADF, adf); REGISTER_MUXER (ADTS, adts); + REGISTER_DEMUXER (ADX, adx); REGISTER_DEMUXER (AEA, aea); REGISTER_MUXDEMUX (AIFF, aiff); REGISTER_MUXDEMUX (AMR, amr); diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index 0199ee1f5f..8a49bef1dc 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -172,6 +172,7 @@ static int film_read_header(AVFormatContext *s, if (film->audio_type == CODEC_ID_ADPCM_ADX) { st->codec->bits_per_coded_sample = 18 * 8 / 32; st->codec->block_align = st->codec->channels * 18; + st->need_parsing = AVSTREAM_PARSE_FULL; } else { st->codec->bits_per_coded_sample = film->audio_bits; st->codec->block_align = st->codec->channels * diff --git a/libavformat/sol.c b/libavformat/sol.c index cd5b2d75a4..7faa4e78b8 100644 --- a/libavformat/sol.c +++ b/libavformat/sol.c @@ -23,7 +23,7 @@ * Based on documents from Game Audio Player and own research */ -#include "libavutil/bswap.h" +#include "libavutil/intreadwrite.h" #include "avformat.h" #include "pcm.h" @@ -33,8 +33,7 @@ static int sol_probe(AVProbeData *p) { /* check file header */ - uint16_t magic; - magic=av_le2ne16(*((uint16_t*)p->buf)); + uint16_t magic = AV_RL32(p->buf); if ((magic == 0x0B8D || magic == 0x0C0D || magic == 0x0C8D) && p->buf[2] == 'S' && p->buf[3] == 'O' && p->buf[4] == 'L' && p->buf[5] == 0) diff --git a/libavformat/version.h b/libavformat/version.h index 5c7ed6863e..c98ff60399 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -24,7 +24,7 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 53 -#define LIBAVFORMAT_VERSION_MINOR 21 +#define LIBAVFORMAT_VERSION_MINOR 22 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 09e2edb933..71033d3df8 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -607,7 +607,7 @@ yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter, const uint8_t * const d128=dither_8x8_220[y&7]; uint8_t *g = c->table_gU[128] + c->table_gV[128]; int i; - int acc = 0; + unsigned acc = 0; for (i = 0; i < dstW - 1; i += 2) { int j;