diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-07-04 20:39:50 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-07-04 21:03:28 +0200 |
commit | 039e9fe01ca27606a0ec1a944d51041541e10aab (patch) | |
tree | 9fc96837e878cdb2c13b6016d9f3d69785570488 /libavcodec | |
parent | 8b421fad24acbba69935caf2a2775bd04f8a707a (diff) | |
parent | 7c29377b702783680b223a12503df784b1808086 (diff) | |
download | ffmpeg-039e9fe01ca27606a0ec1a944d51041541e10aab.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master: (29 commits)
lavfi: reclassify showfiltfmts as a TESTPROG
graph2dot: fix printf format specifier
swscale: yuv2planeX 8bit >=sse2 functions need aligned stack on x86-32.
vp8: loopfilter >=sse2 functions need aligned stack on x86-32.
amr: remove shift out of the AMR_BIT() macro.
dsputilenc: group yasm and inline asm function pointer assignment.
mov: use forward declaration of a function instead of a table.
Clarify Doxygen comment for FF_API_* #defines.
configure: simplify get_version()
Create version.h headers for libraries that lack them
gitignore: Use full path instead of relative path to specify patterns
mpegvideo: remove VLAs
Add XTEA encryption support in libavutil
Add Blowfish encryption support in libavutil
eval: Add the isinf() function and tests for it
flacdec: move lpc filter to flacdsp
flacdec: split off channel decorrelation as flacdsp
avplay: Add an option for not limiting the input buffer size
FATE: add a test for WMA cover art.
FATE: add a test for apetag cover art
...
Conflicts:
.gitignore
configure
ffplay.c
libavcodec/Makefile
libavcodec/error_resilience.c
libavcodec/mpegvideo.c
libavcodec/ratecontrol.c
libavdevice/avdevice.h
libavfilter/Makefile
libavfilter/filtfmts.c
libavfilter/version.h
libavformat/mov.c
libavformat/version.h
libavutil/Makefile
libavutil/avutil.h
libavutil/version.h
libswscale/swscale.h
libswscale/x86/swscale_mmx.c
tests/fate/libavutil.mak
tests/lavfi-regression.sh
tools/graph2dot.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/Makefile | 2 | ||||
-rw-r--r-- | libavcodec/amr.h | 2 | ||||
-rw-r--r-- | libavcodec/amrnbdata.h | 2 | ||||
-rw-r--r-- | libavcodec/amrwbdata.h | 2 | ||||
-rw-r--r-- | libavcodec/error_resilience.c | 8 | ||||
-rw-r--r-- | libavcodec/flac.c | 3 | ||||
-rw-r--r-- | libavcodec/flac.h | 8 | ||||
-rw-r--r-- | libavcodec/flacdec.c | 150 | ||||
-rw-r--r-- | libavcodec/flacdsp.c | 94 | ||||
-rw-r--r-- | libavcodec/flacdsp.h | 34 | ||||
-rw-r--r-- | libavcodec/flacdsp_template.c | 86 | ||||
-rw-r--r-- | libavcodec/flacenc.c | 25 | ||||
-rw-r--r-- | libavcodec/mpegvideo.c | 13 | ||||
-rw-r--r-- | libavcodec/mpegvideo.h | 6 | ||||
-rw-r--r-- | libavcodec/ratecontrol.c | 7 | ||||
-rw-r--r-- | libavcodec/version.h | 6 | ||||
-rw-r--r-- | libavcodec/x86/dsputilenc_mmx.c | 2 | ||||
-rw-r--r-- | libavcodec/x86/vp8dsp-init.c | 6 |
18 files changed, 317 insertions, 139 deletions
diff --git a/libavcodec/Makefile b/libavcodec/Makefile index a3891c2da4..3cc0124a93 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -179,7 +179,7 @@ OBJS-$(CONFIG_FFV1_ENCODER) += ffv1.o rangecoder.o OBJS-$(CONFIG_FFVHUFF_DECODER) += huffyuv.o OBJS-$(CONFIG_FFVHUFF_ENCODER) += huffyuv.o OBJS-$(CONFIG_FFWAVESYNTH_DECODER) += ffwavesynth.o -OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o +OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o flacdsp.o OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o vorbis_data.o OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o diff --git a/libavcodec/amr.h b/libavcodec/amr.h index 7e5a4dce5b..6b24002145 100644 --- a/libavcodec/amr.h +++ b/libavcodec/amr.h @@ -61,7 +61,7 @@ static inline void ff_amr_bit_reorder(uint16_t *out, int size, field <<= 1; field |= data[bit >> 3] >> (bit & 7) & 1; } - out[field_offset] = field; + out[field_offset >> 1] = field; } } diff --git a/libavcodec/amrnbdata.h b/libavcodec/amrnbdata.h index 2745d33ffb..6e555bfdb4 100644 --- a/libavcodec/amrnbdata.h +++ b/libavcodec/amrnbdata.h @@ -71,7 +71,7 @@ typedef struct { } AMRNBFrame; /** The index of a frame parameter */ -#define AMR_BIT(field) (offsetof(AMRNBFrame, field) >> 1) +#define AMR_BIT(field) (offsetof(AMRNBFrame, field)) /** The index of a subframe-specific parameter */ #define AMR_OF(frame_num, variable) AMR_BIT(subframe[frame_num].variable) diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h index 972c257d2a..83390fc393 100644 --- a/libavcodec/amrwbdata.h +++ b/libavcodec/amrwbdata.h @@ -82,7 +82,7 @@ typedef struct { } AMRWBFrame; /** The index of a frame parameter */ -#define AMR_BIT(field) (offsetof(AMRWBFrame, field) >> 1) +#define AMR_BIT(field) (offsetof(AMRWBFrame, field)) /** The index of a subframe-specific parameter */ #define AMR_OF(frame_num, variable) AMR_BIT(subframe[frame_num].variable) diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index 63f996ccde..58e3754b7c 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -408,7 +408,7 @@ static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, static void guess_mv(MpegEncContext *s) { - uint8_t *fixed = av_malloc(s->mb_stride * s->mb_height); + uint8_t *fixed = s->er_temp_buffer; #define MV_FROZEN 3 #define MV_CHANGED 2 #define MV_UNCHANGED 1 @@ -470,7 +470,7 @@ static void guess_mv(MpegEncContext *s) decode_mb(s, 0); } } - goto end; + return; } for (depth = 0; ; depth++) { @@ -722,7 +722,7 @@ skip_last_mv: } if (none_left) - goto end; + return; for (i = 0; i < s->mb_num; i++) { int mb_xy = s->mb_index2xy[i]; @@ -731,8 +731,6 @@ skip_last_mv: } // printf(":"); fflush(stdout); } -end: - av_free(fixed); } static int is_intra_more_likely(MpegEncContext *s) diff --git a/libavcodec/flac.c b/libavcodec/flac.c index 484a44efb3..92268eac8c 100644 --- a/libavcodec/flac.c +++ b/libavcodec/flac.c @@ -55,8 +55,9 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, if (fi->ch_mode < FLAC_MAX_CHANNELS) { fi->channels = fi->ch_mode + 1; fi->ch_mode = FLAC_CHMODE_INDEPENDENT; - } else if (fi->ch_mode <= FLAC_CHMODE_MID_SIDE) { + } else if (fi->ch_mode < FLAC_MAX_CHANNELS + FLAC_CHMODE_MID_SIDE) { fi->channels = 2; + fi->ch_mode -= FLAC_MAX_CHANNELS - 1; } else { av_log(avctx, AV_LOG_ERROR + log_level_offset, "invalid channel mode: %d\n", fi->ch_mode); diff --git a/libavcodec/flac.h b/libavcodec/flac.h index 65965af6ad..94444f8a67 100644 --- a/libavcodec/flac.h +++ b/libavcodec/flac.h @@ -37,10 +37,10 @@ #define FLAC_MIN_FRAME_SIZE 11 enum { - FLAC_CHMODE_INDEPENDENT = 0, - FLAC_CHMODE_LEFT_SIDE = 8, - FLAC_CHMODE_RIGHT_SIDE = 9, - FLAC_CHMODE_MID_SIDE = 10, + FLAC_CHMODE_INDEPENDENT = 0, + FLAC_CHMODE_LEFT_SIDE = 1, + FLAC_CHMODE_RIGHT_SIDE = 2, + FLAC_CHMODE_MID_SIDE = 3, }; enum { diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 02ed463eb3..13ce95d86c 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -42,6 +42,7 @@ #include "golomb.h" #include "flac.h" #include "flacdata.h" +#include "flacdsp.h" #undef NDEBUG #include <assert.h> @@ -54,13 +55,13 @@ typedef struct FLACContext { GetBitContext gb; ///< GetBitContext initialized to start at the current frame int blocksize; ///< number of samples in the current frame - int curr_bps; ///< bps for current subframe, adjusted for channel correlation and wasted bits int sample_shift; ///< shift required to make output samples 16-bit or 32-bit - int is32; ///< flag to indicate if output should be 32-bit instead of 16-bit int ch_mode; ///< channel decorrelation type in the current frame int got_streaminfo; ///< indicates if the STREAMINFO has been read int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples + + FLACDSPContext dsp; } FLACContext; static const int64_t flac_channel_layouts[6] = { @@ -101,6 +102,17 @@ int avpriv_flac_is_extradata_valid(AVCodecContext *avctx, return 1; } +static void flac_set_bps(FLACContext *s) +{ + if (s->bps > 16) { + s->avctx->sample_fmt = AV_SAMPLE_FMT_S32; + s->sample_shift = 32 - s->bps; + } else { + s->avctx->sample_fmt = AV_SAMPLE_FMT_S16; + s->sample_shift = 16 - s->bps; + } +} + static av_cold int flac_decode_init(AVCodecContext *avctx) { enum FLACExtradataFormat format; @@ -118,11 +130,9 @@ static av_cold int flac_decode_init(AVCodecContext *avctx) /* initialize based on the demuxer-supplied streamdata header */ avpriv_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo); - if (s->bps > 16) - avctx->sample_fmt = AV_SAMPLE_FMT_S32; - else - avctx->sample_fmt = AV_SAMPLE_FMT_S16; allocate_buffers(s); + flac_set_bps(s); + ff_flacdsp_init(&s->dsp, avctx->sample_fmt); s->got_streaminfo = 1; avcodec_get_frame_defaults(&s->frame); @@ -150,8 +160,7 @@ static void allocate_buffers(FLACContext *s) assert(s->max_blocksize); for (i = 0; i < s->channels; i++) { - s->decoded[i] = av_realloc(s->decoded[i], - sizeof(int32_t)*s->max_blocksize); + s->decoded[i] = av_malloc(sizeof(int32_t)*s->max_blocksize); } } @@ -223,6 +232,8 @@ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) } avpriv_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]); allocate_buffers(s); + flac_set_bps(s); + ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt); s->got_streaminfo = 1; return 0; @@ -295,7 +306,8 @@ static int decode_residuals(FLACContext *s, int channel, int pred_order) return 0; } -static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order) +static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order, + int bps) { const int blocksize = s->blocksize; int32_t *decoded = s->decoded[channel]; @@ -303,7 +315,7 @@ static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order) /* warm up samples */ for (i = 0; i < pred_order; i++) { - decoded[i] = get_sbits_long(&s->gb, s->curr_bps); + decoded[i] = get_sbits_long(&s->gb, bps); } if (decode_residuals(s, channel, pred_order) < 0) @@ -345,16 +357,17 @@ static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order) return 0; } -static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order) +static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order, + int bps) { - int i, j; + int i; int coeff_prec, qlevel; int coeffs[32]; int32_t *decoded = s->decoded[channel]; /* warm up samples */ for (i = 0; i < pred_order; i++) { - decoded[i] = get_sbits_long(&s->gb, s->curr_bps); + decoded[i] = get_sbits_long(&s->gb, bps); } coeff_prec = get_bits(&s->gb, 4) + 1; @@ -376,38 +389,7 @@ static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order) if (decode_residuals(s, channel, pred_order) < 0) return -1; - if (s->bps > 16) { - int64_t sum; - for (i = pred_order; i < s->blocksize; i++) { - sum = 0; - for (j = 0; j < pred_order; j++) - sum += (int64_t)coeffs[j] * decoded[i-j-1]; - decoded[i] += sum >> qlevel; - } - } else { - for (i = pred_order; i < s->blocksize-1; i += 2) { - int c; - int d = decoded[i-pred_order]; - int s0 = 0, s1 = 0; - for (j = pred_order-1; j > 0; j--) { - c = coeffs[j]; - s0 += c*d; - d = decoded[i-j]; - s1 += c*d; - } - c = coeffs[0]; - s0 += c*d; - d = decoded[i] += s0 >> qlevel; - s1 += c*d; - decoded[i+1] += s1 >> qlevel; - } - if (i < s->blocksize) { - int sum = 0; - for (j = 0; j < pred_order; j++) - sum += coeffs[j] * decoded[i-j-1]; - decoded[i] += sum >> qlevel; - } - } + s->dsp.lpc(decoded, coeffs, pred_order, qlevel, s->blocksize); return 0; } @@ -415,15 +397,15 @@ static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order) static inline int decode_subframe(FLACContext *s, int channel) { int type, wasted = 0; + int bps = s->bps; int i, tmp; - s->curr_bps = s->bps; if (channel == 0) { if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE) - s->curr_bps++; + bps++; } else { if (s->ch_mode == FLAC_CHMODE_LEFT_SIDE || s->ch_mode == FLAC_CHMODE_MID_SIDE) - s->curr_bps++; + bps++; } if (get_bits1(&s->gb)) { @@ -436,35 +418,35 @@ static inline int decode_subframe(FLACContext *s, int channel) int left = get_bits_left(&s->gb); wasted = 1; if ( left < 0 || - (left < s->curr_bps && !show_bits_long(&s->gb, left)) || - !show_bits_long(&s->gb, s->curr_bps)) { + (left < bps && !show_bits_long(&s->gb, left)) || + !show_bits_long(&s->gb, bps)) { av_log(s->avctx, AV_LOG_ERROR, "Invalid number of wasted bits > available bits (%d) - left=%d\n", - s->curr_bps, left); + bps, left); return AVERROR_INVALIDDATA; } while (!get_bits1(&s->gb)) wasted++; - s->curr_bps -= wasted; + bps -= wasted; } - if (s->curr_bps > 32) { + if (bps > 32) { av_log_missing_feature(s->avctx, "decorrelated bit depth > 32", 0); return -1; } //FIXME use av_log2 for types if (type == 0) { - tmp = get_sbits_long(&s->gb, s->curr_bps); + tmp = get_sbits_long(&s->gb, bps); for (i = 0; i < s->blocksize; i++) s->decoded[channel][i] = tmp; } else if (type == 1) { for (i = 0; i < s->blocksize; i++) - s->decoded[channel][i] = get_sbits_long(&s->gb, s->curr_bps); + s->decoded[channel][i] = get_sbits_long(&s->gb, bps); } else if ((type >= 8) && (type <= 12)) { - if (decode_subframe_fixed(s, channel, type & ~0x8) < 0) + if (decode_subframe_fixed(s, channel, type & ~0x8, bps) < 0) return -1; } else if (type >= 32) { - if (decode_subframe_lpc(s, channel, (type & ~0x20)+1) < 0) + if (decode_subframe_lpc(s, channel, (type & ~0x20)+1, bps) < 0) return -1; } else { av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n"); @@ -512,15 +494,7 @@ static int decode_frame(FLACContext *s) } s->bps = s->avctx->bits_per_raw_sample = fi.bps; - if (s->bps > 16) { - s->avctx->sample_fmt = AV_SAMPLE_FMT_S32; - s->sample_shift = 32 - s->bps; - s->is32 = 1; - } else { - s->avctx->sample_fmt = AV_SAMPLE_FMT_S16; - s->sample_shift = 16 - s->bps; - s->is32 = 0; - } + flac_set_bps(s); if (!s->max_blocksize) s->max_blocksize = FLAC_MAX_BLOCKSIZE; @@ -546,6 +520,7 @@ static int decode_frame(FLACContext *s) if (!s->got_streaminfo) { allocate_buffers(s); + ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt); s->got_streaminfo = 1; dump_headers(s->avctx, (FLACStreaminfo *)s); } @@ -572,9 +547,7 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; FLACContext *s = avctx->priv_data; - int i, j = 0, bytes_read = 0; - int16_t *samples_16; - int32_t *samples_32; + int bytes_read = 0; int ret; *got_frame_ptr = 0; @@ -614,42 +587,9 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - samples_16 = (int16_t *)s->frame.data[0]; - samples_32 = (int32_t *)s->frame.data[0]; - -#define DECORRELATE(left, right)\ - assert(s->channels == 2);\ - for (i = 0; i < s->blocksize; i++) {\ - int a= s->decoded[0][i];\ - int b= s->decoded[1][i];\ - if (s->is32) {\ - *samples_32++ = (left) << s->sample_shift;\ - *samples_32++ = (right) << s->sample_shift;\ - } else {\ - *samples_16++ = (left) << s->sample_shift;\ - *samples_16++ = (right) << s->sample_shift;\ - }\ - }\ - break; - - switch (s->ch_mode) { - case FLAC_CHMODE_INDEPENDENT: - for (j = 0; j < s->blocksize; j++) { - for (i = 0; i < s->channels; i++) { - if (s->is32) - *samples_32++ = s->decoded[i][j] << s->sample_shift; - else - *samples_16++ = s->decoded[i][j] << s->sample_shift; - } - } - break; - case FLAC_CHMODE_LEFT_SIDE: - DECORRELATE(a,a-b) - case FLAC_CHMODE_RIGHT_SIDE: - DECORRELATE(a+b,b) - case FLAC_CHMODE_MID_SIDE: - DECORRELATE( (a-=b>>1) + b, a) - } + + s->dsp.decorrelate[s->ch_mode](s->frame.data, s->decoded, s->channels, + s->blocksize, s->sample_shift); if (bytes_read > buf_size) { av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); diff --git a/libavcodec/flacdsp.c b/libavcodec/flacdsp.c new file mode 100644 index 0000000000..6c90e89d9b --- /dev/null +++ b/libavcodec/flacdsp.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012 Mans Rullgard <mans@mansr.com> + * + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/samplefmt.h" +#include "flacdsp.h" + +#define SAMPLE_SIZE 16 +#include "flacdsp_template.c" + +#undef SAMPLE_SIZE +#define SAMPLE_SIZE 32 +#include "flacdsp_template.c" + +static void flac_lpc_16_c(int32_t *decoded, const int coeffs[32], + int pred_order, int qlevel, int len) +{ + int i, j; + + for (i = pred_order; i < len - 1; i += 2) { + int c; + int d = decoded[i-pred_order]; + int s0 = 0, s1 = 0; + for (j = pred_order-1; j > 0; j--) { + c = coeffs[j]; + s0 += c*d; + d = decoded[i-j]; + s1 += c*d; + } + c = coeffs[0]; + s0 += c*d; + d = decoded[i] += s0 >> qlevel; + s1 += c*d; + decoded[i+1] += s1 >> qlevel; + } + if (i < len) { + int sum = 0; + for (j = 0; j < pred_order; j++) + sum += coeffs[j] * decoded[i-j-1]; + decoded[i] += sum >> qlevel; + } +} + +static void flac_lpc_32_c(int32_t *decoded, const int coeffs[32], + int pred_order, int qlevel, int len) +{ + int i, j; + + for (i = pred_order; i < len; i++) { + int64_t sum = 0; + for (j = 0; j < pred_order; j++) + sum += (int64_t)coeffs[j] * decoded[i-j-1]; + decoded[i] += sum >> qlevel; + } + +} + +av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt) +{ + switch (fmt) { + case AV_SAMPLE_FMT_S32: + c->decorrelate[0] = flac_decorrelate_indep_c_32; + c->decorrelate[1] = flac_decorrelate_ls_c_32; + c->decorrelate[2] = flac_decorrelate_rs_c_32; + c->decorrelate[3] = flac_decorrelate_ms_c_32; + c->lpc = flac_lpc_32_c; + break; + + case AV_SAMPLE_FMT_S16: + c->decorrelate[0] = flac_decorrelate_indep_c_16; + c->decorrelate[1] = flac_decorrelate_ls_c_16; + c->decorrelate[2] = flac_decorrelate_rs_c_16; + c->decorrelate[3] = flac_decorrelate_ms_c_16; + c->lpc = flac_lpc_16_c; + break; + } +} diff --git a/libavcodec/flacdsp.h b/libavcodec/flacdsp.h new file mode 100644 index 0000000000..e2abefb7f5 --- /dev/null +++ b/libavcodec/flacdsp.h @@ -0,0 +1,34 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_FLACDSP_H +#define AVCODEC_FLACDSP_H + +#include <stdint.h> +#include "libavutil/samplefmt.h" + +typedef struct FLACDSPContext { + void (*decorrelate[4])(uint8_t **out, int32_t **in, int channels, + int len, int shift); + void (*lpc)(int32_t *samples, const int coeffs[32], int order, + int qlevel, int len); +} FLACDSPContext; + +void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt); + +#endif /* AVCODEC_FLACDSP_H */ diff --git a/libavcodec/flacdsp_template.c b/libavcodec/flacdsp_template.c new file mode 100644 index 0000000000..808b20d41d --- /dev/null +++ b/libavcodec/flacdsp_template.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2012 Mans Rullgard <mans@mansr.com> + * + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdint.h> + +#undef FUNC +#undef sample + +#if SAMPLE_SIZE == 32 +# define FUNC(n) n ## _32 +# define sample int32_t +#else +# define FUNC(n) n ## _16 +# define sample int16_t +#endif + +static void FUNC(flac_decorrelate_indep_c)(uint8_t **out, int32_t **in, + int channels, int len, int shift) +{ + sample *samples = (sample *) out[0]; + int i, j; + + for (j = 0; j < len; j++) + for (i = 0; i < channels; i++) + *samples++ = in[i][j] << shift; +} + +static void FUNC(flac_decorrelate_ls_c)(uint8_t **out, int32_t **in, + int channels, int len, int shift) +{ + sample *samples = (sample *) out[0]; + int i; + + for (i = 0; i < len; i++) { + int a = in[0][i]; + int b = in[1][i]; + *samples++ = a << shift; + *samples++ = (a - b) << shift; + } +} + +static void FUNC(flac_decorrelate_rs_c)(uint8_t **out, int32_t **in, + int channels, int len, int shift) +{ + sample *samples = (sample *) out[0]; + int i; + + for (i = 0; i < len; i++) { + int a = in[0][i]; + int b = in[1][i]; + *samples++ = (a + b) << shift; + *samples++ = b << shift; + } +} + +static void FUNC(flac_decorrelate_ms_c)(uint8_t **out, int32_t **in, + int channels, int len, int shift) +{ + sample *samples = (sample *) out[0]; + int i; + + for (i = 0; i < len; i++) { + int a = in[0][i]; + int b = in[1][i]; + a -= b >> 1; + *samples++ = (a + b) << shift; + *samples++ = a << shift; + } +} diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c index b900cc9998..31ab740b59 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -53,6 +53,7 @@ typedef struct CompressionOptions { int prediction_order_method; int min_partition_order; int max_partition_order; + int ch_mode; } CompressionOptions; typedef struct RiceContext { @@ -1022,15 +1023,8 @@ static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n) for (i = 1; i < 4; i++) if (score[i] < score[best]) best = i; - if (best == 0) { - return FLAC_CHMODE_INDEPENDENT; - } else if (best == 1) { - return FLAC_CHMODE_LEFT_SIDE; - } else if (best == 2) { - return FLAC_CHMODE_RIGHT_SIDE; - } else { - return FLAC_CHMODE_MID_SIDE; - } + + return best; } @@ -1053,7 +1047,10 @@ static void channel_decorrelation(FlacEncodeContext *s) return; } - frame->ch_mode = estimate_stereo_mode(left, right, n); + if (s->options.ch_mode < 0) + frame->ch_mode = estimate_stereo_mode(left, right, n); + else + frame->ch_mode = s->options.ch_mode; /* perform decorrelation and adjust bits-per-sample */ if (frame->ch_mode == FLAC_CHMODE_INDEPENDENT) @@ -1099,7 +1096,7 @@ static void write_frame_header(FlacEncodeContext *s) if (frame->ch_mode == FLAC_CHMODE_INDEPENDENT) put_bits(&s->pb, 4, s->channels-1); else - put_bits(&s->pb, 4, frame->ch_mode); + put_bits(&s->pb, 4, frame->ch_mode + FLAC_MAX_CHANNELS - 1); put_bits(&s->pb, 3, 4); /* bits-per-sample code */ put_bits(&s->pb, 1, 0); @@ -1308,6 +1305,12 @@ static const AVOption options[] = { { "8level", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_8LEVEL }, INT_MIN, INT_MAX, FLAGS, "predm" }, { "search", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_SEARCH }, INT_MIN, INT_MAX, FLAGS, "predm" }, { "log", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_LOG }, INT_MIN, INT_MAX, FLAGS, "predm" }, +{ "ch_mode", "Stereo decorrelation mode", offsetof(FlacEncodeContext, options.ch_mode), AV_OPT_TYPE_INT, { .dbl = -1 }, -1, FLAC_CHMODE_MID_SIDE, FLAGS, "ch_mode" }, +{ "auto", NULL, 0, AV_OPT_TYPE_CONST, { .dbl = -1 }, INT_MIN, INT_MAX, FLAGS, "ch_mode" }, +{ "indep", NULL, 0, AV_OPT_TYPE_CONST, { .dbl = FLAC_CHMODE_INDEPENDENT }, INT_MIN, INT_MAX, FLAGS, "ch_mode" }, +{ "left_side", NULL, 0, AV_OPT_TYPE_CONST, { .dbl = FLAC_CHMODE_LEFT_SIDE }, INT_MIN, INT_MAX, FLAGS, "ch_mode" }, +{ "right_side", NULL, 0, AV_OPT_TYPE_CONST, { .dbl = FLAC_CHMODE_RIGHT_SIDE }, INT_MIN, INT_MAX, FLAGS, "ch_mode" }, +{ "mid_side", NULL, 0, AV_OPT_TYPE_CONST, { .dbl = FLAC_CHMODE_MID_SIDE }, INT_MIN, INT_MAX, FLAGS, "ch_mode" }, { NULL }, }; diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 8710c650d6..a3c55d048f 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -775,6 +775,11 @@ av_cold int ff_MPV_common_init(MpegEncContext *s) if(s->avctx->noise_reduction){ FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset, 2 * 64 * sizeof(uint16_t), fail) } + + FF_ALLOC_OR_GOTO(s->avctx, s->cplx_tab, + mb_array_size * sizeof(float), fail); + FF_ALLOC_OR_GOTO(s->avctx, s->bits_tab, + mb_array_size * sizeof(float), fail); } s->picture_count = MAX_PICTURE_COUNT * FFMAX(1, s->avctx->thread_count); @@ -784,7 +789,10 @@ av_cold int ff_MPV_common_init(MpegEncContext *s) avcodec_get_frame_defaults(&s->picture[i].f); } - FF_ALLOCZ_OR_GOTO(s->avctx, s->error_status_table, mb_array_size*sizeof(uint8_t), fail) + FF_ALLOC_OR_GOTO(s->avctx, s->er_temp_buffer, + mb_array_size * sizeof(uint8_t), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->error_status_table, + mb_array_size * sizeof(uint8_t), fail); if(s->codec_id==CODEC_ID_MPEG4 || (s->flags & CODEC_FLAG_INTERLACED_ME)){ /* interlaced direct mode decoding tables */ @@ -923,6 +931,7 @@ void ff_MPV_common_end(MpegEncContext *s) av_freep(&s->avctx->stats_out); av_freep(&s->ac_stats); av_freep(&s->error_status_table); + av_freep(&s->er_temp_buffer); av_freep(&s->mb_index2xy); av_freep(&s->lambda_table); if(s->q_chroma_intra_matrix != s->q_intra_matrix ) av_freep(&s->q_chroma_intra_matrix); @@ -936,6 +945,8 @@ void ff_MPV_common_end(MpegEncContext *s) av_freep(&s->input_picture); av_freep(&s->reordered_input_picture); av_freep(&s->dct_offset); + av_freep(&s->cplx_tab); + av_freep(&s->bits_tab); if (s->picture && !s->avctx->internal->is_copy) { for (i = 0; i < s->picture_count; i++) { diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 50b86f5b99..89160d2412 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -705,6 +705,12 @@ typedef struct MpegEncContext { int mpv_flags; ///< flags set by private options int quantizer_noise_shaping; + + /* error resilience stuff */ + uint8_t *er_temp_buffer; + + /* temp buffers for rate control */ + float *cplx_tab, *bits_tab; } MpegEncContext; #define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \ diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c index c4624f9e3c..197c807ef2 100644 --- a/libavcodec/ratecontrol.c +++ b/libavcodec/ratecontrol.c @@ -535,8 +535,8 @@ static void adaptive_quantization(MpegEncContext *s, double q){ const float border_masking = s->avctx->border_masking; float bits_sum= 0.0; float cplx_sum= 0.0; - float *cplx_tab = av_malloc(s->mb_num * sizeof(*cplx_tab)); - float *bits_tab = av_malloc(s->mb_num * sizeof(*bits_tab)); + float *cplx_tab = s->cplx_tab; + float *bits_tab = s->bits_tab; const int qmin= s->avctx->mb_lmin; const int qmax= s->avctx->mb_lmax; Picture * const pic= &s->current_picture; @@ -633,9 +633,6 @@ static void adaptive_quantization(MpegEncContext *s, double q){ //printf("%2d%3d ", intq, ff_sqrt(s->mc_mb_var[i])); s->lambda_table[mb_xy]= intq; } - - av_free(cplx_tab); - av_free(bits_tab); } void ff_get_2pass_fcode(MpegEncContext *s){ diff --git a/libavcodec/version.h b/libavcodec/version.h index 8709230c24..5cbd41bac8 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -41,9 +41,11 @@ #define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) /** - * These FF_API_* defines are not part of the public API. - * They may change, break or disappear at any time. + * FF_API_* defines may be placed below to indicate public API that will be + * dropped at a future version bump. The defines themselves are not part of + * the public API and may change, break or disappear at any time. */ + #ifndef FF_API_REQUEST_CHANNELS #define FF_API_REQUEST_CHANNELS (LIBAVCODEC_VERSION_MAJOR < 55) #endif diff --git a/libavcodec/x86/dsputilenc_mmx.c b/libavcodec/x86/dsputilenc_mmx.c index 00e0a3fc37..de365ee400 100644 --- a/libavcodec/x86/dsputilenc_mmx.c +++ b/libavcodec/x86/dsputilenc_mmx.c @@ -1147,11 +1147,11 @@ void ff_dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx) if (mm_flags & AV_CPU_FLAG_MMX2) { - c->sum_abs_dctelem= sum_abs_dctelem_mmx2; #if HAVE_YASM c->hadamard8_diff[0]= ff_hadamard8_diff16_mmx2; c->hadamard8_diff[1]= ff_hadamard8_diff_mmx2; #endif + c->sum_abs_dctelem= sum_abs_dctelem_mmx2; c->vsad[4]= vsad_intra16_mmx2; if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ diff --git a/libavcodec/x86/vp8dsp-init.c b/libavcodec/x86/vp8dsp-init.c index f4f6e92877..3e550b1543 100644 --- a/libavcodec/x86/vp8dsp-init.c +++ b/libavcodec/x86/vp8dsp-init.c @@ -401,11 +401,13 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse2; +#if ARCH_X86_64 || HAVE_ALIGNED_STACK c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_sse2; c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_sse2; c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_sse2; c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_sse2; +#endif } if (mm_flags & AV_CPU_FLAG_SSSE3) { @@ -419,6 +421,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_ssse3; c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_ssse3; +#if ARCH_X86_64 || HAVE_ALIGNED_STACK c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_ssse3; c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_ssse3; c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_ssse3; @@ -428,14 +431,17 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_ssse3; c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_ssse3; c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_ssse3; +#endif } if (mm_flags & AV_CPU_FLAG_SSE4) { c->vp8_idct_dc_add = ff_vp8_idct_dc_add_sse4; c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse4; +#if ARCH_X86_64 || HAVE_ALIGNED_STACK c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_sse4; c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_sse4; +#endif } #endif } |