remove broken downmixing. will add new implementation later.
Originally committed as revision 9821 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
edecaff8c2
commit
7bfd22f25a
@ -38,8 +38,6 @@
|
|||||||
#include "dsputil.h"
|
#include "dsputil.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
|
||||||
static const int nfchans_tbl[8] = { 2, 1, 2, 3, 3, 4, 4, 5 };
|
|
||||||
|
|
||||||
/* table for exponent to scale_factor mapping
|
/* table for exponent to scale_factor mapping
|
||||||
* scale_factor[i] = 2 ^ -(i + 15)
|
* scale_factor[i] = 2 ^ -(i + 15)
|
||||||
*/
|
*/
|
||||||
@ -80,12 +78,7 @@ static const float slevs[4] = { LEVEL_MINUS_3DB, LEVEL_MINUS_6DB, LEVEL_ZERO, LE
|
|||||||
|
|
||||||
#define BLOCK_SIZE 256
|
#define BLOCK_SIZE 256
|
||||||
|
|
||||||
/* Output and input configurations. */
|
#define AC3_OUTPUT_LFEON 8
|
||||||
#define AC3_OUTPUT_UNMODIFIED 0x01
|
|
||||||
#define AC3_OUTPUT_MONO 0x02
|
|
||||||
#define AC3_OUTPUT_STEREO 0x04
|
|
||||||
#define AC3_OUTPUT_DOLBY 0x08
|
|
||||||
#define AC3_OUTPUT_LFEON 0x10
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int acmod;
|
int acmod;
|
||||||
@ -132,10 +125,11 @@ typedef struct {
|
|||||||
int nchans; //number of total channels
|
int nchans; //number of total channels
|
||||||
int nfchans; //number of full-bandwidth channels
|
int nfchans; //number of full-bandwidth channels
|
||||||
int lfeon; //lfe channel in use
|
int lfeon; //lfe channel in use
|
||||||
|
int output_mode; ///< output channel configuration
|
||||||
|
int out_channels; ///< number of output channels
|
||||||
|
|
||||||
float dynrng; //dynamic range gain
|
float dynrng; //dynamic range gain
|
||||||
float dynrng2; //dynamic range gain for 1+1 mode
|
float dynrng2; //dynamic range gain for 1+1 mode
|
||||||
float chcoeffs[6]; //normalized channel coefficients
|
|
||||||
float cplco[5][18]; //coupling coordinates
|
float cplco[5][18]; //coupling coordinates
|
||||||
int ncplbnd; //number of coupling bands
|
int ncplbnd; //number of coupling bands
|
||||||
int ncplsubnd; //number of coupling sub bands
|
int ncplsubnd; //number of coupling sub bands
|
||||||
@ -151,8 +145,6 @@ typedef struct {
|
|||||||
uint8_t bap[5][256]; //fbw channel bit allocation pointers
|
uint8_t bap[5][256]; //fbw channel bit allocation pointers
|
||||||
uint8_t lfebap[256]; //lfe channel bit allocation pointers
|
uint8_t lfebap[256]; //lfe channel bit allocation pointers
|
||||||
|
|
||||||
int blkoutput; //output configuration for block
|
|
||||||
|
|
||||||
DECLARE_ALIGNED_16(float, transform_coeffs[AC3_MAX_CHANNELS][BLOCK_SIZE]); //transform coefficients
|
DECLARE_ALIGNED_16(float, transform_coeffs[AC3_MAX_CHANNELS][BLOCK_SIZE]); //transform coefficients
|
||||||
|
|
||||||
/* For IMDCT. */
|
/* For IMDCT. */
|
||||||
@ -337,9 +329,12 @@ static int ac3_parse_header(AC3DecodeContext *ctx)
|
|||||||
ctx->nchans = hdr.channels;
|
ctx->nchans = hdr.channels;
|
||||||
ctx->nfchans = ctx->nchans - ctx->lfeon;
|
ctx->nfchans = ctx->nchans - ctx->lfeon;
|
||||||
ctx->frame_size = hdr.frame_size;
|
ctx->frame_size = hdr.frame_size;
|
||||||
ctx->blkoutput = nfchans_tbl[ctx->acmod];
|
|
||||||
|
/* set default output to all source channels */
|
||||||
|
ctx->out_channels = ctx->nchans;
|
||||||
|
ctx->output_mode = ctx->acmod;
|
||||||
if(ctx->lfeon)
|
if(ctx->lfeon)
|
||||||
ctx->blkoutput |= AC3_OUTPUT_LFEON;
|
ctx->output_mode |= AC3_OUTPUT_LFEON;
|
||||||
|
|
||||||
/* skip over portion of header which has already been read */
|
/* skip over portion of header which has already been read */
|
||||||
skip_bits(gb, 16); //skip the sync_word, sync_info->sync_word = get_bits(gb, 16);
|
skip_bits(gb, 16); //skip the sync_word, sync_info->sync_word = get_bits(gb, 16);
|
||||||
@ -457,7 +452,7 @@ static int get_transform_coeffs_cpling(AC3DecodeContext *ctx, mant_groups *m)
|
|||||||
}
|
}
|
||||||
cplbndstrc >>= 1;
|
cplbndstrc >>= 1;
|
||||||
for (ch = 0; ch < ctx->nfchans; ch++)
|
for (ch = 0; ch < ctx->nfchans; ch++)
|
||||||
cplcos[ch] = ctx->chcoeffs[ch] * ctx->cplco[ch][bnd];
|
cplcos[ch] = ctx->cplco[ch][bnd];
|
||||||
bnd++;
|
bnd++;
|
||||||
|
|
||||||
while (start < end) {
|
while (start < end) {
|
||||||
@ -535,10 +530,6 @@ static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_gro
|
|||||||
uint8_t *exps;
|
uint8_t *exps;
|
||||||
uint8_t *bap;
|
uint8_t *bap;
|
||||||
float *coeffs;
|
float *coeffs;
|
||||||
float factors[25];
|
|
||||||
|
|
||||||
for (i = 0; i < 25; i++)
|
|
||||||
factors[i] = scale_factors[i] * ctx->chcoeffs[ch_index];
|
|
||||||
|
|
||||||
if (ch_index != -1) { /* fbw channels */
|
if (ch_index != -1) { /* fbw channels */
|
||||||
dithflag = ctx->dithflag[ch_index];
|
dithflag = ctx->dithflag[ch_index];
|
||||||
@ -564,7 +555,7 @@ static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_gro
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
coeffs[i] = (av_random(&ctx->dith_state) & 0xFFFF) * factors[exps[i]];
|
coeffs[i] = (av_random(&ctx->dith_state) & 0xFFFF) * scale_factors[exps[i]];
|
||||||
coeffs[i] *= LEVEL_MINUS_3DB;
|
coeffs[i] *= LEVEL_MINUS_3DB;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -577,7 +568,7 @@ static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_gro
|
|||||||
m->l3_quantizers[2] = l3_quantizers_3[gcode];
|
m->l3_quantizers[2] = l3_quantizers_3[gcode];
|
||||||
m->l3ptr = 0;
|
m->l3ptr = 0;
|
||||||
}
|
}
|
||||||
coeffs[i] = m->l3_quantizers[m->l3ptr++] * factors[exps[i]];
|
coeffs[i] = m->l3_quantizers[m->l3ptr++] * scale_factors[exps[i]];
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
@ -588,11 +579,11 @@ static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_gro
|
|||||||
m->l5_quantizers[2] = l5_quantizers_3[gcode];
|
m->l5_quantizers[2] = l5_quantizers_3[gcode];
|
||||||
m->l5ptr = 0;
|
m->l5ptr = 0;
|
||||||
}
|
}
|
||||||
coeffs[i] = m->l5_quantizers[m->l5ptr++] * factors[exps[i]];
|
coeffs[i] = m->l5_quantizers[m->l5ptr++] * scale_factors[exps[i]];
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
coeffs[i] = l7_quantizers[get_bits(gb, 3)] * factors[exps[i]];
|
coeffs[i] = l7_quantizers[get_bits(gb, 3)] * scale_factors[exps[i]];
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
@ -602,15 +593,15 @@ static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_gro
|
|||||||
m->l11_quantizers[1] = l11_quantizers_2[gcode];
|
m->l11_quantizers[1] = l11_quantizers_2[gcode];
|
||||||
m->l11ptr = 0;
|
m->l11ptr = 0;
|
||||||
}
|
}
|
||||||
coeffs[i] = m->l11_quantizers[m->l11ptr++] * factors[exps[i]];
|
coeffs[i] = m->l11_quantizers[m->l11ptr++] * scale_factors[exps[i]];
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
coeffs[i] = l15_quantizers[get_bits(gb, 4)] * factors[exps[i]];
|
coeffs[i] = l15_quantizers[get_bits(gb, 4)] * scale_factors[exps[i]];
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
coeffs[i] = (get_sbits(gb, qntztab[tbap]) << (16 - qntztab[tbap])) * factors[exps[i]];
|
coeffs[i] = (get_sbits(gb, qntztab[tbap]) << (16 - qntztab[tbap])) * scale_factors[exps[i]];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -701,498 +692,6 @@ static void do_rematrixing(AC3DecodeContext *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function sets the normalized channel coefficients.
|
|
||||||
* Transform coefficients are multipllied by the channel
|
|
||||||
* coefficients to get normalized transform coefficients.
|
|
||||||
*/
|
|
||||||
static void get_downmix_coeffs(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int from = ctx->acmod;
|
|
||||||
int to = ctx->blkoutput;
|
|
||||||
float clev = clevs[ctx->cmixlev];
|
|
||||||
float slev = slevs[ctx->surmixlev];
|
|
||||||
float nf = 1.0; //normalization factor for downmix coeffs
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!ctx->acmod) {
|
|
||||||
ctx->chcoeffs[0] = 2 * ctx->dynrng;
|
|
||||||
ctx->chcoeffs[1] = 2 * ctx->dynrng2;
|
|
||||||
} else {
|
|
||||||
for (i = 0; i < ctx->nfchans; i++)
|
|
||||||
ctx->chcoeffs[i] = 2 * ctx->dynrng;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to == AC3_OUTPUT_UNMODIFIED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (from) {
|
|
||||||
case AC3_ACMOD_DUALMONO:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
case AC3_OUTPUT_STEREO: /* We Assume that sum of both mono channels is requested */
|
|
||||||
nf = 0.5;
|
|
||||||
ctx->chcoeffs[0] *= nf;
|
|
||||||
ctx->chcoeffs[1] *= nf;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_MONO:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_STEREO:
|
|
||||||
nf = LEVEL_MINUS_3DB;
|
|
||||||
ctx->chcoeffs[0] *= nf;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_STEREO:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
nf = LEVEL_MINUS_3DB;
|
|
||||||
ctx->chcoeffs[0] *= nf;
|
|
||||||
ctx->chcoeffs[1] *= nf;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_3F:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
nf = LEVEL_MINUS_3DB / (1.0 + clev);
|
|
||||||
ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[1] *= ((nf * clev * LEVEL_MINUS_3DB) / 2.0);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_STEREO:
|
|
||||||
nf = 1.0 / (1.0 + clev);
|
|
||||||
ctx->chcoeffs[0] *= nf;
|
|
||||||
ctx->chcoeffs[2] *= nf;
|
|
||||||
ctx->chcoeffs[1] *= (nf * clev);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_2F1R:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
nf = 2.0 * LEVEL_MINUS_3DB / (2.0 + slev);
|
|
||||||
ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[2] *= (nf * slev * LEVEL_MINUS_3DB);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_STEREO:
|
|
||||||
nf = 1.0 / (1.0 + (slev * LEVEL_MINUS_3DB));
|
|
||||||
ctx->chcoeffs[0] *= nf;
|
|
||||||
ctx->chcoeffs[1] *= nf;
|
|
||||||
ctx->chcoeffs[2] *= (nf * slev * LEVEL_MINUS_3DB);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_DOLBY:
|
|
||||||
nf = 1.0 / (1.0 + LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[0] *= nf;
|
|
||||||
ctx->chcoeffs[1] *= nf;
|
|
||||||
ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_3F1R:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
nf = LEVEL_MINUS_3DB / (1.0 + clev + (slev / 2.0));
|
|
||||||
ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[1] *= (nf * clev * LEVEL_PLUS_3DB);
|
|
||||||
ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_STEREO:
|
|
||||||
nf = 1.0 / (1.0 + clev + (slev * LEVEL_MINUS_3DB));
|
|
||||||
ctx->chcoeffs[0] *= nf;
|
|
||||||
ctx->chcoeffs[2] *= nf;
|
|
||||||
ctx->chcoeffs[1] *= (nf * clev);
|
|
||||||
ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_DOLBY:
|
|
||||||
nf = 1.0 / (1.0 + (2.0 * LEVEL_MINUS_3DB));
|
|
||||||
ctx->chcoeffs[0] *= nf;
|
|
||||||
ctx->chcoeffs[1] *= nf;
|
|
||||||
ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[3] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_2F2R:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
nf = LEVEL_MINUS_3DB / (1.0 + slev);
|
|
||||||
ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[2] *= (nf * slev * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_STEREO:
|
|
||||||
nf = 1.0 / (1.0 + slev);
|
|
||||||
ctx->chcoeffs[0] *= nf;
|
|
||||||
ctx->chcoeffs[1] *= nf;
|
|
||||||
ctx->chcoeffs[2] *= (nf * slev);
|
|
||||||
ctx->chcoeffs[3] *= (nf * slev);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_DOLBY:
|
|
||||||
nf = 1.0 / (1.0 + (2.0 * LEVEL_MINUS_3DB));
|
|
||||||
ctx->chcoeffs[0] *= nf;
|
|
||||||
ctx->chcoeffs[1] *= nf;
|
|
||||||
ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[3] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_3F2R:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
nf = LEVEL_MINUS_3DB / (1.0 + clev + slev);
|
|
||||||
ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[1] *= (nf * clev * LEVEL_PLUS_3DB);
|
|
||||||
ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[4] *= (nf * slev * LEVEL_MINUS_3DB);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_STEREO:
|
|
||||||
nf = 1.0 / (1.0 + clev + slev);
|
|
||||||
ctx->chcoeffs[0] *= nf;
|
|
||||||
ctx->chcoeffs[2] *= nf;
|
|
||||||
ctx->chcoeffs[1] *= (nf * clev);
|
|
||||||
ctx->chcoeffs[3] *= (nf * slev);
|
|
||||||
ctx->chcoeffs[4] *= (nf * slev);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_DOLBY:
|
|
||||||
nf = 1.0 / (1.0 + (3.0 * LEVEL_MINUS_3DB));
|
|
||||||
ctx->chcoeffs[0] *= nf;
|
|
||||||
ctx->chcoeffs[1] *= nf;
|
|
||||||
ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[3] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
ctx->chcoeffs[4] *= (nf * LEVEL_MINUS_3DB);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********** BEGIN DOWNMIX FUNCTIONS ***********/
|
|
||||||
static inline void mix_dualmono_to_mono(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
output[1][i] += output[2][i];
|
|
||||||
memset(output[2], 0, sizeof(output[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_dualmono_to_stereo(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float tmp;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
tmp = output[1][i] + output[2][i];
|
|
||||||
output[1][i] = output[2][i] = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void upmix_mono_to_stereo(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
output[2][i] = output[1][i];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_stereo_to_mono(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
output[1][i] += output[2][i];
|
|
||||||
memset(output[2], 0, sizeof(output[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_3f_to_mono(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
output[1][i] += (output[2][i] + output[3][i]);
|
|
||||||
memset(output[2], 0, sizeof(output[2]));
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_3f_to_stereo(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
output[1][i] += output[2][i];
|
|
||||||
output[2][i] += output[3][i];
|
|
||||||
}
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_2f_1r_to_mono(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
output[1][i] += (output[2][i] + output[3][i]);
|
|
||||||
memset(output[2], 0, sizeof(output[2]));
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_2f_1r_to_stereo(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
output[1][i] += output[2][i];
|
|
||||||
output[2][i] += output[3][i];
|
|
||||||
}
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_2f_1r_to_dolby(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
output[1][i] -= output[3][i];
|
|
||||||
output[2][i] += output[3][i];
|
|
||||||
}
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_3f_1r_to_mono(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
output[1][i] = (output[2][i] + output[3][i] + output[4][i]);
|
|
||||||
memset(output[2], 0, sizeof(output[2]));
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
memset(output[4], 0, sizeof(output[4]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_3f_1r_to_stereo(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
output[1][i] += (output[2][i] + output[4][i]);
|
|
||||||
output[2][i] += (output[3][i] + output[4][i]);
|
|
||||||
}
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
memset(output[4], 0, sizeof(output[4]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_3f_1r_to_dolby(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
output[1][i] += (output[2][i] - output[4][i]);
|
|
||||||
output[2][i] += (output[3][i] + output[4][i]);
|
|
||||||
}
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
memset(output[4], 0, sizeof(output[4]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_2f_2r_to_mono(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
output[1][i] = (output[2][i] + output[3][i] + output[4][i]);
|
|
||||||
memset(output[2], 0, sizeof(output[2]));
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
memset(output[4], 0, sizeof(output[4]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_2f_2r_to_stereo(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
output[1][i] += output[3][i];
|
|
||||||
output[2][i] += output[4][i];
|
|
||||||
}
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
memset(output[4], 0, sizeof(output[4]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_2f_2r_to_dolby(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
output[1][i] -= output[3][i];
|
|
||||||
output[2][i] += output[4][i];
|
|
||||||
}
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
memset(output[4], 0, sizeof(output[4]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_3f_2r_to_mono(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
output[1][i] += (output[2][i] + output[3][i] + output[4][i] + output[5][i]);
|
|
||||||
memset(output[2], 0, sizeof(output[2]));
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
memset(output[4], 0, sizeof(output[4]));
|
|
||||||
memset(output[5], 0, sizeof(output[5]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_3f_2r_to_stereo(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
output[1][i] += (output[2][i] + output[4][i]);
|
|
||||||
output[2][i] += (output[3][i] + output[5][i]);
|
|
||||||
}
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
memset(output[4], 0, sizeof(output[4]));
|
|
||||||
memset(output[5], 0, sizeof(output[5]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mix_3f_2r_to_dolby(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float (*output)[BLOCK_SIZE] = ctx->output;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
output[1][i] += (output[2][i] - output[4][i] - output[5][i]);
|
|
||||||
output[2][i] += (output[3][i] + output[4][i] + output[5][i]);
|
|
||||||
}
|
|
||||||
memset(output[3], 0, sizeof(output[3]));
|
|
||||||
memset(output[4], 0, sizeof(output[4]));
|
|
||||||
memset(output[5], 0, sizeof(output[5]));
|
|
||||||
}
|
|
||||||
/*********** END DOWNMIX FUNCTIONS ***********/
|
|
||||||
|
|
||||||
/* Downmix the output.
|
|
||||||
* This function downmixes the output when the number of input
|
|
||||||
* channels is not equal to the number of output channels requested.
|
|
||||||
*/
|
|
||||||
static void do_downmix(AC3DecodeContext *ctx)
|
|
||||||
{
|
|
||||||
int from = ctx->acmod;
|
|
||||||
int to = ctx->blkoutput;
|
|
||||||
|
|
||||||
if (to == AC3_OUTPUT_UNMODIFIED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (from) {
|
|
||||||
case AC3_ACMOD_DUALMONO:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
mix_dualmono_to_mono(ctx);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_STEREO: /* We assume that sum of both mono channels is requested */
|
|
||||||
mix_dualmono_to_stereo(ctx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_MONO:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_STEREO:
|
|
||||||
upmix_mono_to_stereo(ctx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_STEREO:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
mix_stereo_to_mono(ctx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_3F:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
mix_3f_to_mono(ctx);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_STEREO:
|
|
||||||
mix_3f_to_stereo(ctx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_2F1R:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
mix_2f_1r_to_mono(ctx);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_STEREO:
|
|
||||||
mix_2f_1r_to_stereo(ctx);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_DOLBY:
|
|
||||||
mix_2f_1r_to_dolby(ctx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_3F1R:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
mix_3f_1r_to_mono(ctx);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_STEREO:
|
|
||||||
mix_3f_1r_to_stereo(ctx);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_DOLBY:
|
|
||||||
mix_3f_1r_to_dolby(ctx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_2F2R:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
mix_2f_2r_to_mono(ctx);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_STEREO:
|
|
||||||
mix_2f_2r_to_stereo(ctx);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_DOLBY:
|
|
||||||
mix_2f_2r_to_dolby(ctx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC3_ACMOD_3F2R:
|
|
||||||
switch (to) {
|
|
||||||
case AC3_OUTPUT_MONO:
|
|
||||||
mix_3f_2r_to_mono(ctx);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_STEREO:
|
|
||||||
mix_3f_2r_to_stereo(ctx);
|
|
||||||
break;
|
|
||||||
case AC3_OUTPUT_DOLBY:
|
|
||||||
mix_3f_2r_to_dolby(ctx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function performs the imdct on 256 sample transform
|
/* This function performs the imdct on 256 sample transform
|
||||||
* coefficients.
|
* coefficients.
|
||||||
*/
|
*/
|
||||||
@ -1239,9 +738,13 @@ static inline void do_imdct(AC3DecodeContext *ctx)
|
|||||||
{
|
{
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
if (ctx->blkoutput & AC3_OUTPUT_LFEON) {
|
if (ctx->output_mode & AC3_OUTPUT_LFEON) {
|
||||||
ctx->imdct_512.fft.imdct_calc(&ctx->imdct_512, ctx->tmp_output,
|
ctx->imdct_512.fft.imdct_calc(&ctx->imdct_512, ctx->tmp_output,
|
||||||
ctx->transform_coeffs[0], ctx->tmp_imdct);
|
ctx->transform_coeffs[0], ctx->tmp_imdct);
|
||||||
|
ctx->dsp.vector_fmul_add_add(ctx->output[0], ctx->tmp_output,
|
||||||
|
ctx->window, ctx->delay[0], 384, 256, 1);
|
||||||
|
ctx->dsp.vector_fmul_reverse(ctx->delay[0], ctx->tmp_output+256,
|
||||||
|
ctx->window, 256);
|
||||||
}
|
}
|
||||||
for (ch=1; ch<=ctx->nfchans; ch++) {
|
for (ch=1; ch<=ctx->nfchans; ch++) {
|
||||||
if (ctx->blksw[ch-1])
|
if (ctx->blksw[ch-1])
|
||||||
@ -1267,7 +770,7 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk)
|
|||||||
{
|
{
|
||||||
int nfchans = ctx->nfchans;
|
int nfchans = ctx->nfchans;
|
||||||
int acmod = ctx->acmod;
|
int acmod = ctx->acmod;
|
||||||
int i, bnd, rbnd, seg, grpsize;
|
int i, bnd, rbnd, seg, grpsize, ch;
|
||||||
GetBitContext *gb = &ctx->gb;
|
GetBitContext *gb = &ctx->gb;
|
||||||
int bit_alloc_flags = 0;
|
int bit_alloc_flags = 0;
|
||||||
int8_t *dexps;
|
int8_t *dexps;
|
||||||
@ -1296,8 +799,6 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get_downmix_coeffs(ctx);
|
|
||||||
|
|
||||||
if (get_bits1(gb)) { /* coupling strategy */
|
if (get_bits1(gb)) { /* coupling strategy */
|
||||||
ctx->cplinu = get_bits1(gb);
|
ctx->cplinu = get_bits1(gb);
|
||||||
ctx->cplbndstrc = 0;
|
ctx->cplbndstrc = 0;
|
||||||
@ -1537,7 +1038,23 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk)
|
|||||||
if(ctx->acmod == AC3_ACMOD_STEREO)
|
if(ctx->acmod == AC3_ACMOD_STEREO)
|
||||||
do_rematrixing(ctx);
|
do_rematrixing(ctx);
|
||||||
|
|
||||||
do_downmix(ctx);
|
/* apply scaling to coefficients (headroom, dynrng) */
|
||||||
|
if(ctx->lfeon) {
|
||||||
|
for(i=0; i<7; i++) {
|
||||||
|
ctx->transform_coeffs[0][i] *= 2.0f * ctx->dynrng;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(ch=1; ch<=ctx->nfchans; ch++) {
|
||||||
|
float gain = 2.0f;
|
||||||
|
if(ctx->acmod == AC3_ACMOD_DUALMONO && ch == 2) {
|
||||||
|
gain *= ctx->dynrng2;
|
||||||
|
} else {
|
||||||
|
gain *= ctx->dynrng;
|
||||||
|
}
|
||||||
|
for(i=0; i<ctx->endmant[ch-1]; i++) {
|
||||||
|
ctx->transform_coeffs[ch][i] *= gain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
do_imdct(ctx);
|
do_imdct(ctx);
|
||||||
|
|
||||||
@ -1585,27 +1102,14 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
|
|||||||
avctx->sample_rate = ctx->sampling_rate;
|
avctx->sample_rate = ctx->sampling_rate;
|
||||||
avctx->bit_rate = ctx->bit_rate;
|
avctx->bit_rate = ctx->bit_rate;
|
||||||
|
|
||||||
|
/* channel config */
|
||||||
if (avctx->channels == 0) {
|
if (avctx->channels == 0) {
|
||||||
ctx->blkoutput |= AC3_OUTPUT_UNMODIFIED;
|
avctx->channels = ctx->out_channels;
|
||||||
if (ctx->lfeon)
|
|
||||||
ctx->blkoutput |= AC3_OUTPUT_LFEON;
|
|
||||||
avctx->channels = ctx->nfchans + ctx->lfeon;
|
|
||||||
}
|
}
|
||||||
else if (avctx->channels == 1)
|
if(avctx->channels != ctx->out_channels) {
|
||||||
ctx->blkoutput |= AC3_OUTPUT_MONO;
|
av_log(avctx, AV_LOG_ERROR, "Cannot mix AC3 to %d channels.\n",
|
||||||
else if (avctx->channels == 2) {
|
avctx->channels);
|
||||||
if (ctx->dsurmod == 0x02)
|
return -1;
|
||||||
ctx->blkoutput |= AC3_OUTPUT_DOLBY;
|
|
||||||
else
|
|
||||||
ctx->blkoutput |= AC3_OUTPUT_STEREO;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (avctx->channels < (ctx->nfchans + ctx->lfeon))
|
|
||||||
av_log(avctx, AV_LOG_INFO, "ac3_decoder: AC3 Source Channels Are Less Then Specified %d: Output to %d Channels\n",avctx->channels, ctx->nfchans + ctx->lfeon);
|
|
||||||
ctx->blkoutput |= AC3_OUTPUT_UNMODIFIED;
|
|
||||||
if (ctx->lfeon)
|
|
||||||
ctx->blkoutput |= AC3_OUTPUT_LFEON;
|
|
||||||
avctx->channels = ctx->nfchans + ctx->lfeon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//av_log(avctx, AV_LOG_INFO, "channels = %d \t bit rate = %d \t sampling rate = %d \n", avctx->channels, avctx->bit_rate * 1000, avctx->sample_rate);
|
//av_log(avctx, AV_LOG_INFO, "channels = %d \t bit rate = %d \t sampling rate = %d \n", avctx->channels, avctx->bit_rate * 1000, avctx->sample_rate);
|
||||||
@ -1617,9 +1121,9 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
|
|||||||
*data_size = 0;
|
*data_size = 0;
|
||||||
return ctx->frame_size;
|
return ctx->frame_size;
|
||||||
}
|
}
|
||||||
start = (ctx->blkoutput & AC3_OUTPUT_LFEON) ? 0 : 1;
|
start = (ctx->output_mode & AC3_OUTPUT_LFEON) ? 0 : 1;
|
||||||
for (k = 0; k < BLOCK_SIZE; k++)
|
for (k = 0; k < BLOCK_SIZE; k++)
|
||||||
for (j = start; j <= avctx->channels; j++)
|
for (j = start; j <= ctx->nfchans; j++)
|
||||||
*(out_samples++) = convert(int_ptr[j][k]);
|
*(out_samples++) = convert(int_ptr[j][k]);
|
||||||
}
|
}
|
||||||
*data_size = NB_BLOCKS * BLOCK_SIZE * avctx->channels * sizeof (int16_t);
|
*data_size = NB_BLOCKS * BLOCK_SIZE * avctx->channels * sizeof (int16_t);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user