From 2968bedf129558024ea87a1aabc4aa2d3a5bcb6e Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 23 Jul 2011 15:46:35 +0200 Subject: [PATCH 1/9] bink: make IDCT take 32-bit input Since IDCT transforming 32-bit input to 8-bit output is unusual and unpractical for most codecs, move Bink IDCT into separate context. Get rid of an additional permutation table while at it since SIMD support for Bink IDCT is unlikely to be implemented in foreseeable future. Quantisation tables also have to change type to signed for proper dequantisation of DCT coefficients. Signed-off-by: Mans Rullgard --- libavcodec/Makefile | 2 +- libavcodec/bink.c | 58 ++++++++++++++-------------- libavcodec/binkdata.h | 4 +- libavcodec/{binkidct.c => binkdsp.c} | 21 ++++++---- libavcodec/binkdsp.h | 39 +++++++++++++++++++ libavcodec/dsputil.c | 5 --- 6 files changed, 86 insertions(+), 43 deletions(-) rename libavcodec/{binkidct.c => binkdsp.c} (86%) create mode 100644 libavcodec/binkdsp.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 99ecbbf567..36e07a9fc1 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -89,7 +89,7 @@ OBJS-$(CONFIG_AURA2_DECODER) += aura.o OBJS-$(CONFIG_AVS_DECODER) += avs.o OBJS-$(CONFIG_BETHSOFTVID_DECODER) += bethsoftvideo.o OBJS-$(CONFIG_BFI_DECODER) += bfi.o -OBJS-$(CONFIG_BINK_DECODER) += bink.o binkidct.o +OBJS-$(CONFIG_BINK_DECODER) += bink.o binkdsp.o OBJS-$(CONFIG_BINKAUDIO_DCT_DECODER) += binkaudio.o wma.o OBJS-$(CONFIG_BINKAUDIO_RDFT_DECODER) += binkaudio.o wma.o OBJS-$(CONFIG_BMP_DECODER) += bmp.o msrledec.o diff --git a/libavcodec/bink.c b/libavcodec/bink.c index e085aa54e2..8e989d9dd9 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -24,6 +24,7 @@ #include "avcodec.h" #include "dsputil.h" #include "binkdata.h" +#include "binkdsp.h" #include "mathops.h" #define ALT_BITSTREAM_READER_LE @@ -60,8 +61,8 @@ static const int binkb_bundle_signed[BINKB_NB_SRC] = { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0 }; -static uint32_t binkb_intra_quant[16][64]; -static uint32_t binkb_inter_quant[16][64]; +static int32_t binkb_intra_quant[16][64]; +static int32_t binkb_inter_quant[16][64]; /** * IDs for different data types used in Bink video codec @@ -109,11 +110,11 @@ typedef struct Bundle { typedef struct BinkContext { AVCodecContext *avctx; DSPContext dsp; + BinkDSPContext bdsp; AVFrame pic, last; int version; ///< internal Bink file version int has_alpha; int swap_planes; - ScanTable scantable; ///< permutated scantable for DCT coeffs decoding Bundle bundle[BINKB_NB_SRC]; ///< bundles for decoding all data types Tree col_high[16]; ///< trees for decoding high nibble in "colours" data type @@ -580,8 +581,8 @@ static inline int binkb_get_value(BinkContext *c, int bundle_num) * @param quant_matrices quantization matrices * @return 0 for success, negative value in other cases */ -static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *scan, - const uint32_t quant_matrices[16][64], int q) +static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t *scan, + const int32_t quant_matrices[16][64], int q) { int coef_list[128]; int mode_list[128]; @@ -590,7 +591,7 @@ static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t * int coef_count = 0; int coef_idx[64]; int quant_idx; - const uint32_t *quant; + const int32_t *quant; coef_list[list_end] = 4; mode_list[list_end++] = 0; coef_list[list_end] = 24; mode_list[list_end++] = 0; @@ -791,6 +792,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, const uint8_t *scan; int xoff, yoff; LOCAL_ALIGNED_16(DCTELEM, block, [64]); + LOCAL_ALIGNED_16(int32_t, dctblock, [64]); int coordmap[64]; int ybias = is_key ? -15 : 0; int qp; @@ -845,11 +847,11 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, dst[coordmap[*scan++]] = binkb_get_value(c, BINKB_SRC_COLORS); break; case 2: - c->dsp.clear_block(block); - block[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC); + memset(dctblock, 0, sizeof(*dctblock) * 64); + dctblock[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC); qp = binkb_get_value(c, BINKB_SRC_INTRA_Q); - read_dct_coeffs(gb, block, c->scantable.permutated, binkb_intra_quant, qp); - c->dsp.idct_put(dst, stride, block); + read_dct_coeffs(gb, dctblock, bink_scan, binkb_intra_quant, qp); + c->bdsp.idct_put(dst, stride, dctblock); break; case 3: xoff = binkb_get_value(c, BINKB_SRC_X_OFF); @@ -878,11 +880,11 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, } else { put_pixels8x8_overlapped(dst, ref, stride); } - c->dsp.clear_block(block); - block[0] = binkb_get_value(c, BINKB_SRC_INTER_DC); + memset(dctblock, 0, sizeof(*dctblock) * 64); + dctblock[0] = binkb_get_value(c, BINKB_SRC_INTER_DC); qp = binkb_get_value(c, BINKB_SRC_INTER_Q); - read_dct_coeffs(gb, block, c->scantable.permutated, binkb_inter_quant, qp); - c->dsp.idct_add(dst, stride, block); + read_dct_coeffs(gb, dctblock, bink_scan, binkb_inter_quant, qp); + c->bdsp.idct_add(dst, stride, dctblock); break; case 5: v = binkb_get_value(c, BINKB_SRC_COLORS); @@ -937,6 +939,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, int xoff, yoff; LOCAL_ALIGNED_16(DCTELEM, block, [64]); LOCAL_ALIGNED_16(uint8_t, ublock, [64]); + LOCAL_ALIGNED_16(int32_t, dctblock, [64]); int coordmap[64]; const int stride = c->pic.linesize[plane_idx]; @@ -1019,11 +1022,10 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, ublock[*scan++] = get_value(c, BINK_SRC_COLORS); break; case INTRA_BLOCK: - c->dsp.clear_block(block); - block[0] = get_value(c, BINK_SRC_INTRA_DC); - read_dct_coeffs(gb, block, c->scantable.permutated, bink_intra_quant, -1); - c->dsp.idct(block); - c->dsp.put_pixels_nonclamped(block, ublock, 8); + memset(dctblock, 0, sizeof(*dctblock) * 64); + dctblock[0] = get_value(c, BINK_SRC_INTRA_DC); + read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1); + c->bdsp.idct_put(ublock, 8, dctblock); break; case FILL_BLOCK: v = get_value(c, BINK_SRC_COLORS); @@ -1103,10 +1105,10 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, c->dsp.add_pixels8(dst, block, stride); break; case INTRA_BLOCK: - c->dsp.clear_block(block); - block[0] = get_value(c, BINK_SRC_INTRA_DC); - read_dct_coeffs(gb, block, c->scantable.permutated, bink_intra_quant, -1); - c->dsp.idct_put(dst, stride, block); + memset(dctblock, 0, sizeof(*dctblock) * 64); + dctblock[0] = get_value(c, BINK_SRC_INTRA_DC); + read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1); + c->bdsp.idct_put(dst, stride, dctblock); break; case FILL_BLOCK: v = get_value(c, BINK_SRC_COLORS); @@ -1117,10 +1119,10 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, yoff = get_value(c, BINK_SRC_Y_OFF); ref = prev + xoff + yoff * stride; c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); - c->dsp.clear_block(block); - block[0] = get_value(c, BINK_SRC_INTER_DC); - read_dct_coeffs(gb, block, c->scantable.permutated, bink_inter_quant, -1); - c->dsp.idct_add(dst, stride, block); + memset(dctblock, 0, sizeof(*dctblock) * 64); + dctblock[0] = get_value(c, BINK_SRC_INTER_DC); + read_dct_coeffs(gb, dctblock, bink_scan, bink_inter_quant, -1); + c->bdsp.idct_add(dst, stride, dctblock); break; case PATTERN_BLOCK: for (i = 0; i < 2; i++) @@ -1288,7 +1290,7 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->idct_algo = FF_IDCT_BINK; dsputil_init(&c->dsp, avctx); - ff_init_scantable(c->dsp.idct_permutation, &c->scantable, bink_scan); + ff_binkdsp_init(&c->bdsp); init_bundles(c); diff --git a/libavcodec/binkdata.h b/libavcodec/binkdata.h index db289ad3a1..60f0a59b49 100644 --- a/libavcodec/binkdata.h +++ b/libavcodec/binkdata.h @@ -285,7 +285,7 @@ static const uint8_t bink_patterns[16][64] = { } }; -static const uint32_t bink_intra_quant[16][64] = { +static const int32_t bink_intra_quant[16][64] = { { 0x010000, 0x016315, 0x01E83D, 0x02A535, 0x014E7B, 0x016577, 0x02F1E6, 0x02724C, 0x010000, 0x00EEDA, 0x024102, 0x017F9B, 0x00BE80, 0x00611E, 0x01083C, 0x00A552, @@ -448,7 +448,7 @@ static const uint32_t bink_intra_quant[16][64] = { }, }; -static const uint32_t bink_inter_quant[16][64] = { +static const int32_t bink_inter_quant[16][64] = { { 0x010000, 0x017946, 0x01A5A9, 0x0248DC, 0x016363, 0x0152A7, 0x0243EC, 0x0209EA, 0x012000, 0x00E248, 0x01BBDA, 0x015CBC, 0x00A486, 0x0053E0, 0x00F036, 0x008095, diff --git a/libavcodec/binkidct.c b/libavcodec/binkdsp.c similarity index 86% rename from libavcodec/binkidct.c rename to libavcodec/binkdsp.c index 2326a616d5..109906f262 100644 --- a/libavcodec/binkidct.c +++ b/libavcodec/binkdsp.c @@ -1,5 +1,5 @@ /* - * Bink IDCT algorithm + * Bink DSP routines * Copyright (c) 2009 Kostya Shishkov * * This file is part of Libav. @@ -21,10 +21,11 @@ /** * @file - * Bink IDCT algorithm + * Bink DSP routines */ #include "dsputil.h" +#include "binkdsp.h" #define A1 2896 /* (1/sqrt(2))<<12 */ #define A2 2217 @@ -62,7 +63,7 @@ #define MUNGE_ROW(x) (((x) + 0x7F)>>8) #define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_ROW,src) -static inline void bink_idct_col(int *dest, const DCTELEM *src) +static inline void bink_idct_col(int *dest, const int32_t *src) { if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) { dest[0] = @@ -78,7 +79,7 @@ static inline void bink_idct_col(int *dest, const DCTELEM *src) } } -void ff_bink_idct_c(DCTELEM *block) +static void bink_idct_c(int32_t *block) { int i; int temp[64]; @@ -90,17 +91,17 @@ void ff_bink_idct_c(DCTELEM *block) } } -void ff_bink_idct_add_c(uint8_t *dest, int linesize, DCTELEM *block) +static void bink_idct_add_c(uint8_t *dest, int linesize, int32_t *block) { int i, j; - ff_bink_idct_c(block); + bink_idct_c(block); for (i = 0; i < 8; i++, dest += linesize, block += 8) for (j = 0; j < 8; j++) dest[j] += block[j]; } -void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block) +static void bink_idct_put_c(uint8_t *dest, int linesize, int32_t *block) { int i; int temp[64]; @@ -110,3 +111,9 @@ void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block) IDCT_ROW( (&dest[i*linesize]), (&temp[8*i]) ); } } + +void ff_binkdsp_init(BinkDSPContext *c) +{ + c->idct_add = bink_idct_add_c; + c->idct_put = bink_idct_put_c; +} diff --git a/libavcodec/binkdsp.h b/libavcodec/binkdsp.h new file mode 100644 index 0000000000..8253ab3004 --- /dev/null +++ b/libavcodec/binkdsp.h @@ -0,0 +1,39 @@ +/* + * Bink DSP routines + * Copyright (c) 2009 Kostya Shishkov + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Bink DSP routines + */ + +#ifndef AVCODEC_BINKDSP_H +#define AVCODEC_BINKDSP_H + +#include "dsputil.h" + +typedef struct BinkDSPContext { + void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, int32_t *block/*align 16*/); + void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, int32_t *block/*align 16*/); +} BinkDSPContext; + +void ff_binkdsp_init(BinkDSPContext *c); + +#endif /* AVCODEC_BINKDSP_H */ diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index 09e58f46d2..04c2ff67a4 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -2894,11 +2894,6 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) }else if(CONFIG_EATGQ_DECODER && avctx->idct_algo==FF_IDCT_EA) { c->idct_put= ff_ea_idct_put_c; c->idct_permutation_type= FF_NO_IDCT_PERM; - }else if(CONFIG_BINK_DECODER && avctx->idct_algo==FF_IDCT_BINK) { - c->idct = ff_bink_idct_c; - c->idct_add = ff_bink_idct_add_c; - c->idct_put = ff_bink_idct_put_c; - c->idct_permutation_type = FF_NO_IDCT_PERM; }else{ //accurate/default c->idct_put = ff_simple_idct_put_8; c->idct_add = ff_simple_idct_add_8; From cbd58a872d343f5996ed7ab917c8839dbfd99eaa Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 27 Jul 2011 14:47:56 +0100 Subject: [PATCH 2/9] dsputil: remove some unused functions Signed-off-by: Mans Rullgard --- libavcodec/arm/dsputil_init_neon.c | 14 ---- libavcodec/arm/dsputil_neon.S | 104 ----------------------------- libavcodec/dsputil.c | 72 -------------------- libavcodec/dsputil.h | 27 -------- 4 files changed, 217 deletions(-) diff --git a/libavcodec/arm/dsputil_init_neon.c b/libavcodec/arm/dsputil_init_neon.c index 238fdae41f..101bd055a1 100644 --- a/libavcodec/arm/dsputil_init_neon.c +++ b/libavcodec/arm/dsputil_init_neon.c @@ -143,14 +143,6 @@ void ff_vector_fmul_window_neon(float *dst, const float *src0, const float *src1, const float *win, int len); void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul, int len); -void ff_vector_fmul_sv_scalar_2_neon(float *dst, const float *src, - const float **vp, float mul, int len); -void ff_vector_fmul_sv_scalar_4_neon(float *dst, const float *src, - const float **vp, float mul, int len); -void ff_sv_fmul_scalar_2_neon(float *dst, const float **vp, float mul, - int len); -void ff_sv_fmul_scalar_4_neon(float *dst, const float **vp, float mul, - int len); void ff_butterflies_float_neon(float *v1, float *v2, int len); float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len); void ff_vector_fmul_reverse_neon(float *dst, const float *src0, @@ -320,12 +312,6 @@ void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx) c->vector_clipf = ff_vector_clipf_neon; c->vector_clip_int32 = ff_vector_clip_int32_neon; - c->vector_fmul_sv_scalar[0] = ff_vector_fmul_sv_scalar_2_neon; - c->vector_fmul_sv_scalar[1] = ff_vector_fmul_sv_scalar_4_neon; - - c->sv_fmul_scalar[0] = ff_sv_fmul_scalar_2_neon; - c->sv_fmul_scalar[1] = ff_sv_fmul_scalar_4_neon; - if (CONFIG_VORBIS_DECODER) c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_neon; diff --git a/libavcodec/arm/dsputil_neon.S b/libavcodec/arm/dsputil_neon.S index 3b9b542a68..aef8a129ee 100644 --- a/libavcodec/arm/dsputil_neon.S +++ b/libavcodec/arm/dsputil_neon.S @@ -587,110 +587,6 @@ NOVFP vdup.32 q8, r2 .unreq len endfunc -function ff_vector_fmul_sv_scalar_2_neon, export=1 -VFP vdup.32 d16, d0[0] -NOVFP vdup.32 d16, r3 -NOVFP ldr r3, [sp] - vld1.32 {d0},[r1,:64]! - vld1.32 {d1},[r1,:64]! -1: subs r3, r3, #4 - vmul.f32 d4, d0, d16 - vmul.f32 d5, d1, d16 - ldr r12, [r2], #4 - vld1.32 {d2},[r12,:64] - ldr r12, [r2], #4 - vld1.32 {d3},[r12,:64] - vmul.f32 d4, d4, d2 - vmul.f32 d5, d5, d3 - beq 2f - vld1.32 {d0},[r1,:64]! - vld1.32 {d1},[r1,:64]! - vst1.32 {d4},[r0,:64]! - vst1.32 {d5},[r0,:64]! - b 1b -2: vst1.32 {d4},[r0,:64]! - vst1.32 {d5},[r0,:64]! - bx lr -endfunc - -function ff_vector_fmul_sv_scalar_4_neon, export=1 -VFP vdup.32 q10, d0[0] -NOVFP vdup.32 q10, r3 -NOVFP ldr r3, [sp] - push {lr} - bics lr, r3, #7 - beq 3f - vld1.32 {q0},[r1,:128]! - vld1.32 {q2},[r1,:128]! -1: ldr r12, [r2], #4 - vld1.32 {q1},[r12,:128] - ldr r12, [r2], #4 - vld1.32 {q3},[r12,:128] - vmul.f32 q8, q0, q10 - vmul.f32 q8, q8, q1 - vmul.f32 q9, q2, q10 - vmul.f32 q9, q9, q3 - subs lr, lr, #8 - beq 2f - vld1.32 {q0},[r1,:128]! - vld1.32 {q2},[r1,:128]! - vst1.32 {q8},[r0,:128]! - vst1.32 {q9},[r0,:128]! - b 1b -2: vst1.32 {q8},[r0,:128]! - vst1.32 {q9},[r0,:128]! - ands r3, r3, #7 - it eq - popeq {pc} -3: vld1.32 {q0},[r1,:128]! - ldr r12, [r2], #4 - vld1.32 {q1},[r12,:128] - vmul.f32 q0, q0, q10 - vmul.f32 q0, q0, q1 - vst1.32 {q0},[r0,:128]! - subs r3, r3, #4 - bgt 3b - pop {pc} -endfunc - -function ff_sv_fmul_scalar_2_neon, export=1 -VFP len .req r2 -NOVFP len .req r3 -VFP vdup.32 q8, d0[0] -NOVFP vdup.32 q8, r2 - ldr r12, [r1], #4 - vld1.32 {d0},[r12,:64] - ldr r12, [r1], #4 - vld1.32 {d1},[r12,:64] -1: vmul.f32 q1, q0, q8 - subs len, len, #4 - beq 2f - ldr r12, [r1], #4 - vld1.32 {d0},[r12,:64] - ldr r12, [r1], #4 - vld1.32 {d1},[r12,:64] - vst1.32 {q1},[r0,:128]! - b 1b -2: vst1.32 {q1},[r0,:128]! - bx lr - .unreq len -endfunc - -function ff_sv_fmul_scalar_4_neon, export=1 -VFP len .req r2 -NOVFP len .req r3 -VFP vdup.32 q8, d0[0] -NOVFP vdup.32 q8, r2 -1: ldr r12, [r1], #4 - vld1.32 {q0},[r12,:128] - vmul.f32 q0, q0, q8 - vst1.32 {q0},[r0,:128]! - subs len, len, #4 - bgt 1b - bx lr - .unreq len -endfunc - function ff_butterflies_float_neon, export=1 1: vld1.32 {q0},[r0,:128] vld1.32 {q1},[r1,:128] diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index 04c2ff67a4..e1be534585 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -405,27 +405,6 @@ void ff_put_signed_pixels_clamped_c(const DCTELEM *block, } } -static void put_pixels_nonclamped_c(const DCTELEM *block, uint8_t *restrict pixels, - int line_size) -{ - int i; - - /* read the pixels */ - for(i=0;i<8;i++) { - pixels[0] = block[0]; - pixels[1] = block[1]; - pixels[2] = block[2]; - pixels[3] = block[3]; - pixels[4] = block[4]; - pixels[5] = block[5]; - pixels[6] = block[6]; - pixels[7] = block[7]; - - pixels += line_size; - block += 8; - } -} - void ff_add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, int line_size) { @@ -2492,50 +2471,6 @@ static void vector_fmul_scalar_c(float *dst, const float *src, float mul, dst[i] = src[i] * mul; } -static void vector_fmul_sv_scalar_2_c(float *dst, const float *src, - const float **sv, float mul, int len) -{ - int i; - for (i = 0; i < len; i += 2, sv++) { - dst[i ] = src[i ] * sv[0][0] * mul; - dst[i+1] = src[i+1] * sv[0][1] * mul; - } -} - -static void vector_fmul_sv_scalar_4_c(float *dst, const float *src, - const float **sv, float mul, int len) -{ - int i; - for (i = 0; i < len; i += 4, sv++) { - dst[i ] = src[i ] * sv[0][0] * mul; - dst[i+1] = src[i+1] * sv[0][1] * mul; - dst[i+2] = src[i+2] * sv[0][2] * mul; - dst[i+3] = src[i+3] * sv[0][3] * mul; - } -} - -static void sv_fmul_scalar_2_c(float *dst, const float **sv, float mul, - int len) -{ - int i; - for (i = 0; i < len; i += 2, sv++) { - dst[i ] = sv[0][0] * mul; - dst[i+1] = sv[0][1] * mul; - } -} - -static void sv_fmul_scalar_4_c(float *dst, const float **sv, float mul, - int len) -{ - int i; - for (i = 0; i < len; i += 4, sv++) { - dst[i ] = sv[0][0] * mul; - dst[i+1] = sv[0][1] * mul; - dst[i+2] = sv[0][2] * mul; - dst[i+3] = sv[0][3] * mul; - } -} - static void butterflies_float_c(float *restrict v1, float *restrict v2, int len) { @@ -2906,7 +2841,6 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) c->diff_pixels = diff_pixels_c; c->put_pixels_clamped = ff_put_pixels_clamped_c; c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_c; - c->put_pixels_nonclamped = put_pixels_nonclamped_c; c->add_pixels_clamped = ff_add_pixels_clamped_c; c->sum_abs_dctelem = sum_abs_dctelem_c; c->gmc1 = gmc1_c; @@ -3088,12 +3022,6 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) c->butterflies_float = butterflies_float_c; c->vector_fmul_scalar = vector_fmul_scalar_c; - c->vector_fmul_sv_scalar[0] = vector_fmul_sv_scalar_2_c; - c->vector_fmul_sv_scalar[1] = vector_fmul_sv_scalar_4_c; - - c->sv_fmul_scalar[0] = sv_fmul_scalar_2_c; - c->sv_fmul_scalar[1] = sv_fmul_scalar_4_c; - c->shrink[0]= av_image_copy_plane; c->shrink[1]= ff_shrink22; c->shrink[2]= ff_shrink44; diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index 0ba36d77ec..b6f0607b08 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -229,7 +229,6 @@ typedef struct DSPContext { void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride); void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); void (*put_signed_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); - void (*put_pixels_nonclamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); void (*add_pixels8)(uint8_t *pixels, DCTELEM *block, int line_size); void (*add_pixels4)(uint8_t *pixels, DCTELEM *block, int line_size); @@ -423,32 +422,6 @@ typedef struct DSPContext { */ void (*vector_fmul_scalar)(float *dst, const float *src, float mul, int len); - /** - * Multiply a vector of floats by concatenated short vectors of - * floats and by a scalar float. Source and destination vectors - * must overlap exactly or not at all. - * [0]: short vectors of length 2, 8-byte aligned - * [1]: short vectors of length 4, 16-byte aligned - * @param dst output vector, 16-byte aligned - * @param src input vector, 16-byte aligned - * @param sv array of pointers to short vectors - * @param mul scalar value - * @param len number of elements in src and dst, multiple of 4 - */ - void (*vector_fmul_sv_scalar[2])(float *dst, const float *src, - const float **sv, float mul, int len); - /** - * Multiply short vectors of floats by a scalar float, store - * concatenated result. - * [0]: short vectors of length 2, 8-byte aligned - * [1]: short vectors of length 4, 16-byte aligned - * @param dst output vector, 16-byte aligned - * @param sv array of pointers to short vectors - * @param mul scalar value - * @param len number of output elements, multiple of 4 - */ - void (*sv_fmul_scalar[2])(float *dst, const float **sv, - float mul, int len); /** * Calculate the scalar product of two vectors of floats. * @param v1 first vector, 16-byte aligned From 1b3539d4534f9877b463fb8b7fa56b7d20dd1338 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 27 Jul 2011 15:47:02 +0100 Subject: [PATCH 3/9] dsputil: move a bink-only function to binkdsp Signed-off-by: Mans Rullgard --- libavcodec/bink.c | 2 +- libavcodec/binkdsp.c | 17 +++++++++++++++++ libavcodec/binkdsp.h | 1 + libavcodec/dsputil.c | 17 ----------------- libavcodec/dsputil.h | 1 - 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/libavcodec/bink.c b/libavcodec/bink.c index 8e989d9dd9..8f42ff8bea 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -1050,7 +1050,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, return -1; } if (blk != FILL_BLOCK) - c->dsp.scale_block(ublock, dst, stride); + c->bdsp.scale_block(ublock, dst, stride); bx++; dst += 8; prev += 8; diff --git a/libavcodec/binkdsp.c b/libavcodec/binkdsp.c index 109906f262..1f7855b30b 100644 --- a/libavcodec/binkdsp.c +++ b/libavcodec/binkdsp.c @@ -112,8 +112,25 @@ static void bink_idct_put_c(uint8_t *dest, int linesize, int32_t *block) } } +static void scale_block_c(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align 8*/, int linesize) +{ + int i, j; + uint16_t *dst1 = (uint16_t *) dst; + uint16_t *dst2 = (uint16_t *)(dst + linesize); + + for (j = 0; j < 8; j++) { + for (i = 0; i < 8; i++) { + dst1[i] = dst2[i] = src[i] * 0x0101; + } + src += 8; + dst1 += linesize; + dst2 += linesize; + } +} + void ff_binkdsp_init(BinkDSPContext *c) { c->idct_add = bink_idct_add_c; c->idct_put = bink_idct_put_c; + c->scale_block = scale_block_c; } diff --git a/libavcodec/binkdsp.h b/libavcodec/binkdsp.h index 8253ab3004..d105f717e9 100644 --- a/libavcodec/binkdsp.h +++ b/libavcodec/binkdsp.h @@ -32,6 +32,7 @@ typedef struct BinkDSPContext { void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, int32_t *block/*align 16*/); void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, int32_t *block/*align 16*/); + void (*scale_block)(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align 8*/, int linesize); } BinkDSPContext; void ff_binkdsp_init(BinkDSPContext *c); diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index e1be534585..d31860166d 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -486,22 +486,6 @@ static void fill_block8_c(uint8_t *block, uint8_t value, int line_size, int h) } } -static void scale_block_c(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align 8*/, int linesize) -{ - int i, j; - uint16_t *dst1 = (uint16_t *) dst; - uint16_t *dst2 = (uint16_t *)(dst + linesize); - - for (j = 0; j < 8; j++) { - for (i = 0; i < 8; i++) { - dst1[i] = dst2[i] = src[i] * 0x0101; - } - src += 8; - dst1 += linesize; - dst2 += linesize; - } -} - #define avg2(a,b) ((a+b+1)>>1) #define avg4(a,b,c,d) ((a+b+c+d+2)>>2) @@ -2850,7 +2834,6 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) c->fill_block_tab[0] = fill_block16_c; c->fill_block_tab[1] = fill_block8_c; - c->scale_block = scale_block_c; /* TODO [0] 16 [1] 8 */ c->pix_abs[0][0] = pix_abs16_c; diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index b6f0607b08..93fbe9c6f7 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -559,7 +559,6 @@ typedef struct DSPContext { /* bink functions */ op_fill_func fill_block_tab[2]; - void (*scale_block)(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align 8*/, int linesize); } DSPContext; void dsputil_static_init(void); From c358a0364e26ffcd8f5986a85997882e1c36eed2 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 27 Jul 2011 15:49:03 +0100 Subject: [PATCH 4/9] dsputil: remove stale bink prototypes and comments Signed-off-by: Mans Rullgard --- libavcodec/dsputil.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index 93fbe9c6f7..536357a529 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -111,11 +111,6 @@ void ff_vp3_idct_dc_add_c(uint8_t *dest/*align 8*/, int line_size, const DCTELEM void ff_vp3_v_loop_filter_c(uint8_t *src, int stride, int *bounding_values); void ff_vp3_h_loop_filter_c(uint8_t *src, int stride, int *bounding_values); -/* Bink functions */ -void ff_bink_idct_c (DCTELEM *block); -void ff_bink_idct_add_c(uint8_t *dest, int linesize, DCTELEM *block); -void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block); - /* EA functions */ void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block); @@ -557,7 +552,6 @@ typedef struct DSPContext { h264_chroma_mc_func put_rv40_chroma_pixels_tab[3]; h264_chroma_mc_func avg_rv40_chroma_pixels_tab[3]; - /* bink functions */ op_fill_func fill_block_tab[2]; } DSPContext; From e72f3d10f64f5c65a67aa21dcc79a85ee55e912e Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 27 Jul 2011 16:14:33 +0100 Subject: [PATCH 5/9] dnxhdenc: fix declarations in for loops Apparently the gcc warning doesn't trigger on these. Signed-off-by: Mans Rullgard --- libavcodec/dnxhdenc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 3fb10d4380..1a0c8ce02e 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -79,13 +79,14 @@ static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, DCTELEM *block, const uint8_t *scantable= ctx->intra_scantable.scantable; const int *qmat = ctx->q_intra_matrix[qscale]; int last_non_zero = 0; + int i; ctx->dsp.fdct(block); // Divide by 4 with rounding, to compensate scaling of DCT coefficients block[0] = (block[0] + 2) >> 2; - for (int i = 1; i < 64; ++i) { + for (i = 1; i < 64; ++i) { int j = scantable[i]; int sign = block[j] >> 31; int level = (block[j] ^ sign) - sign; @@ -634,9 +635,10 @@ static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg, int jobnr, int int sum = 0; int sqsum = 0; int mean, sqmean; + int i, j; // Macroblocks are 16x16 pixels, unlike DCT blocks which are 8x8. - for (int i = 0; i < 16; ++i) { - for (int j = 0; j < 16; ++j) { + for (i = 0; i < 16; ++i) { + for (j = 0; j < 16; ++j) { // Turn 16-bit pixels into 10-bit ones. int const sample = (unsigned)pix[j] >> 6; sum += sample; From 1bca72e1bd2fa5db2585a58e452c384ca73bf0eb Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 29 May 2011 19:16:46 -0400 Subject: [PATCH 6/9] eac3enc: support writing of basic mixing and info metadata --- libavcodec/ac3enc.c | 243 ++++++++++++++++++++---------- libavcodec/ac3enc.h | 2 + libavcodec/ac3enc_opts_template.c | 14 +- libavcodec/ac3enc_template.c | 2 +- libavcodec/eac3enc.c | 46 +++++- 5 files changed, 212 insertions(+), 95 deletions(-) diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index 017b1d4b93..a3b77ec6ed 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -759,6 +759,30 @@ static void count_frame_bits(AC3EncodeContext *s) /* header */ if (s->eac3) { + if (opt->eac3_mixing_metadata) { + if (s->channel_mode > AC3_CHMODE_STEREO) + frame_bits += 2; + if (s->has_center) + frame_bits += 6; + if (s->has_surround) + frame_bits += 6; + frame_bits += s->lfe_on; + frame_bits += 1 + 1 + 2; + if (s->channel_mode < AC3_CHMODE_STEREO) + frame_bits++; + frame_bits++; + } + if (opt->eac3_info_metadata) { + frame_bits += 3 + 1 + 1; + if (s->channel_mode == AC3_CHMODE_STEREO) + frame_bits += 2 + 2; + if (s->channel_mode >= AC3_CHMODE_2F2R) + frame_bits += 2; + frame_bits++; + if (opt->audio_production_info) + frame_bits += 5 + 2 + 1; + frame_bits++; + } /* coupling */ if (s->channel_mode > AC3_CHMODE_MONO) { frame_bits++; @@ -1736,20 +1760,145 @@ int ff_ac3_validate_metadata(AC3EncodeContext *s) AVCodecContext *avctx = s->avctx; AC3EncOptions *opt = &s->options; - /* validate mixing levels */ - if (s->has_center) { - validate_mix_level(avctx, "center_mix_level", &opt->center_mix_level, - cmixlev_options, CMIXLEV_NUM_OPTIONS, 1, 0, - &s->center_mix_level); + opt->audio_production_info = 0; + opt->extended_bsi_1 = 0; + opt->extended_bsi_2 = 0; + opt->eac3_mixing_metadata = 0; + opt->eac3_info_metadata = 0; + + /* determine mixing metadata / xbsi1 use */ + if (s->channel_mode > AC3_CHMODE_STEREO && opt->preferred_stereo_downmix >= 0) { + opt->extended_bsi_1 = 1; + opt->eac3_mixing_metadata = 1; } - if (s->has_surround) { - validate_mix_level(avctx, "surround_mix_level", &opt->surround_mix_level, - surmixlev_options, SURMIXLEV_NUM_OPTIONS, 1, 0, - &s->surround_mix_level); + if (s->has_center && + (opt->ltrt_center_mix_level >= 0 || opt->loro_center_mix_level >= 0)) { + opt->extended_bsi_1 = 1; + opt->eac3_mixing_metadata = 1; + } + if (s->has_surround && + (opt->ltrt_surround_mix_level >= 0 || opt->loro_surround_mix_level >= 0)) { + opt->extended_bsi_1 = 1; + opt->eac3_mixing_metadata = 1; } - /* set audio production info flag */ - if (opt->mixing_level >= 0 || opt->room_type >= 0) { + if (s->eac3) { + /* determine info metadata use */ + if (avctx->audio_service_type != AV_AUDIO_SERVICE_TYPE_MAIN) + opt->eac3_info_metadata = 1; + if (opt->copyright >= 0 || opt->original >= 0) + opt->eac3_info_metadata = 1; + if (s->channel_mode == AC3_CHMODE_STEREO && + (opt->dolby_headphone_mode >= 0 || opt->dolby_surround_mode >= 0)) + opt->eac3_info_metadata = 1; + if (s->channel_mode >= AC3_CHMODE_2F2R && opt->dolby_surround_ex_mode >= 0) + opt->eac3_info_metadata = 1; + if (opt->mixing_level >= 0 || opt->room_type >= 0 || opt->ad_converter_type >= 0) { + opt->audio_production_info = 1; + opt->eac3_info_metadata = 1; + } + } else { + /* determine audio production info use */ + if (opt->mixing_level >= 0 || opt->room_type >= 0) + opt->audio_production_info = 1; + + /* determine xbsi2 use */ + if (s->channel_mode >= AC3_CHMODE_2F2R && opt->dolby_surround_ex_mode >= 0) + opt->extended_bsi_2 = 1; + if (s->channel_mode == AC3_CHMODE_STEREO && opt->dolby_headphone_mode >= 0) + opt->extended_bsi_2 = 1; + if (opt->ad_converter_type >= 0) + opt->extended_bsi_2 = 1; + } + + /* validate AC-3 mixing levels */ + if (!s->eac3) { + if (s->has_center) { + validate_mix_level(avctx, "center_mix_level", &opt->center_mix_level, + cmixlev_options, CMIXLEV_NUM_OPTIONS, 1, 0, + &s->center_mix_level); + } + if (s->has_surround) { + validate_mix_level(avctx, "surround_mix_level", &opt->surround_mix_level, + surmixlev_options, SURMIXLEV_NUM_OPTIONS, 1, 0, + &s->surround_mix_level); + } + } + + /* validate extended bsi 1 / mixing metadata */ + if (opt->extended_bsi_1 || opt->eac3_mixing_metadata) { + /* default preferred stereo downmix */ + if (opt->preferred_stereo_downmix < 0) + opt->preferred_stereo_downmix = 0; + if (!s->eac3 || s->has_center) { + /* validate Lt/Rt center mix level */ + validate_mix_level(avctx, "ltrt_center_mix_level", + &opt->ltrt_center_mix_level, extmixlev_options, + EXTMIXLEV_NUM_OPTIONS, 5, 0, + &s->ltrt_center_mix_level); + /* validate Lo/Ro center mix level */ + validate_mix_level(avctx, "loro_center_mix_level", + &opt->loro_center_mix_level, extmixlev_options, + EXTMIXLEV_NUM_OPTIONS, 5, 0, + &s->loro_center_mix_level); + } + if (!s->eac3 || s->has_surround) { + /* validate Lt/Rt surround mix level */ + validate_mix_level(avctx, "ltrt_surround_mix_level", + &opt->ltrt_surround_mix_level, extmixlev_options, + EXTMIXLEV_NUM_OPTIONS, 6, 3, + &s->ltrt_surround_mix_level); + /* validate Lo/Ro surround mix level */ + validate_mix_level(avctx, "loro_surround_mix_level", + &opt->loro_surround_mix_level, extmixlev_options, + EXTMIXLEV_NUM_OPTIONS, 6, 3, + &s->loro_surround_mix_level); + } + } + + /* validate audio service type / channels combination */ + if ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_KARAOKE && + avctx->channels == 1) || + ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_COMMENTARY || + avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_EMERGENCY || + avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_VOICE_OVER) + && avctx->channels > 1)) { + av_log(avctx, AV_LOG_ERROR, "invalid audio service type for the " + "specified number of channels\n"); + return AVERROR(EINVAL); + } + + /* validate extended bsi 2 / info metadata */ + if (opt->extended_bsi_2 || opt->eac3_info_metadata) { + /* default dolby headphone mode */ + if (opt->dolby_headphone_mode < 0) + opt->dolby_headphone_mode = 0; + /* default dolby surround ex mode */ + if (opt->dolby_surround_ex_mode < 0) + opt->dolby_surround_ex_mode = 0; + /* default A/D converter type */ + if (opt->ad_converter_type < 0) + opt->ad_converter_type = 0; + } + + /* copyright & original defaults */ + if (!s->eac3 || opt->eac3_info_metadata) { + /* default copyright */ + if (opt->copyright < 0) + opt->copyright = 0; + /* default original */ + if (opt->original < 0) + opt->original = 1; + } + + /* dolby surround mode default */ + if (!s->eac3 || opt->eac3_info_metadata) { + if (opt->dolby_surround_mode < 0) + opt->dolby_surround_mode = 0; + } + + /* validate audio production info */ + if (opt->audio_production_info) { if (opt->mixing_level < 0) { av_log(avctx, AV_LOG_ERROR, "mixing_level must be set if " "room_type is set\n"); @@ -1763,66 +1912,10 @@ int ff_ac3_validate_metadata(AC3EncodeContext *s) /* default room type */ if (opt->room_type < 0) opt->room_type = 0; - opt->audio_production_info = 1; - } else { - opt->audio_production_info = 0; - } - - /* set extended bsi 1 flag */ - if ((s->has_center || s->has_surround) && - (opt->preferred_stereo_downmix >= 0 || - opt->ltrt_center_mix_level >= 0 || - opt->ltrt_surround_mix_level >= 0 || - opt->loro_center_mix_level >= 0 || - opt->loro_surround_mix_level >= 0)) { - /* default preferred stereo downmix */ - if (opt->preferred_stereo_downmix < 0) - opt->preferred_stereo_downmix = 0; - /* validate Lt/Rt center mix level */ - validate_mix_level(avctx, "ltrt_center_mix_level", - &opt->ltrt_center_mix_level, extmixlev_options, - EXTMIXLEV_NUM_OPTIONS, 5, 0, - &s->ltrt_center_mix_level); - /* validate Lt/Rt surround mix level */ - validate_mix_level(avctx, "ltrt_surround_mix_level", - &opt->ltrt_surround_mix_level, extmixlev_options, - EXTMIXLEV_NUM_OPTIONS, 6, 3, - &s->ltrt_surround_mix_level); - /* validate Lo/Ro center mix level */ - validate_mix_level(avctx, "loro_center_mix_level", - &opt->loro_center_mix_level, extmixlev_options, - EXTMIXLEV_NUM_OPTIONS, 5, 0, - &s->loro_center_mix_level); - /* validate Lo/Ro surround mix level */ - validate_mix_level(avctx, "loro_surround_mix_level", - &opt->loro_surround_mix_level, extmixlev_options, - EXTMIXLEV_NUM_OPTIONS, 6, 3, - &s->loro_surround_mix_level); - opt->extended_bsi_1 = 1; - } else { - opt->extended_bsi_1 = 0; - } - - /* set extended bsi 2 flag */ - if (opt->dolby_surround_ex_mode >= 0 || - opt->dolby_headphone_mode >= 0 || - opt->ad_converter_type >= 0) { - /* default dolby surround ex mode */ - if (opt->dolby_surround_ex_mode < 0) - opt->dolby_surround_ex_mode = 0; - /* default dolby headphone mode */ - if (opt->dolby_headphone_mode < 0) - opt->dolby_headphone_mode = 0; - /* default A/D converter type */ - if (opt->ad_converter_type < 0) - opt->ad_converter_type = 0; - opt->extended_bsi_2 = 1; - } else { - opt->extended_bsi_2 = 0; } /* set bitstream id for alternate bitstream syntax */ - if (opt->extended_bsi_1 || opt->extended_bsi_2) { + if (!s->eac3 && (opt->extended_bsi_1 || opt->extended_bsi_2)) { if (s->bitstream_id > 8 && s->bitstream_id < 11) { static int warn_once = 1; if (warn_once) { @@ -2041,23 +2134,9 @@ static av_cold int validate_options(AC3EncodeContext *s) if (s->cutoff > (s->sample_rate >> 1)) s->cutoff = s->sample_rate >> 1; - /* validate audio service type / channels combination */ - if ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_KARAOKE && - avctx->channels == 1) || - ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_COMMENTARY || - avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_EMERGENCY || - avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_VOICE_OVER) - && avctx->channels > 1)) { - av_log(avctx, AV_LOG_ERROR, "invalid audio service type for the " - "specified number of channels\n"); - return AVERROR(EINVAL); - } - - if (!s->eac3) { ret = ff_ac3_validate_metadata(s); if (ret) return ret; - } s->rematrixing_enabled = s->options.stereo_rematrixing && (s->channel_mode == AC3_CHMODE_STEREO); diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h index 407e751b40..6d57143a01 100644 --- a/libavcodec/ac3enc.h +++ b/libavcodec/ac3enc.h @@ -91,6 +91,8 @@ typedef struct AC3EncOptions { int dolby_surround_ex_mode; int dolby_headphone_mode; int ad_converter_type; + int eac3_mixing_metadata; + int eac3_info_metadata; /* other encoding options */ int allow_per_frame_metadata; diff --git a/libavcodec/ac3enc_opts_template.c b/libavcodec/ac3enc_opts_template.c index 39138a1083..7c0eead011 100644 --- a/libavcodec/ac3enc_opts_template.c +++ b/libavcodec/ac3enc_opts_template.c @@ -29,12 +29,13 @@ static const AVOption ac3_options[] = { #else /* AC3ENC_TYPE_EAC3 */ static const AVOption eac3_options[] = { #endif -#if AC3ENC_TYPE != AC3ENC_TYPE_EAC3 /* Metadata Options */ {"per_frame_metadata", "Allow Changing Metadata Per-Frame", OFFSET(allow_per_frame_metadata), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, 1, AC3ENC_PARAM}, -/* downmix levels */ +#if AC3ENC_TYPE != AC3ENC_TYPE_EAC3 +/* AC-3 downmix levels */ {"center_mixlev", "Center Mix Level", OFFSET(center_mix_level), FF_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_4POINT5DB }, 0.0, 1.0, AC3ENC_PARAM}, {"surround_mixlev", "Surround Mix Level", OFFSET(surround_mix_level), FF_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_6DB }, 0.0, 1.0, AC3ENC_PARAM}, +#endif /* audio production information */ {"mixing_level", "Mixing Level", OFFSET(mixing_level), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 111, AC3ENC_PARAM}, {"room_type", "Room Type", OFFSET(room_type), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 2, AC3ENC_PARAM, "room_type"}, @@ -42,15 +43,13 @@ static const AVOption eac3_options[] = { {"large", "Large Room", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"}, {"small", "Small Room", 0, FF_OPT_TYPE_CONST, {.dbl = 2 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"}, /* other metadata options */ -{"copyright", "Copyright Bit", OFFSET(copyright), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, 1, AC3ENC_PARAM}, -#endif +{"copyright", "Copyright Bit", OFFSET(copyright), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 1, AC3ENC_PARAM}, {"dialnorm", "Dialogue Level (dB)", OFFSET(dialogue_level), FF_OPT_TYPE_INT, {.dbl = -31 }, -31, -1, AC3ENC_PARAM}, -#if AC3ENC_TYPE != AC3ENC_TYPE_EAC3 -{"dsur_mode", "Dolby Surround Mode", OFFSET(dolby_surround_mode), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, 2, AC3ENC_PARAM, "dsur_mode"}, +{"dsur_mode", "Dolby Surround Mode", OFFSET(dolby_surround_mode), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 2, AC3ENC_PARAM, "dsur_mode"}, {"notindicated", "Not Indicated (default)", 0, FF_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"}, {"on", "Dolby Surround Encoded", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"}, {"off", "Not Dolby Surround Encoded", 0, FF_OPT_TYPE_CONST, {.dbl = 2 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"}, -{"original", "Original Bit Stream", OFFSET(original), FF_OPT_TYPE_INT, {.dbl = 1 }, 0, 1, AC3ENC_PARAM}, +{"original", "Original Bit Stream", OFFSET(original), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 1, AC3ENC_PARAM}, /* extended bitstream information */ {"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 2, AC3ENC_PARAM, "dmix_mode"}, {"notindicated", "Not Indicated (default)", 0, FF_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"}, @@ -71,7 +70,6 @@ static const AVOption eac3_options[] = { {"ad_conv_type", "A/D Converter Type", OFFSET(ad_converter_type), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 1, AC3ENC_PARAM, "ad_conv_type"}, {"standard", "Standard (default)", 0, FF_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, {"hdcd", "HDCD", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, -#endif /* Other Encoding Options */ {"stereo_rematrixing", "Stereo Rematrixing", OFFSET(stereo_rematrixing), FF_OPT_TYPE_INT, {.dbl = 1 }, 0, 1, AC3ENC_PARAM}, #if AC3ENC_TYPE != AC3ENC_TYPE_AC3_FIXED diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index c4e2a121bf..103e7b1a96 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -423,7 +423,7 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, unsigned char *frame, const SampleType *samples = data; int ret; - if (!s->eac3 && s->options.allow_per_frame_metadata) { + if (s->options.allow_per_frame_metadata) { ret = ff_ac3_validate_metadata(s); if (ret) return ret; diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c index 038aa2a234..75113b272f 100644 --- a/libavcodec/eac3enc.c +++ b/libavcodec/eac3enc.c @@ -142,10 +142,48 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s) put_bits(&s->pb, 5, s->bitstream_id); /* bitstream id (EAC3=16) */ put_bits(&s->pb, 5, -opt->dialogue_level); /* dialogue normalization level */ put_bits(&s->pb, 1, 0); /* no compression gain */ - put_bits(&s->pb, 1, 0); /* no mixing metadata */ - /* TODO: mixing metadata */ - put_bits(&s->pb, 1, 0); /* no info metadata */ - /* TODO: info metadata */ + /* mixing metadata*/ + put_bits(&s->pb, 1, opt->eac3_mixing_metadata); + if (opt->eac3_mixing_metadata) { + if (s->channel_mode > AC3_CHMODE_STEREO) + put_bits(&s->pb, 2, opt->preferred_stereo_downmix); + if (s->has_center) { + put_bits(&s->pb, 3, s->ltrt_center_mix_level); + put_bits(&s->pb, 3, s->loro_center_mix_level); + } + if (s->has_surround) { + put_bits(&s->pb, 3, s->ltrt_surround_mix_level); + put_bits(&s->pb, 3, s->loro_surround_mix_level); + } + if (s->lfe_on) + put_bits(&s->pb, 1, 0); + put_bits(&s->pb, 1, 0); /* no program scale */ + put_bits(&s->pb, 1, 0); /* no ext program scale */ + put_bits(&s->pb, 2, 0); /* no mixing parameters */ + if (s->channel_mode < AC3_CHMODE_STEREO) + put_bits(&s->pb, 1, 0); /* no pan info */ + put_bits(&s->pb, 1, 0); /* no frame mix config info */ + } + /* info metadata*/ + put_bits(&s->pb, 1, opt->eac3_info_metadata); + if (opt->eac3_info_metadata) { + put_bits(&s->pb, 3, s->bitstream_mode); + put_bits(&s->pb, 1, opt->copyright); + put_bits(&s->pb, 1, opt->original); + if (s->channel_mode == AC3_CHMODE_STEREO) { + put_bits(&s->pb, 2, opt->dolby_surround_mode); + put_bits(&s->pb, 2, opt->dolby_headphone_mode); + } + if (s->channel_mode >= AC3_CHMODE_2F2R) + put_bits(&s->pb, 2, opt->dolby_surround_ex_mode); + put_bits(&s->pb, 1, opt->audio_production_info); + if (opt->audio_production_info) { + put_bits(&s->pb, 5, opt->mixing_level - 80); + put_bits(&s->pb, 2, opt->room_type); + put_bits(&s->pb, 1, opt->ad_converter_type); + } + put_bits(&s->pb, 1, 0); + } if (s->num_blocks != 6) put_bits(&s->pb, 1, !(s->avctx->frame_number % 6)); /* converter sync flag */ put_bits(&s->pb, 1, 0); /* no additional bit stream info */ From 093ee8e199d758d3f8576354fc4783a5e54eb970 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 25 Jul 2011 12:54:25 -0400 Subject: [PATCH 7/9] cosmetics: reindent --- libavcodec/ac3enc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index a3b77ec6ed..c138f99207 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -2134,9 +2134,9 @@ static av_cold int validate_options(AC3EncodeContext *s) if (s->cutoff > (s->sample_rate >> 1)) s->cutoff = s->sample_rate >> 1; - ret = ff_ac3_validate_metadata(s); - if (ret) - return ret; + ret = ff_ac3_validate_metadata(s); + if (ret) + return ret; s->rematrixing_enabled = s->options.stereo_rematrixing && (s->channel_mode == AC3_CHMODE_STEREO); From c3027b4d2f9d14906387ced6f73008d4fa2c2dfb Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 25 Jul 2011 15:51:36 +0100 Subject: [PATCH 8/9] mpegvideo: initialise DSPContext in ff_dct_common_init() The functions and tables initialised in this function rely on an initialised DSPContext. Make sure they always have one. Signed-off-by: Mans Rullgard --- libavcodec/mpegvideo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index d422e12bc1..365a0d4736 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -155,6 +155,8 @@ const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end /* init common dct for both encoder and decoder */ av_cold int ff_dct_common_init(MpegEncContext *s) { + dsputil_init(&s->dsp, s->avctx); + s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c; s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_c; s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c; @@ -603,7 +605,6 @@ av_cold int MPV_common_init(MpegEncContext *s) if((s->width || s->height) && av_image_check_size(s->width, s->height, 0, s->avctx)) return -1; - dsputil_init(&s->dsp, s->avctx); ff_dct_common_init(s); s->flags= s->avctx->flags; From ca6a90465634152c7abe2f10112fd06dc778122f Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 25 Jul 2011 16:18:17 +0100 Subject: [PATCH 9/9] ppc: remove redundant setting of Altivec IDCT This is already set by dsputil_init_ppc() and is best done in only one place. Signed-off-by: Mans Rullgard --- libavcodec/ppc/mpegvideo_altivec.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c index 673b11d0c9..2d3bf892a0 100644 --- a/libavcodec/ppc/mpegvideo_altivec.c +++ b/libavcodec/ppc/mpegvideo_altivec.c @@ -558,15 +558,6 @@ void MPV_common_init_altivec(MpegEncContext *s) { if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) return; - if (s->avctx->lowres==0) { - if ((s->avctx->idct_algo == FF_IDCT_AUTO) || - (s->avctx->idct_algo == FF_IDCT_ALTIVEC)) { - s->dsp.idct_put = idct_put_altivec; - s->dsp.idct_add = idct_add_altivec; - s->dsp.idct_permutation_type = FF_TRANSPOSE_IDCT_PERM; - } - } - // Test to make sure that the dct required alignments are met. if ((((long)(s->q_intra_matrix) & 0x0f) != 0) || (((long)(s->q_inter_matrix) & 0x0f) != 0)) {