diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-02-01 02:08:23 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-02-01 02:36:09 +0100 |
commit | a369a6b85819890b21a87af3ce983ce533b7169b (patch) | |
tree | 838f9821dc09bd99b59ce4a2d8123d5fd6868b91 /libavcodec | |
parent | 0a3a69e8d77146b53a1112c715a78e7d293883b1 (diff) | |
parent | 52afc9716849e6fb6c2420674d790d374061c663 (diff) | |
download | ffmpeg-a369a6b85819890b21a87af3ce983ce533b7169b.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master: (29 commits)
fate: add golomb-test
golomb-test: K&R formatting cosmetics
h264: Split h264-test off into a separate file - golomb-test.c.
h264-test: cleanup: drop timer invocations, commented out code and other cruft
h264-test: Remove unused DSP and AVCodec contexts and related init calls.
adpcm: Add missing stdint.h #include to fix standalone header compilation.
lavf: add functions for accessing the fourcc<->CodecID mapping tables.
lavc: set AVCodecContext.codec in avcodec_get_context_defaults3().
lavc: make avcodec_close() work properly on unopened codecs.
lavc: add avcodec_is_open().
lavf: rename AVInputFormat.value to raw_codec_id.
lavf: remove the pointless value field from flv and iv8
lavc/lavf: remove unnecessary symbols from the symbol version script.
lavc: reorder AVCodec fields.
lavf: reorder AVInput/OutputFormat fields.
mp3dec: Fix a heap-buffer-overflow
adpcmenc: remove some unneeded casts
adpcmenc: use int16_t and uint8_t instead of short and unsigned char.
adpcmenc: fix adpcm_ms extradata allocation
adpcmenc: return proper AVERROR codes instead of -1
...
Conflicts:
doc/APIchanges
libavcodec/Makefile
libavcodec/adpcmenc.c
libavcodec/avcodec.h
libavcodec/h264.c
libavcodec/libavcodec.v
libavcodec/mpc7.c
libavcodec/mpegaudiodec.c
libavcodec/options.c
libavformat/Makefile
libavformat/avformat.h
libavformat/flvdec.c
libavformat/libavformat.v
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/Makefile | 2 | ||||
-rw-r--r-- | libavcodec/adpcm.h | 8 | ||||
-rw-r--r-- | libavcodec/adpcmenc.c | 75 | ||||
-rw-r--r-- | libavcodec/avcodec.h | 62 | ||||
-rw-r--r-- | libavcodec/golomb-test.c | 70 | ||||
-rw-r--r-- | libavcodec/h264.c | 71 | ||||
-rw-r--r-- | libavcodec/mpegaudiodec.c | 7 | ||||
-rw-r--r-- | libavcodec/options.c | 2 | ||||
-rw-r--r-- | libavcodec/utils.c | 44 | ||||
-rw-r--r-- | libavcodec/wmalosslessdec.c | 17 | ||||
-rw-r--r-- | libavcodec/x86/Makefile | 3 | ||||
-rw-r--r-- | libavcodec/x86/fmtconvert_mmx.c | 2 | ||||
-rw-r--r-- | libavcodec/x86/rv40dsp.asm | 207 | ||||
-rw-r--r-- | libavcodec/x86/rv40dsp_init.c (renamed from libavcodec/x86/rv40dsp.c) | 23 |
14 files changed, 436 insertions, 157 deletions
diff --git a/libavcodec/Makefile b/libavcodec/Makefile index b8128efd4e..2173855e5b 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -737,7 +737,7 @@ SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h SKIPHEADERS-$(HAVE_W32THREADS) += w32pthreads.h -TESTPROGS = cabac dct fft fft-fixed h264 iirfilter rangecoder snowenc +TESTPROGS = cabac dct fft fft-fixed golomb iirfilter rangecoder snowenc TESTPROGS-$(HAVE_MMX) += motion TESTOBJS = dctref.o diff --git a/libavcodec/adpcm.h b/libavcodec/adpcm.h index 475719adf5..08fd23f87b 100644 --- a/libavcodec/adpcm.h +++ b/libavcodec/adpcm.h @@ -26,18 +26,20 @@ #ifndef AVCODEC_ADPCM_H #define AVCODEC_ADPCM_H +#include <stdint.h> + #define BLKSIZE 1024 typedef struct ADPCMChannelStatus { int predictor; - short int step_index; + int16_t step_index; int step; /* for encoding */ int prev_sample; /* MS version */ - short sample1; - short sample2; + int16_t sample1; + int16_t sample2; int coeff1; int coeff2; int idelta; diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index d40b8a78d9..de85054288 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -65,12 +65,16 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) ADPCMEncodeContext *s = avctx->priv_data; uint8_t *extradata; int i; - if (avctx->channels > 2) - return -1; /* only stereo or mono =) */ + int ret = AVERROR(ENOMEM); + + if (avctx->channels > 2) { + av_log(avctx, AV_LOG_ERROR, "only stereo or mono is supported\n"); + return AVERROR(EINVAL); + } if (avctx->trellis && (unsigned)avctx->trellis > 16U) { av_log(avctx, AV_LOG_ERROR, "invalid trellis size\n"); - return -1; + return AVERROR(EINVAL); } if (avctx->trellis) { @@ -107,12 +111,12 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) /* each 16 bits sample gives one nibble and we have 7 bytes per channel overhead */ avctx->frame_size = (BLKSIZE - 7 * avctx->channels) * 2 / avctx->channels + 2; - avctx->block_align = BLKSIZE; avctx->bits_per_coded_sample = 4; + avctx->block_align = BLKSIZE; + if (!(avctx->extradata = av_malloc(32 + FF_INPUT_BUFFER_PADDING_SIZE))) + goto error; avctx->extradata_size = 32; - extradata = avctx->extradata = av_malloc(avctx->extradata_size); - if (!extradata) - return AVERROR(ENOMEM); + extradata = avctx->extradata; bytestream_put_le16(&extradata, avctx->frame_size); bytestream_put_le16(&extradata, 7); /* wNumCoef */ for (i = 0; i < 7; i++) { @@ -130,22 +134,23 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) avctx->sample_rate != 44100) { av_log(avctx, AV_LOG_ERROR, "Sample rate must be 11025, " "22050 or 44100\n"); + ret = AVERROR(EINVAL); goto error; } avctx->frame_size = 512 * (avctx->sample_rate / 11025); break; default: + ret = AVERROR(EINVAL); goto error; } - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) + if (!(avctx->coded_frame = avcodec_alloc_frame())) goto error; return 0; error: adpcm_encode_close(avctx); - return -1; + return ret; } static av_cold int adpcm_encode_close(AVCodecContext *avctx) @@ -161,8 +166,8 @@ static av_cold int adpcm_encode_close(AVCodecContext *avctx) } -static inline unsigned char adpcm_ima_compress_sample(ADPCMChannelStatus *c, - short sample) +static inline uint8_t adpcm_ima_compress_sample(ADPCMChannelStatus *c, + int16_t sample) { int delta = sample - c->prev_sample; int nibble = FFMIN(7, abs(delta) * 4 / @@ -174,8 +179,8 @@ static inline unsigned char adpcm_ima_compress_sample(ADPCMChannelStatus *c, return nibble; } -static inline unsigned char adpcm_ima_qt_compress_sample(ADPCMChannelStatus *c, - short sample) +static inline uint8_t adpcm_ima_qt_compress_sample(ADPCMChannelStatus *c, + int16_t sample) { int delta = sample - c->prev_sample; int diff, step = ff_adpcm_step_table[c->step_index]; @@ -211,8 +216,8 @@ static inline unsigned char adpcm_ima_qt_compress_sample(ADPCMChannelStatus *c, return nibble; } -static inline unsigned char adpcm_ms_compress_sample(ADPCMChannelStatus *c, - short sample) +static inline uint8_t adpcm_ms_compress_sample(ADPCMChannelStatus *c, + int16_t sample) { int predictor, nibble, bias; @@ -228,20 +233,20 @@ static inline unsigned char adpcm_ms_compress_sample(ADPCMChannelStatus *c, nibble = (nibble + bias) / c->idelta; nibble = av_clip(nibble, -8, 7) & 0x0F; - predictor += (signed)((nibble & 0x08) ? (nibble - 0x10) : nibble) * c->idelta; + predictor += ((nibble & 0x08) ? (nibble - 0x10) : nibble) * c->idelta; c->sample2 = c->sample1; c->sample1 = av_clip_int16(predictor); - c->idelta = (ff_adpcm_AdaptationTable[(int)nibble] * c->idelta) >> 8; + c->idelta = (ff_adpcm_AdaptationTable[nibble] * c->idelta) >> 8; if (c->idelta < 16) c->idelta = 16; return nibble; } -static inline unsigned char adpcm_yamaha_compress_sample(ADPCMChannelStatus *c, - short sample) +static inline uint8_t adpcm_yamaha_compress_sample(ADPCMChannelStatus *c, + int16_t sample) { int nibble, delta; @@ -262,8 +267,9 @@ static inline unsigned char adpcm_yamaha_compress_sample(ADPCMChannelStatus *c, return nibble; } -static void adpcm_compress_trellis(AVCodecContext *avctx, const short *samples, - uint8_t *dst, ADPCMChannelStatus *c, int n) +static void adpcm_compress_trellis(AVCodecContext *avctx, + const int16_t *samples, uint8_t *dst, + ADPCMChannelStatus *c, int n) { //FIXME 6% faster if frontier is a compile-time constant ADPCMEncodeContext *s = avctx->priv_data; @@ -467,35 +473,35 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, const short *samples, c->idelta = nodes[0]->step; } -static int adpcm_encode_frame(AVCodecContext *avctx, - unsigned char *frame, int buf_size, void *data) +static int adpcm_encode_frame(AVCodecContext *avctx, uint8_t *frame, + int buf_size, void *data) { int n, i, st; - short *samples; - unsigned char *dst; + int16_t *samples; + uint8_t *dst; ADPCMEncodeContext *c = avctx->priv_data; uint8_t *buf; dst = frame; - samples = (short *)data; + samples = data; st = avctx->channels == 2; /* n = (BLKSIZE - 4 * avctx->channels) / (2 * 8 * avctx->channels); */ switch(avctx->codec->id) { case CODEC_ID_ADPCM_IMA_WAV: n = avctx->frame_size / 8; - c->status[0].prev_sample = (signed short)samples[0]; /* XXX */ + c->status[0].prev_sample = samples[0]; /* c->status[0].step_index = 0; XXX: not sure how to init the state machine */ bytestream_put_le16(&dst, c->status[0].prev_sample); - *dst++ = (unsigned char)c->status[0].step_index; + *dst++ = c->status[0].step_index; *dst++ = 0; /* unknown */ samples++; if (avctx->channels == 2) { - c->status[1].prev_sample = (signed short)samples[0]; + c->status[1].prev_sample = samples[0]; /* c->status[1].step_index = 0; */ bytestream_put_le16(&dst, c->status[1].prev_sample); - *dst++ = (unsigned char)c->status[1].step_index; + *dst++ = c->status[1].step_index; *dst++ = 0; samples++; } @@ -595,7 +601,7 @@ static int adpcm_encode_frame(AVCodecContext *avctx, c->status[i].step_index = av_clip(c->status[i].step_index, 0, 63); put_sbits(&pb, 16, samples[i]); put_bits(&pb, 6, c->status[i].step_index); - c->status[i].prev_sample = (signed short)samples[i]; + c->status[i].prev_sample = samples[i]; } if (avctx->trellis > 0) { @@ -692,10 +698,11 @@ static int adpcm_encode_frame(AVCodecContext *avctx, } break; default: - error: - return -1; + return AVERROR(EINVAL); } return dst - frame; +error: + return AVERROR(ENOMEM); } diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 4c5800b432..43c2128042 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2848,31 +2848,20 @@ typedef struct AVCodec { * This is the primary way to find a codec from the user perspective. */ const char *name; + /** + * Descriptive name for the codec, meant to be more human readable than name. + * You should use the NULL_IF_CONFIG_SMALL() macro to define it. + */ + const char *long_name; enum AVMediaType type; enum CodecID id; - int priv_data_size; - int (*init)(AVCodecContext *); - int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data); - int (*close)(AVCodecContext *); - int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt); /** * Codec capabilities. * see CODEC_CAP_* */ int capabilities; - struct AVCodec *next; - /** - * Flush buffers. - * Will be called when seeking - */ - void (*flush)(AVCodecContext *); const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0} const enum PixelFormat *pix_fmts; ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1 - /** - * Descriptive name for the codec, meant to be more human readable than name. - * You should use the NULL_IF_CONFIG_SMALL() macro to define it. - */ - const char *long_name; const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 const uint64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 @@ -2880,6 +2869,15 @@ typedef struct AVCodec { const AVClass *priv_class; ///< AVClass for the private context const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN} + /***************************************************************** + * No fields below this line are part of the public API. They + * may not be used outside of libavcodec and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + int priv_data_size; + struct AVCodec *next; /** * @name Frame-level threading support functions * @{ @@ -2910,6 +2908,8 @@ typedef struct AVCodec { */ void (*init_static_data)(struct AVCodec *codec); + int (*init)(AVCodecContext *); + int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data); /** * Encode data to an AVPacket. * @@ -2922,6 +2922,13 @@ typedef struct AVCodec { */ int (*encode2)(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr); + int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt); + int (*close)(AVCodecContext *); + /** + * Flush buffers. + * Will be called when seeking + */ + void (*flush)(AVCodecContext *); } AVCodec; /** @@ -3561,7 +3568,8 @@ AVCodecContext *avcodec_alloc_context2(enum AVMediaType); /** * Allocate an AVCodecContext and set its fields to default values. The - * resulting struct can be deallocated by simply calling av_free(). + * resulting struct can be deallocated by calling avcodec_close() on it followed + * by av_free(). * * @param codec if non-NULL, allocate private data and initialize defaults * for the given codec. It is illegal to then call avcodec_open2() @@ -3702,6 +3710,11 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec); * @endcode * * @param avctx The context to initialize. + * @param codec The codec to open this context for. If a non-NULL codec has been + * previously passed to avcodec_alloc_context3() or + * avcodec_get_context_defaults3() for this context, then this + * parameter MUST be either NULL or equal to the previously passed + * codec. * @param options A dictionary filled with AVCodecContext and codec-private options. * On return this object will be filled with options that were not found. * @@ -3987,6 +4000,15 @@ int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVSubtitle *sub); +/** + * Close a given AVCodecContext and free all the data associated with it + * (but not the AVCodecContext itself). + * + * Calling this function on an AVCodecContext that hasn't been opened will free + * the codec-specific data allocated in avcodec_alloc_context3() / + * avcodec_get_context_defaults3() with a non-NULL codec. Subsequent calls will + * do nothing. + */ int avcodec_close(AVCodecContext *avctx); /** @@ -4378,4 +4400,10 @@ const AVClass *avcodec_get_class(void); */ const AVClass *avcodec_get_frame_class(void); +/** + * @return a positive value if s is open (i.e. avcodec_open2() was called on it + * with no corresponding avcodec_close()), 0 otherwise. + */ +int avcodec_is_open(AVCodecContext *s); + #endif /* AVCODEC_AVCODEC_H */ diff --git a/libavcodec/golomb-test.c b/libavcodec/golomb-test.c new file mode 100644 index 0000000000..3dbf9d14cb --- /dev/null +++ b/libavcodec/golomb-test.c @@ -0,0 +1,70 @@ +/* + * 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 <stdint.h> +#include <stdio.h> + +#include "avcodec.h" +#include "dsputil.h" +#include "get_bits.h" +#include "golomb.h" +#include "put_bits.h" + +#undef printf +#define COUNT 8000 +#define SIZE (COUNT * 40) + +int main(void) +{ + int i; + uint8_t temp[SIZE]; + PutBitContext pb; + GetBitContext gb; + + init_put_bits(&pb, temp, SIZE); + printf("testing unsigned exp golomb\n"); + for (i = 0; i < COUNT; i++) + set_ue_golomb(&pb, i); + flush_put_bits(&pb); + + init_get_bits(&gb, temp, 8 * SIZE); + for (i = 0; i < COUNT; i++) { + int j, s = show_bits(&gb, 24); + + j = get_ue_golomb(&gb); + if (j != i) + printf("mismatch at %d (%d should be %d) bits: %6X\n", i, j, i, s); + } + + init_put_bits(&pb, temp, SIZE); + printf("testing signed exp golomb\n"); + for (i = 0; i < COUNT; i++) + set_se_golomb(&pb, i - COUNT / 2); + flush_put_bits(&pb); + + init_get_bits(&gb, temp, 8 * SIZE); + for (i = 0; i < COUNT; i++) { + int j, s = show_bits(&gb, 24); + + j = get_se_golomb(&gb); + if (j != i - COUNT / 2) + printf("mismatch at %d (%d should be %d) bits: %6X\n", i, j, i, s); + } + + return 0; +} diff --git a/libavcodec/h264.c b/libavcodec/h264.c index a3343da6e4..7a16bdaedc 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -4162,77 +4162,6 @@ static inline void fill_mb_avail(H264Context *h){ } #endif -#ifdef TEST -#undef printf -#undef random -#define COUNT 8000 -#define SIZE (COUNT*40) -extern AVCodec ff_h264_decoder; -int main(void){ - int i; - uint8_t temp[SIZE]; - PutBitContext pb; - GetBitContext gb; - DSPContext dsp; - AVCodecContext avctx; - - avcodec_get_context_defaults3(&avctx, &ff_h264_decoder); - - dsputil_init(&dsp, &avctx); - - init_put_bits(&pb, temp, SIZE); - printf("testing unsigned exp golomb\n"); - for(i=0; i<COUNT; i++){ - START_TIMER - set_ue_golomb(&pb, i); - STOP_TIMER("set_ue_golomb"); - } - flush_put_bits(&pb); - - init_get_bits(&gb, temp, 8*SIZE); - for(i=0; i<COUNT; i++){ - int j, s = show_bits(&gb, 24); - - {START_TIMER - j= get_ue_golomb(&gb); - if(j != i){ - printf("mismatch! at %d (%d should be %d) bits:%6X\n", i, j, i, s); -// return -1; - } - STOP_TIMER("get_ue_golomb");} - } - - - init_put_bits(&pb, temp, SIZE); - printf("testing signed exp golomb\n"); - for(i=0; i<COUNT; i++){ - START_TIMER - set_se_golomb(&pb, i - COUNT/2); - STOP_TIMER("set_se_golomb"); - } - flush_put_bits(&pb); - - init_get_bits(&gb, temp, 8*SIZE); - for(i=0; i<COUNT; i++){ - int j, s = show_bits(&gb, 24); - - {START_TIMER - j= get_se_golomb(&gb); - if(j != i - COUNT/2){ - printf("mismatch! at %d (%d should be %d) bits:%6X\n", i, j, i, s); -// return -1; - } - STOP_TIMER("get_se_golomb");} - } - - printf("Testing RBSP\n"); - - - return 0; -} -#endif /* TEST */ - - av_cold void ff_h264_free_context(H264Context *h) { int i; diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index da34d84878..19d6f0d5eb 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -1380,18 +1380,17 @@ static int mp_decode_layer3(MPADecodeContext *s) if (!s->adu_mode) { int skip; const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3); + int extrasize = av_clip(get_bits_left(&s->gb) >> 3, 0, EXTRABYTES); assert((get_bits_count(&s->gb) & 7) == 0); /* now we get bits from the main_data_begin offset */ av_dlog(s->avctx, "seekback: %d\n", main_data_begin); //av_log(NULL, AV_LOG_ERROR, "backstep:%d, lastbuf:%d\n", main_data_begin, s->last_buf_size); - if (s->gb.size_in_bits > get_bits_count(&s->gb)) - memcpy(s->last_buf + s->last_buf_size, ptr, - FFMIN(EXTRABYTES, (s->gb.size_in_bits - get_bits_count(&s->gb))>>3)); + memcpy(s->last_buf + s->last_buf_size, ptr, extrasize); s->in_gb = s->gb; init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8); #if !UNCHECKED_BITSTREAM_READER - s->gb.size_in_bits_plus8 += EXTRABYTES * 8; + s->gb.size_in_bits_plus8 += extrasize * 8; #endif skip_bits_long(&s->gb, 8*(s->last_buf_size - main_data_begin)); } diff --git a/libavcodec/options.c b/libavcodec/options.c index e1b8084bc3..d154da765b 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -526,7 +526,7 @@ AVCodecContext *avcodec_alloc_context(void){ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) { - if (dest->codec) { // check that the dest context is uninitialized + if (avcodec_is_open(dest)) { // check that the dest context is uninitialized av_log(dest, AV_LOG_ERROR, "Tried to copy AVCodecContext %p into already-initialized %p\n", src, dest); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index a41c8a5596..0df3d7f8b0 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -700,6 +700,21 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD int ret = 0; AVDictionary *tmp = NULL; + if (avcodec_is_open(avctx)) + return 0; + + if ((!codec && !avctx->codec)) { + av_log(avctx, AV_LOG_ERROR, "No codec provided to avcodec_open2().\n"); + return AVERROR(EINVAL); + } + if ((codec && avctx->codec && codec != avctx->codec)) { + av_log(avctx, AV_LOG_ERROR, "This AVCodecContext was allocated for %s, " + "but %s passed to avcodec_open2().\n", avctx->codec->name, codec->name); + return AVERROR(EINVAL); + } + if (!codec) + codec = avctx->codec; + if (avctx->extradata_size < 0 || avctx->extradata_size >= FF_MAX_EXTRADATA_SIZE) return AVERROR(EINVAL); @@ -719,11 +734,6 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD goto end; } - if(avctx->codec || !codec) { - ret = AVERROR(EINVAL); - goto end; - } - avctx->internal = av_mallocz(sizeof(AVCodecInternal)); if (!avctx->internal) { ret = AVERROR(ENOMEM); @@ -1408,14 +1418,17 @@ av_cold int avcodec_close(AVCodecContext *avctx) return -1; } - if (HAVE_THREADS && avctx->thread_opaque) - ff_thread_free(avctx); - if (avctx->codec && avctx->codec->close) - avctx->codec->close(avctx); - avcodec_default_free_buffers(avctx); - avctx->coded_frame = NULL; - av_freep(&avctx->internal); - if (avctx->codec && avctx->codec->priv_class) + if (avcodec_is_open(avctx)) { + if (HAVE_THREADS && avctx->thread_opaque) + ff_thread_free(avctx); + if (avctx->codec && avctx->codec->close) + avctx->codec->close(avctx); + avcodec_default_free_buffers(avctx); + avctx->coded_frame = NULL; + av_freep(&avctx->internal); + } + + if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) av_opt_free(avctx->priv_data); av_opt_free(avctx); av_freep(&avctx->priv_data); @@ -1976,3 +1989,8 @@ enum AVMediaType avcodec_get_type(enum CodecID codec_id) return AVMEDIA_TYPE_UNKNOWN; } + +int avcodec_is_open(AVCodecContext *s) +{ + return !!s->internal; +} diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c index 4b0a68b2d5..e6d202af3b 100644 --- a/libavcodec/wmalosslessdec.c +++ b/libavcodec/wmalosslessdec.c @@ -1550,15 +1550,14 @@ static void flush(AVCodecContext *avctx) *@brief wmall decoder */ AVCodec ff_wmalossless_decoder = { - "wmalossless", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_WMALOSSLESS, - sizeof(WmallDecodeCtx), - decode_init, - NULL, - decode_end, - decode_packet, + .name = "wmalossless", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_WMALOSSLESS, + .priv_data_size = sizeof(WmallDecodeCtx), + .init = decode_init, + .close = decode_end, + .decode = decode_packet, + .flush = flush, .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_EXPERIMENTAL, - .flush= flush, .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Lossless"), }; diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index 282bc916bd..3b8ee56a49 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -29,8 +29,9 @@ MMX-OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred_init.o MMX-OBJS-$(CONFIG_RV30_DECODER) += x86/rv34dsp_init.o YASM-OBJS-$(CONFIG_RV30_DECODER) += x86/rv34dsp.o MMX-OBJS-$(CONFIG_RV40_DECODER) += x86/rv34dsp_init.o \ + x86/rv40dsp_init.o +YASM-OBJS-$(CONFIG_RV40_DECODER) += x86/rv34dsp.o \ x86/rv40dsp.o -YASM-OBJS-$(CONFIG_RV40_DECODER) += x86/rv34dsp.o YASM-OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp_yasm.o diff --git a/libavcodec/x86/fmtconvert_mmx.c b/libavcodec/x86/fmtconvert_mmx.c index a3d8f89816..ca0b29344a 100644 --- a/libavcodec/x86/fmtconvert_mmx.c +++ b/libavcodec/x86/fmtconvert_mmx.c @@ -110,9 +110,9 @@ static void float_interleave_sse(float *dst, const float **src, void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx) { +#if HAVE_YASM int mm_flags = av_get_cpu_flags(); -#if HAVE_YASM if (mm_flags & AV_CPU_FLAG_MMX) { c->float_interleave = float_interleave_mmx; diff --git a/libavcodec/x86/rv40dsp.asm b/libavcodec/x86/rv40dsp.asm new file mode 100644 index 0000000000..bff3e7b96a --- /dev/null +++ b/libavcodec/x86/rv40dsp.asm @@ -0,0 +1,207 @@ +;****************************************************************************** +;* MMX/SSE2-optimized functions for the RV40 decoder +;* Copyright (C) 2012 Christophe Gisquet <christophe.gisquet@gmail.com> +;* +;* 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 "x86inc.asm" +%include "x86util.asm" + +SECTION_RODATA + +align 16 +shift_round: times 8 dw 1 << (16 - 6) +cextern pw_16 + +SECTION .text + +; %1=5bits weights?, %2=dst %3=src1 %4=src3 %5=stride if sse2 +%macro RV40_WCORE 4-5 + movh m4, [%3 + 0] + movh m5, [%4 + 0] +%if %0 == 4 +%define OFFSET mmsize / 2 +%else + ; 8x8 block and sse2, stride was provided +%define OFFSET %5 +%endif + movh m6, [%3 + OFFSET] + movh m7, [%4 + OFFSET] + +%if %1 == 0 + ; 14bits weights + punpcklbw m4, m0 + punpcklbw m5, m0 + punpcklbw m6, m0 + punpcklbw m7, m0 + + psllw m4, 7 + psllw m5, 7 + psllw m6, 7 + psllw m7, 7 + pmulhw m4, m3 + pmulhw m5, m2 + pmulhw m6, m3 + pmulhw m7, m2 + + paddw m4, m5 + paddw m6, m7 +%else + ; 5bits weights +%if cpuflag(ssse3) + punpcklbw m4, m5 + punpcklbw m6, m7 + + pmaddubsw m4, m3 + pmaddubsw m6, m3 +%else + punpcklbw m4, m0 + punpcklbw m5, m0 + punpcklbw m6, m0 + punpcklbw m7, m0 + + pmullw m4, m3 + pmullw m5, m2 + pmullw m6, m3 + pmullw m7, m2 + paddw m4, m5 + paddw m6, m7 +%endif + +%endif + + ; bias and shift down +%if cpuflag(ssse3) + pmulhrsw m4, m1 + pmulhrsw m6, m1 +%else + paddw m4, m1 + paddw m6, m1 + psrlw m4, 5 + psrlw m6, 5 +%endif + + packuswb m4, m6 +%if %0 == 5 + ; Only called for 8x8 blocks and sse2 + movh [%2 + 0], m4 + movhps [%2 + %5], m4 +%else + mova [%2], m4 +%endif +%endmacro + + +%macro MAIN_LOOP 2 +%if mmsize == 8 + RV40_WCORE %2, r0, r1, r2 +%if %1 == 16 + RV40_WCORE %2, r0 + 8, r1 + 8, r2 + 8 +%endif + + ; Prepare for next loop + add r0, r5 + add r1, r5 + add r2, r5 +%else +%ifidn %1, 8 + RV40_WCORE %2, r0, r1, r2, r5 + ; Prepare 2 next lines + lea r0, [r0 + 2 * r5] + lea r1, [r1 + 2 * r5] + lea r2, [r2 + 2 * r5] +%else + RV40_WCORE %2, r0, r1, r2 + ; Prepare single next line + add r0, r5 + add r1, r5 + add r2, r5 +%endif +%endif + + dec r6 +%endmacro + +; rv40_weight_func_%1(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w1, int w2, int stride) +; %1=size %2=num of xmm regs +%macro RV40_WEIGHT 2 +cglobal rv40_weight_func_%1, 6, 7, %2 +%if cpuflag(ssse3) + mova m1, [shift_round] +%else + mova m1, [pw_16] +%endif + pxor m0, m0 + mov r6, r3 + or r6, r4 + ; The weights are FP0.14 notation of fractions depending on pts. + ; For timebases without rounding error (i.e. PAL), the fractions + ; can be simplified, and several operations can be avoided. + ; Therefore, we check here whether they are multiples of 2^9 for + ; those simplifications to occur. + and r6, 0x1FF + ; Set loop counter and increments +%if mmsize == 8 + mov r6, %1 +%else + mov r6, (%1 * %1) / mmsize +%endif + + ; Use result of test now + jz .loop_512 + movd m2, r3 + movd m3, r4 + SPLATW m2, m2 + SPLATW m3, m3 + +.loop: + MAIN_LOOP %1, 0 + jnz .loop + REP_RET + + ; Weights are multiple of 512, which allows some shortcuts +.loop_512: + sar r3, 9 + sar r4, 9 + movd m2, r3 + movd m3, r4 +%if cpuflag(ssse3) + punpcklbw m3, m2 + SPLATW m3, m3 +%else + SPLATW m2, m2 + SPLATW m3, m3 +%endif +.loop2: + MAIN_LOOP %1, 1 + jnz .loop2 + REP_RET + +%endmacro + +INIT_MMX mmx +RV40_WEIGHT 8, 0 +RV40_WEIGHT 16, 0 + +INIT_XMM sse2 +RV40_WEIGHT 8, 8 +RV40_WEIGHT 16, 8 + +INIT_XMM ssse3 +RV40_WEIGHT 8, 8 +RV40_WEIGHT 16, 8 diff --git a/libavcodec/x86/rv40dsp.c b/libavcodec/x86/rv40dsp_init.c index 9f90ad8bb6..3d6c6f0fa0 100644 --- a/libavcodec/x86/rv40dsp.c +++ b/libavcodec/x86/rv40dsp_init.c @@ -40,14 +40,25 @@ void ff_avg_rv40_chroma_mc4_mmx2 (uint8_t *dst, uint8_t *src, void ff_avg_rv40_chroma_mc4_3dnow(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y); +#define DECLARE_WEIGHT(opt) \ +void ff_rv40_weight_func_16_##opt(uint8_t *dst, uint8_t *src1, uint8_t *src2, \ + int w1, int w2, int stride); \ +void ff_rv40_weight_func_8_##opt (uint8_t *dst, uint8_t *src1, uint8_t *src2, \ + int w1, int w2, int stride); +DECLARE_WEIGHT(mmx) +DECLARE_WEIGHT(sse2) +DECLARE_WEIGHT(ssse3) + void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp) { - av_unused int mm_flags = av_get_cpu_flags(); - #if HAVE_YASM + int mm_flags = av_get_cpu_flags(); + if (mm_flags & AV_CPU_FLAG_MMX) { c->put_chroma_pixels_tab[0] = ff_put_rv40_chroma_mc8_mmx; c->put_chroma_pixels_tab[1] = ff_put_rv40_chroma_mc4_mmx; + c->rv40_weight_pixels_tab[0] = ff_rv40_weight_func_16_mmx; + c->rv40_weight_pixels_tab[1] = ff_rv40_weight_func_8_mmx; } if (mm_flags & AV_CPU_FLAG_MMX2) { c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_mmx2; @@ -56,5 +67,13 @@ void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp) c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_3dnow; c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_3dnow; } + if (mm_flags & AV_CPU_FLAG_SSE2) { + c->rv40_weight_pixels_tab[0] = ff_rv40_weight_func_16_sse2; + c->rv40_weight_pixels_tab[1] = ff_rv40_weight_func_8_sse2; + } + if (mm_flags & AV_CPU_FLAG_SSSE3) { + c->rv40_weight_pixels_tab[0] = ff_rv40_weight_func_16_ssse3; + c->rv40_weight_pixels_tab[1] = ff_rv40_weight_func_8_ssse3; + } #endif } |