summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-02-01 02:08:23 +0100
committerMichael Niedermayer <michaelni@gmx.at>2012-02-01 02:36:09 +0100
commita369a6b85819890b21a87af3ce983ce533b7169b (patch)
tree838f9821dc09bd99b59ce4a2d8123d5fd6868b91 /libavcodec
parent0a3a69e8d77146b53a1112c715a78e7d293883b1 (diff)
parent52afc9716849e6fb6c2420674d790d374061c663 (diff)
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/Makefile2
-rw-r--r--libavcodec/adpcm.h8
-rw-r--r--libavcodec/adpcmenc.c75
-rw-r--r--libavcodec/avcodec.h62
-rw-r--r--libavcodec/golomb-test.c70
-rw-r--r--libavcodec/h264.c71
-rw-r--r--libavcodec/mpegaudiodec.c7
-rw-r--r--libavcodec/options.c2
-rw-r--r--libavcodec/utils.c44
-rw-r--r--libavcodec/wmalosslessdec.c17
-rw-r--r--libavcodec/x86/Makefile3
-rw-r--r--libavcodec/x86/fmtconvert_mmx.c2
-rw-r--r--libavcodec/x86/rv40dsp.asm207
-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
}