diff --git a/doc/APIchanges b/doc/APIchanges index 3c5fe68921..84d821a7cd 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -16,6 +16,12 @@ API changes, most recent first: 2012-01-24 - xxxxxxx - lavfi 2.60.100 Add avfilter_graph_dump. +2012-01-31 - xxxxxxx - lavf 54.01.0 + Add avformat_get_riff_video_tags() and avformat_get_riff_audio_tags(). + +2012-01-31 - xxxxxxx - lavc 54.01.0 + Add avcodec_is_open() function. + 2012-01-30 - xxxxxxx - lavu 51.22.0 - intfloat.h Add a new installed header libavutil/intfloat.h with int/float punning functions. 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 + #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 +#include + +#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; iadu_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 +;* +;* 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 similarity index 72% rename from libavcodec/x86/rv40dsp.c rename to 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 } diff --git a/libavformat/Makefile b/libavformat/Makefile index 623cd65234..bd2b17b6cd 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -12,6 +12,7 @@ OBJS = allformats.o \ metadata.o \ options.o \ os_support.o \ + riff.o \ sdp.o \ seek.o \ utils.o \ @@ -29,8 +30,8 @@ OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o OBJS-$(CONFIG_ADX_MUXER) += rawenc.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 -OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o riff.o isom.o +OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o pcm.o isom.o +OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o isom.o OBJS-$(CONFIG_AMR_DEMUXER) += amr.o OBJS-$(CONFIG_AMR_MUXER) += amr.o OBJS-$(CONFIG_ANM_DEMUXER) += anm.o @@ -38,14 +39,14 @@ OBJS-$(CONFIG_APC_DEMUXER) += apc.o OBJS-$(CONFIG_APE_DEMUXER) += ape.o apetag.o OBJS-$(CONFIG_APPLEHTTP_DEMUXER) += applehttp.o OBJS-$(CONFIG_ASF_DEMUXER) += asfdec.o asf.o asfcrypt.o \ - riff.o avlanguage.o -OBJS-$(CONFIG_ASF_MUXER) += asfenc.o asf.o riff.o + avlanguage.o +OBJS-$(CONFIG_ASF_MUXER) += asfenc.o asf.o OBJS-$(CONFIG_ASS_DEMUXER) += assdec.o OBJS-$(CONFIG_ASS_MUXER) += assenc.o OBJS-$(CONFIG_AU_DEMUXER) += au.o pcm.o OBJS-$(CONFIG_AU_MUXER) += au.o -OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o riff.o -OBJS-$(CONFIG_AVI_MUXER) += avienc.o riff.o +OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o +OBJS-$(CONFIG_AVI_MUXER) += avienc.o OBJS-$(CONFIG_AVISYNTH) += avisynth.o OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o OBJS-$(CONFIG_AVS_DEMUXER) += avs.o vocdec.o voc.o @@ -58,7 +59,7 @@ OBJS-$(CONFIG_BIT_MUXER) += bit.o OBJS-$(CONFIG_BMV_DEMUXER) += bmv.o OBJS-$(CONFIG_C93_DEMUXER) += c93.o vocdec.o voc.o OBJS-$(CONFIG_CAF_DEMUXER) += cafdec.o caf.o mov.o mov_chan.o \ - riff.o isom.o + isom.o OBJS-$(CONFIG_CAF_MUXER) += cafenc.o caf.o riff.o isom.o OBJS-$(CONFIG_CAVSVIDEO_DEMUXER) += cavsvideodec.o rawdec.o OBJS-$(CONFIG_CAVSVIDEO_MUXER) += rawenc.o @@ -76,7 +77,7 @@ OBJS-$(CONFIG_DTS_DEMUXER) += dtsdec.o rawdec.o OBJS-$(CONFIG_DTS_MUXER) += rawenc.o OBJS-$(CONFIG_DV_DEMUXER) += dv.o OBJS-$(CONFIG_DV_MUXER) += dvenc.o -OBJS-$(CONFIG_DXA_DEMUXER) += dxa.o riff.o +OBJS-$(CONFIG_DXA_DEMUXER) += dxa.o OBJS-$(CONFIG_EA_CDATA_DEMUXER) += eacdata.o OBJS-$(CONFIG_EA_DEMUXER) += electronicarts.o OBJS-$(CONFIG_EAC3_DEMUXER) += ac3dec.o rawdec.o @@ -125,7 +126,7 @@ OBJS-$(CONFIG_INGENIENT_DEMUXER) += ingenientdec.o rawdec.o OBJS-$(CONFIG_IPMOVIE_DEMUXER) += ipmovie.o OBJS-$(CONFIG_ISS_DEMUXER) += iss.o OBJS-$(CONFIG_IV8_DEMUXER) += iv8.o -OBJS-$(CONFIG_IVF_DEMUXER) += ivfdec.o riff.o +OBJS-$(CONFIG_IVF_DEMUXER) += ivfdec.o OBJS-$(CONFIG_IVF_MUXER) += ivfenc.o OBJS-$(CONFIG_JV_DEMUXER) += jvdec.o OBJS-$(CONFIG_LATM_DEMUXER) += rawdec.o @@ -136,9 +137,9 @@ OBJS-$(CONFIG_LXF_DEMUXER) += lxfdec.o OBJS-$(CONFIG_M4V_DEMUXER) += m4vdec.o rawdec.o OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ - riff.o isom.o rmdec.o rm.o + isom.o rmdec.o rm.o OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \ - riff.o isom.o avc.o \ + isom.o avc.o \ flacenc_header.o avlanguage.o OBJS-$(CONFIG_MD5_MUXER) += md5enc.o OBJS-$(CONFIG_MICRODVD_DEMUXER) += microdvddec.o @@ -149,9 +150,9 @@ OBJS-$(CONFIG_MLP_DEMUXER) += rawdec.o OBJS-$(CONFIG_MLP_MUXER) += rawenc.o OBJS-$(CONFIG_MM_DEMUXER) += mm.o OBJS-$(CONFIG_MMF_DEMUXER) += mmf.o pcm.o -OBJS-$(CONFIG_MMF_MUXER) += mmf.o riff.o -OBJS-$(CONFIG_MOV_DEMUXER) += mov.o riff.o isom.o mov_chan.o -OBJS-$(CONFIG_MOV_MUXER) += movenc.o riff.o isom.o avc.o \ +OBJS-$(CONFIG_MMF_MUXER) += mmf.o +OBJS-$(CONFIG_MOV_DEMUXER) += mov.o isom.o mov_chan.o +OBJS-$(CONFIG_MOV_MUXER) += movenc.o isom.o avc.o \ movenchint.o rtpenc_chain.o \ mov_chan.o OBJS-$(CONFIG_MP2_MUXER) += mp3enc.o rawenc.o @@ -180,9 +181,9 @@ OBJS-$(CONFIG_MXG_DEMUXER) += mxg.o OBJS-$(CONFIG_NC_DEMUXER) += ncdec.o OBJS-$(CONFIG_NSV_DEMUXER) += nsvdec.o OBJS-$(CONFIG_NULL_MUXER) += nullenc.o -OBJS-$(CONFIG_NUT_DEMUXER) += nutdec.o nut.o riff.o -OBJS-$(CONFIG_NUT_MUXER) += nutenc.o nut.o riff.o -OBJS-$(CONFIG_NUV_DEMUXER) += nuv.o riff.o +OBJS-$(CONFIG_NUT_DEMUXER) += nutdec.o nut.o +OBJS-$(CONFIG_NUT_MUXER) += nutenc.o nut.o +OBJS-$(CONFIG_NUV_DEMUXER) += nuv.o OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \ oggparsecelt.o \ oggparsedirac.o \ @@ -192,7 +193,6 @@ OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \ oggparsespeex.o \ oggparsetheora.o \ oggparsevorbis.o \ - riff.o \ vorbiscomment.o OBJS-$(CONFIG_OGG_MUXER) += oggenc.o \ vorbiscomment.o @@ -319,31 +319,31 @@ OBJS-$(CONFIG_VMD_DEMUXER) += sierravmd.o OBJS-$(CONFIG_VOC_DEMUXER) += vocdec.o voc.o OBJS-$(CONFIG_VOC_MUXER) += vocenc.o voc.o OBJS-$(CONFIG_VQF_DEMUXER) += vqf.o -OBJS-$(CONFIG_W64_DEMUXER) += wav.o riff.o pcm.o -OBJS-$(CONFIG_WAV_DEMUXER) += wav.o riff.o pcm.o -OBJS-$(CONFIG_WAV_MUXER) += wav.o riff.o +OBJS-$(CONFIG_W64_DEMUXER) += wav.o pcm.o +OBJS-$(CONFIG_WAV_DEMUXER) += wav.o pcm.o +OBJS-$(CONFIG_WAV_MUXER) += wav.o OBJS-$(CONFIG_WC3_DEMUXER) += wc3movie.o OBJS-$(CONFIG_WEBM_MUXER) += matroskaenc.o matroska.o \ - riff.o isom.o avc.o \ + isom.o avc.o \ flacenc_header.o avlanguage.o OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood_aud.o OBJS-$(CONFIG_WSVQA_DEMUXER) += westwood_vqa.o OBJS-$(CONFIG_WTV_DEMUXER) += wtvdec.o wtv.o asfdec.o asf.o asfcrypt.o \ - avlanguage.o mpegts.o isom.o riff.o -OBJS-$(CONFIG_WTV_MUXER) += wtvenc.o wtv.o asf.o asfenc.o riff.o + avlanguage.o mpegts.o isom.o +OBJS-$(CONFIG_WTV_MUXER) += wtvenc.o wtv.o asf.o asfenc.o OBJS-$(CONFIG_WV_DEMUXER) += wv.o apetag.o OBJS-$(CONFIG_XA_DEMUXER) += xa.o OBJS-$(CONFIG_XBIN_DEMUXER) += bintext.o sauce.o -OBJS-$(CONFIG_XMV_DEMUXER) += xmv.o riff.o -OBJS-$(CONFIG_XWMA_DEMUXER) += xwma.o riff.o +OBJS-$(CONFIG_XMV_DEMUXER) += xmv.o +OBJS-$(CONFIG_XWMA_DEMUXER) += xwma.o OBJS-$(CONFIG_YOP_DEMUXER) += yop.o OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER) += yuv4mpeg.o OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER) += yuv4mpeg.o # external libraries OBJS-$(CONFIG_LIBMODPLUG_DEMUXER) += libmodplug.o -OBJS-$(CONFIG_LIBNUT_DEMUXER) += libnut.o riff.o -OBJS-$(CONFIG_LIBNUT_MUXER) += libnut.o riff.o +OBJS-$(CONFIG_LIBNUT_DEMUXER) += libnut.o +OBJS-$(CONFIG_LIBNUT_MUXER) += libnut.o # protocols I/O OBJS+= avio.o aviobuf.o diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c index ff58c36675..156a3509a4 100644 --- a/libavformat/aacdec.c +++ b/libavformat/aacdec.c @@ -71,7 +71,7 @@ static int adts_aac_read_header(AVFormatContext *s) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->iformat->value; + st->codec->codec_id = s->iformat->raw_codec_id; st->need_parsing = AVSTREAM_PARSE_FULL; ff_id3v1_read(s); @@ -90,5 +90,5 @@ AVInputFormat ff_aac_demuxer = { .read_packet = ff_raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, .extensions = "aac", - .value = CODEC_ID_AAC, + .raw_codec_id = CODEC_ID_AAC, }; diff --git a/libavformat/ac3dec.c b/libavformat/ac3dec.c index f1421dc058..849b8360f8 100644 --- a/libavformat/ac3dec.c +++ b/libavformat/ac3dec.c @@ -80,7 +80,7 @@ AVInputFormat ff_ac3_demuxer = { .read_packet = ff_raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, .extensions = "ac3", - .value = CODEC_ID_AC3, + .raw_codec_id = CODEC_ID_AC3, }; #endif @@ -98,6 +98,6 @@ AVInputFormat ff_eac3_demuxer = { .read_packet = ff_raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, .extensions = "eac3", - .value = CODEC_ID_EAC3, + .raw_codec_id = CODEC_ID_EAC3, }; #endif diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c index 243160940c..305c67431b 100644 --- a/libavformat/adxdec.c +++ b/libavformat/adxdec.c @@ -94,7 +94,7 @@ static int adx_read_header(AVFormatContext *s) return ret; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->iformat->value; + st->codec->codec_id = s->iformat->raw_codec_id; avpriv_set_pts_info(st, 64, BLOCK_SAMPLES, avctx->sample_rate); @@ -108,6 +108,6 @@ AVInputFormat ff_adx_demuxer = { .read_header = adx_read_header, .read_packet = adx_read_packet, .extensions = "adx", - .value = CODEC_ID_ADPCM_ADX, + .raw_codec_id = CODEC_ID_ADPCM_ADX, .flags = AVFMT_GENERIC_INDEX, }; diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 55616a8010..dae0c07ffb 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -312,13 +312,39 @@ typedef struct AVOutputFormat { const char *long_name; const char *mime_type; const char *extensions; /**< comma-separated filename extensions */ + /* output support */ + enum CodecID audio_codec; /**< default audio codec */ + enum CodecID video_codec; /**< default video codec */ + enum CodecID subtitle_codec; /**< default subtitle codec */ + /** + * can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_RAWPICTURE, + * AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS, AVFMT_VARIABLE_FPS, + * AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH + */ + int flags; + + /** + * List of supported codec_id-codec_tag pairs, ordered by "better + * choice first". The arrays are all terminated by CODEC_ID_NONE. + */ + const struct AVCodecTag * const *codec_tag; + + + const AVClass *priv_class; ///< AVClass for the private context + + /***************************************************************** + * No fields below this line are part of the public API. They + * may not be used outside of libavformat and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + struct AVOutputFormat *next; /** * size of private data so that it can be allocated in the wrapper */ int priv_data_size; - /* output support */ - enum CodecID audio_codec; /**< default audio codec */ - enum CodecID video_codec; /**< default video codec */ + int (*write_header)(struct AVFormatContext *); /** * Write a packet. If AVFMT_ALLOW_FLUSH is set in flags, @@ -330,24 +356,10 @@ typedef struct AVOutputFormat { int (*write_packet)(struct AVFormatContext *, AVPacket *pkt); int (*write_trailer)(struct AVFormatContext *); /** - * can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_RAWPICTURE, - * AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS, AVFMT_VARIABLE_FPS, - * AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH + * Currently only used to set pixel format if not YUV420P. */ - int flags; int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, AVPacket *in, int flush); - - /** - * List of supported codec_id-codec_tag pairs, ordered by "better - * choice first". The arrays are all terminated by CODEC_ID_NONE. - */ - const struct AVCodecTag * const *codec_tag; - - enum CodecID subtitle_codec; /**< default subtitle codec */ - - const AVClass *priv_class; ///< AVClass for the private context - /** * Test if the given codec can be stored in this container. * @@ -358,9 +370,6 @@ typedef struct AVOutputFormat { void (*get_output_timestamp)(struct AVFormatContext *s, int stream, int64_t *dts, int64_t *wall); - - /* private fields */ - struct AVOutputFormat *next; } AVOutputFormat; /** * @} @@ -384,6 +393,38 @@ typedef struct AVInputFormat { */ const char *long_name; + /** + * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS, + * AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH, + * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK. + */ + int flags; + + /** + * If extensions are defined, then no probe is done. You should + * usually not use extension format guessing because it is not + * reliable enough + */ + const char *extensions; + + const struct AVCodecTag * const *codec_tag; + + const AVClass *priv_class; ///< AVClass for the private context + + /***************************************************************** + * No fields below this line are part of the public API. They + * may not be used outside of libavformat and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + struct AVInputFormat *next; + + /** + * Raw demuxers store their codec ID here. + */ + int raw_codec_id; + /** * Size of private data so that it can be allocated in the wrapper. */ @@ -439,25 +480,6 @@ typedef struct AVInputFormat { int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, int64_t *pos, int64_t pos_limit); - /** - * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS, - * AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH, - * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK. - */ - int flags; - - /** - * If extensions are defined, then no probe is done. You should - * usually not use extension format guessing because it is not - * reliable enough - */ - const char *extensions; - - /** - * General purpose read-only value that the format can use. - */ - int value; - /** * Start/resume playing - only meaningful if using a network-based format * (RTSP). @@ -470,8 +492,6 @@ typedef struct AVInputFormat { */ int (*read_pause)(struct AVFormatContext *); - const struct AVCodecTag * const *codec_tag; - /** * Seek to timestamp ts. * Seeking will be done so that the point from which all active streams @@ -479,11 +499,6 @@ typedef struct AVInputFormat { * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. */ int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); - - const AVClass *priv_class; ///< AVClass for the private context - - /* private fields */ - struct AVInputFormat *next; } AVInputFormat; /** * @} @@ -1774,6 +1789,30 @@ int av_match_ext(const char *filename, const char *extensions); */ int avformat_query_codec(AVOutputFormat *ofmt, enum CodecID codec_id, int std_compliance); +/** + * @defgroup riff_fourcc RIFF FourCCs + * @{ + * Get the tables mapping RIFF FourCCs to libavcodec CodecIDs. The tables are + * meant to be passed to av_codec_get_id()/av_codec_get_tag() as in the + * following code: + * @code + * uint32_t tag = MKTAG('H', '2', '6', '4'); + * const struct AVCodecTag *table[] = { avformat_get_riff_video_tags(), 0 }; + * enum CodecID id = av_codec_get_id(table, tag); + * @endcode + */ +/** + * @return the table mapping RIFF FourCCs for video to libavcodec CodecID. + */ +const struct AVCodecTag *avformat_get_riff_video_tags(void); +/** + * @return the table mapping RIFF FourCCs for audio to CodecID. + */ +const struct AVCodecTag *avformat_get_riff_audio_tags(void); +/** + * @} + */ + /** * @} */ diff --git a/libavformat/dtsdec.c b/libavformat/dtsdec.c index e762b85e19..7395d79f91 100644 --- a/libavformat/dtsdec.c +++ b/libavformat/dtsdec.c @@ -73,5 +73,5 @@ AVInputFormat ff_dts_demuxer = { .read_packet = ff_raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, .extensions = "dts", - .value = CODEC_ID_DTS, + .raw_codec_id = CODEC_ID_DTS, }; diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index 65a75b2c48..95362922ed 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -157,5 +157,5 @@ AVInputFormat ff_flac_demuxer = { .read_packet = ff_raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, .extensions = "flac", - .value = CODEC_ID_FLAC, + .raw_codec_id = CODEC_ID_FLAC, }; diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 1f1424e949..ffb84e9794 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -233,22 +233,18 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0) return -1; break; - case AMF_DATA_TYPE_OBJECT: { - unsigned int keylen; - + case AMF_DATA_TYPE_OBJECT: if ((vstream || astream) && ioc->seekable && key && !strcmp(KEYFRAMES_TAG, key) && depth == 1) if (parse_keyframes_index(s, ioc, vstream ? vstream : astream, max_pos) < 0) av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n"); - while(avio_tell(ioc) < max_pos - 2 && (keylen = avio_rb16(ioc))) { - avio_skip(ioc, keylen); //skip key string - if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0) + while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) { + if (amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0) return -1; //if we couldn't skip, bomb out. } if(avio_r8(ioc) != AMF_END_OF_OBJECT) return -1; - } break; case AMF_DATA_TYPE_NULL: case AMF_DATA_TYPE_UNDEFINED: @@ -697,5 +693,4 @@ AVInputFormat ff_flv_demuxer = { #endif .read_close = flv_read_close, .extensions = "flv", - .value = CODEC_ID_FLV1, }; diff --git a/libavformat/gsmdec.c b/libavformat/gsmdec.c index 5d6495860a..3525a038c7 100644 --- a/libavformat/gsmdec.c +++ b/libavformat/gsmdec.c @@ -62,7 +62,7 @@ static int gsm_read_header(AVFormatContext *s) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->iformat->value; + st->codec->codec_id = s->iformat->raw_codec_id; st->codec->channels = 1; st->codec->sample_rate = c->sample_rate; st->codec->bit_rate = GSM_BLOCK_SIZE * 8 * c->sample_rate / GSM_BLOCK_SAMPLES; @@ -94,6 +94,6 @@ AVInputFormat ff_gsm_demuxer = { .read_packet = gsm_read_packet, .flags = AVFMT_GENERIC_INDEX, .extensions = "gsm", - .value = CODEC_ID_GSM, + .raw_codec_id = CODEC_ID_GSM, .priv_class = &class, }; diff --git a/libavformat/ingenientdec.c b/libavformat/ingenientdec.c index 97774abbcd..0ce2b5718c 100644 --- a/libavformat/ingenientdec.c +++ b/libavformat/ingenientdec.c @@ -68,6 +68,6 @@ AVInputFormat ff_ingenient_demuxer = { .read_packet = ingenient_read_packet, .flags= AVFMT_GENERIC_INDEX, .extensions = "cgi", // FIXME - .value = CODEC_ID_MJPEG, + .raw_codec_id = CODEC_ID_MJPEG, .priv_class = &ingenient_demuxer_class, }; diff --git a/libavformat/iv8.c b/libavformat/iv8.c index e431c342db..21f70d504a 100644 --- a/libavformat/iv8.c +++ b/libavformat/iv8.c @@ -115,5 +115,4 @@ AVInputFormat ff_iv8_demuxer = { .read_header = read_header, .read_packet = read_packet, .flags= AVFMT_GENERIC_INDEX, - .value = CODEC_ID_MPEG4, }; diff --git a/libavformat/loasdec.c b/libavformat/loasdec.c index 5c8a8be573..4b4e04fff9 100644 --- a/libavformat/loasdec.c +++ b/libavformat/loasdec.c @@ -68,7 +68,7 @@ static int loas_read_header(AVFormatContext *s) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->iformat->value; + st->codec->codec_id = s->iformat->raw_codec_id; st->need_parsing = AVSTREAM_PARSE_FULL; //LCM of all possible AAC sample rates @@ -84,5 +84,5 @@ AVInputFormat ff_loas_demuxer = { .read_header = loas_read_header, .read_packet = ff_raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, - .value = CODEC_ID_AAC_LATM, + .raw_codec_id = CODEC_ID_AAC_LATM, }; diff --git a/libavformat/mov.c b/libavformat/mov.c index 0968da264a..851997ca61 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2341,7 +2341,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->ctts_data[sc->ctts_count].duration = (flags & 0x800) ? avio_rb32(pb) : 0; sc->ctts_count++; if ((keyframe = st->codec->codec_type == AVMEDIA_TYPE_AUDIO || - (flags & 0x004 && !i && !sample_flags) || sample_flags & 0x2000000)) + (flags & 0x004 && !i && !(sample_flags & 0xffff0000)) || sample_flags & 0x2000000)) distance = 0; av_add_index_entry(st, offset, dts, sample_size, distance, keyframe ? AVINDEX_KEYFRAME : 0); diff --git a/libavformat/pcmdec.c b/libavformat/pcmdec.c index 542ee17749..e27a6b908c 100644 --- a/libavformat/pcmdec.c +++ b/libavformat/pcmdec.c @@ -70,7 +70,7 @@ AVInputFormat ff_pcm_ ## name_ ## _demuxer = { \ .read_seek = pcm_read_seek, \ .flags = AVFMT_GENERIC_INDEX, \ .extensions = ext, \ - .value = codec, \ + .raw_codec_id = codec, \ .priv_class = &name_ ## _demuxer_class, \ }; diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c index f7c0de8c25..34e4ae05b5 100644 --- a/libavformat/rawdec.c +++ b/libavformat/rawdec.c @@ -38,7 +38,7 @@ int ff_raw_read_header(AVFormatContext *s) if (!st) return AVERROR(ENOMEM); - id = s->iformat->value; + id = s->iformat->raw_codec_id; if (id == CODEC_ID_RAWVIDEO) { st->codec->codec_type = AVMEDIA_TYPE_VIDEO; } else { @@ -132,7 +132,7 @@ int ff_raw_audio_read_header(AVFormatContext *s) if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->iformat->value; + st->codec->codec_id = s->iformat->raw_codec_id; st->need_parsing = AVSTREAM_PARSE_FULL; st->start_time = 0; /* the parameters will be extracted from the compressed bitstream */ @@ -156,7 +156,7 @@ int ff_raw_video_read_header(AVFormatContext *s) } st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = s->iformat->value; + st->codec->codec_id = s->iformat->raw_codec_id; st->need_parsing = AVSTREAM_PARSE_FULL; if ((ret = av_parse_video_rate(&framerate, s1->framerate)) < 0) { @@ -188,7 +188,7 @@ AVInputFormat ff_g722_demuxer = { .read_packet = ff_raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, .extensions = "g722,722", - .value = CODEC_ID_ADPCM_G722, + .raw_codec_id = CODEC_ID_ADPCM_G722, }; #endif @@ -200,7 +200,7 @@ AVInputFormat ff_latm_demuxer = { .read_packet = ff_raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, .extensions = "latm", - .value = CODEC_ID_AAC_LATM, + .raw_codec_id = CODEC_ID_AAC_LATM, }; #endif @@ -216,7 +216,7 @@ AVInputFormat ff_mlp_demuxer = { .read_packet = ff_raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, .extensions = "mlp", - .value = CODEC_ID_MLP, + .raw_codec_id = CODEC_ID_MLP, }; #endif @@ -228,7 +228,7 @@ AVInputFormat ff_truehd_demuxer = { .read_packet = ff_raw_read_partial_packet, .flags= AVFMT_GENERIC_INDEX, .extensions = "thd", - .value = CODEC_ID_TRUEHD, + .raw_codec_id = CODEC_ID_TRUEHD, }; #endif @@ -240,7 +240,7 @@ AVInputFormat ff_shorten_demuxer = { .read_packet = ff_raw_read_partial_packet, .flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK, .extensions = "shn", - .value = CODEC_ID_SHORTEN, + .raw_codec_id = CODEC_ID_SHORTEN, }; #endif diff --git a/libavformat/rawdec.h b/libavformat/rawdec.h index 844a28824d..5812e5019b 100644 --- a/libavformat/rawdec.h +++ b/libavformat/rawdec.h @@ -67,7 +67,7 @@ AVInputFormat ff_ ## shortname ## _demuxer = {\ .read_packet = ff_raw_read_partial_packet,\ .extensions = ext,\ .flags = AVFMT_GENERIC_INDEX,\ - .value = id,\ + .raw_codec_id = id,\ .priv_data_size = sizeof(FFRawVideoDemuxerContext),\ .priv_class = &shortname ## _demuxer_class,\ }; diff --git a/libavformat/rawvideodec.c b/libavformat/rawvideodec.c index 8bd0dc92f0..7750eb2880 100644 --- a/libavformat/rawvideodec.c +++ b/libavformat/rawvideodec.c @@ -68,6 +68,6 @@ AVInputFormat ff_rawvideo_demuxer = { .read_packet = rawvideo_read_packet, .flags= AVFMT_GENERIC_INDEX, .extensions = "yuv,cif,qcif,rgb", - .value = CODEC_ID_RAWVIDEO, + .raw_codec_id = CODEC_ID_RAWVIDEO, .priv_class = &rawvideo_demuxer_class, }; diff --git a/libavformat/utils.c b/libavformat/utils.c index f6010fdb31..d974ccd0cd 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2106,10 +2106,12 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option AVFrame picture; AVPacket pkt = *avpkt; - if(!st->codec->codec){ + if (!avcodec_is_open(st->codec)) { AVDictionary *thread_opt = NULL; - codec = avcodec_find_decoder(st->codec->codec_id); + codec = st->codec->codec ? st->codec->codec : + avcodec_find_decoder(st->codec->codec_id); + if (!codec) return -1; @@ -2272,8 +2274,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; } } - assert(!st->codec->codec); - codec = avcodec_find_decoder(st->codec->codec_id); + codec = st->codec->codec ? st->codec->codec : + avcodec_find_decoder(st->codec->codec_id); /* force thread count to 1 since the h264 decoder will not extract SPS * and PPS to extradata during multi-threaded decoding */ @@ -2470,8 +2472,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) // close codecs which were opened in try_decode_frame() for(i=0;inb_streams;i++) { st = ic->streams[i]; - if(st->codec->codec) - avcodec_close(st->codec); + avcodec_close(st->codec); } for(i=0;inb_streams;i++) { st = ic->streams[i]; @@ -4184,3 +4185,12 @@ int ff_add_param_change(AVPacket *pkt, int32_t channels, } return 0; } + +const struct AVCodecTag *avformat_get_riff_video_tags(void) +{ + return ff_codec_bmp_tags; +} +const struct AVCodecTag *avformat_get_riff_audio_tags(void) +{ + return ff_codec_wav_tags; +} diff --git a/tests/fate/libavcodec.mak b/tests/fate/libavcodec.mak index 083f6e8b04..90c817812f 100644 --- a/tests/fate/libavcodec.mak +++ b/tests/fate/libavcodec.mak @@ -1,3 +1,7 @@ +FATE_TESTS += fate-golomb +fate-golomb: libavcodec/golomb-test$(EXESUF) +fate-golomb: CMD = run libavcodec/golomb-test + FATE_TESTS += fate-iirfilter fate-iirfilter: libavcodec/iirfilter-test$(EXESUF) fate-iirfilter: CMD = run libavcodec/iirfilter-test diff --git a/tests/ref/fate/golomb b/tests/ref/fate/golomb new file mode 100644 index 0000000000..652e97b305 --- /dev/null +++ b/tests/ref/fate/golomb @@ -0,0 +1,2 @@ +testing unsigned exp golomb +testing signed exp golomb