Commit 4478e9d8 authored by Michael Niedermayer's avatar Michael Niedermayer

Merge remote-tracking branch 'qatar/master'

* qatar/master:
  FATE: add tests for dfa
  mpegaudiodec: fix seeking.
  mpegaudiodec: fix compilation when testing the unchecked bitstream reader
  threads: add sysconf based number of CPUs detection
  threads: always include necessary headers for number of CPUs detection
  threads: default to automatic thread count detection
  Changelog: restore version <next> header
  cook: K&R formatting cosmetics

Conflicts:
	Changelog
	libavcodec/version.h
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents 2cba62bd febd0222
...@@ -6,7 +6,6 @@ version next: ...@@ -6,7 +6,6 @@ version next:
- v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder - v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder
- SBaGen (SBG) binaural beats script demuxer - SBaGen (SBG) binaural beats script demuxer
- OpenMG Audio muxer - OpenMG Audio muxer
- SMJPEG demuxer
- dv: add timecode to metadata - dv: add timecode to metadata
- thumbnail video filter - thumbnail video filter
- XML output in ffprobe - XML output in ffprobe
...@@ -14,6 +13,9 @@ version next: ...@@ -14,6 +13,9 @@ version next:
- tinterlace video filter - tinterlace video filter
- astreamsync audio filter - astreamsync audio filter
- amerge audio filter - amerge audio filter
- Indeo 4 decoder
- SMJPEG demuxer
- Automatic thread count based on detection number of (available) CPU cores
version 0.9: version 0.9:
...@@ -150,8 +152,6 @@ easier to use. The changes are: ...@@ -150,8 +152,6 @@ easier to use. The changes are:
- Dxtory capture format decoder - Dxtory capture format decoder
- cellauto source - cellauto source
- Simple segmenting muxer - Simple segmenting muxer
- Indeo 4 decoder
- SMJPEG demuxer
version 0.8: version 0.8:
......
...@@ -1229,6 +1229,7 @@ HAVE_LIST=" ...@@ -1229,6 +1229,7 @@ HAVE_LIST="
symver symver
symver_asm_label symver_asm_label
symver_gnu_asm symver_gnu_asm
sysconf
sysctl sysctl
sys_mman_h sys_mman_h
sys_param_h sys_param_h
...@@ -3008,6 +3009,7 @@ check_func setrlimit ...@@ -3008,6 +3009,7 @@ check_func setrlimit
check_func strerror_r check_func strerror_r
check_func strptime check_func strptime
check_func sched_getaffinity check_func sched_getaffinity
check_func sysconf
check_func sysctl check_func sysctl
check_func_headers conio.h kbhit check_func_headers conio.h kbhit
check_func_headers windows.h PeekNamedPipe check_func_headers windows.h PeekNamedPipe
......
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
#define MONO 0x1000001 #define MONO 0x1000001
#define STEREO 0x1000002 #define STEREO 0x1000002
#define JOINT_STEREO 0x1000003 #define JOINT_STEREO 0x1000003
#define MC_COOK 0x2000000 //multichannel Cook, not supported #define MC_COOK 0x2000000 // multichannel Cook, not supported
#define SUBBAND_SIZE 20 #define SUBBAND_SIZE 20
#define MAX_SUBPACKETS 5 #define MAX_SUBPACKETS 5
...@@ -102,24 +102,24 @@ typedef struct cook { ...@@ -102,24 +102,24 @@ typedef struct cook {
* The following 5 functions provide the lowlevel arithmetic on * The following 5 functions provide the lowlevel arithmetic on
* the internal audio buffers. * the internal audio buffers.
*/ */
void (* scalar_dequant)(struct cook *q, int index, int quant_index, void (*scalar_dequant)(struct cook *q, int index, int quant_index,
int* subband_coef_index, int* subband_coef_sign, int *subband_coef_index, int *subband_coef_sign,
float* mlt_p); float *mlt_p);
void (* decouple) (struct cook *q, void (*decouple)(struct cook *q,
COOKSubpacket *p, COOKSubpacket *p,
int subband, int subband,
float f1, float f2, float f1, float f2,
float *decode_buffer, float *decode_buffer,
float *mlt_buffer1, float *mlt_buffer2); float *mlt_buffer1, float *mlt_buffer2);
void (* imlt_window) (struct cook *q, float *buffer1, void (*imlt_window)(struct cook *q, float *buffer1,
cook_gains *gains_ptr, float *previous_buffer); cook_gains *gains_ptr, float *previous_buffer);
void (* interpolate) (struct cook *q, float* buffer, void (*interpolate)(struct cook *q, float *buffer,
int gain_index, int gain_index_next); int gain_index, int gain_index_next);
void (* saturate_output) (struct cook *q, int chan, float *out); void (*saturate_output)(struct cook *q, int chan, float *out);
AVCodecContext* avctx; AVCodecContext* avctx;
AVFrame frame; AVFrame frame;
...@@ -140,7 +140,7 @@ typedef struct cook { ...@@ -140,7 +140,7 @@ typedef struct cook {
/* VLC data */ /* VLC data */
VLC envelope_quant_index[13]; VLC envelope_quant_index[13];
VLC sqvh[7]; //scalar quantization VLC sqvh[7]; // scalar quantization
/* generatable tables and related variables */ /* generatable tables and related variables */
int gain_size_factor; int gain_size_factor;
...@@ -165,55 +165,58 @@ static float rootpow2tab[127]; ...@@ -165,55 +165,58 @@ static float rootpow2tab[127];
/*************** init functions ***************/ /*************** init functions ***************/
/* table generator */ /* table generator */
static av_cold void init_pow2table(void){ static av_cold void init_pow2table(void)
{
int i; int i;
for (i=-63 ; i<64 ; i++){ for (i = -63; i < 64; i++) {
pow2tab[63+i]= pow(2, i); pow2tab[63 + i] = pow(2, i);
rootpow2tab[63+i]=sqrt(pow(2, i)); rootpow2tab[63 + i] = sqrt(pow(2, i));
} }
} }
/* table generator */ /* table generator */
static av_cold void init_gain_table(COOKContext *q) { static av_cold void init_gain_table(COOKContext *q)
{
int i; int i;
q->gain_size_factor = q->samples_per_channel/8; q->gain_size_factor = q->samples_per_channel / 8;
for (i=0 ; i<23 ; i++) { for (i = 0; i < 23; i++)
q->gain_table[i] = pow(pow2tab[i+52] , q->gain_table[i] = pow(pow2tab[i + 52],
(1.0/(double)q->gain_size_factor)); (1.0 / (double) q->gain_size_factor));
}
} }
static av_cold int init_cook_vlc_tables(COOKContext *q) { static av_cold int init_cook_vlc_tables(COOKContext *q)
{
int i, result; int i, result;
result = 0; result = 0;
for (i=0 ; i<13 ; i++) { for (i = 0; i < 13; i++) {
result |= init_vlc (&q->envelope_quant_index[i], 9, 24, result |= init_vlc(&q->envelope_quant_index[i], 9, 24,
envelope_quant_index_huffbits[i], 1, 1, envelope_quant_index_huffbits[i], 1, 1,
envelope_quant_index_huffcodes[i], 2, 2, 0); envelope_quant_index_huffcodes[i], 2, 2, 0);
} }
av_log(q->avctx,AV_LOG_DEBUG,"sqvh VLC init\n"); av_log(q->avctx, AV_LOG_DEBUG, "sqvh VLC init\n");
for (i=0 ; i<7 ; i++) { for (i = 0; i < 7; i++) {
result |= init_vlc (&q->sqvh[i], vhvlcsize_tab[i], vhsize_tab[i], result |= init_vlc(&q->sqvh[i], vhvlcsize_tab[i], vhsize_tab[i],
cvh_huffbits[i], 1, 1, cvh_huffbits[i], 1, 1,
cvh_huffcodes[i], 2, 2, 0); cvh_huffcodes[i], 2, 2, 0);
} }
for(i=0;i<q->num_subpackets;i++){ for (i = 0; i < q->num_subpackets; i++) {
if (q->subpacket[i].joint_stereo==1){ if (q->subpacket[i].joint_stereo == 1) {
result |= init_vlc (&q->subpacket[i].ccpl, 6, (1<<q->subpacket[i].js_vlc_bits)-1, result |= init_vlc(&q->subpacket[i].ccpl, 6, (1 << q->subpacket[i].js_vlc_bits) - 1,
ccpl_huffbits[q->subpacket[i].js_vlc_bits-2], 1, 1, ccpl_huffbits[q->subpacket[i].js_vlc_bits - 2], 1, 1,
ccpl_huffcodes[q->subpacket[i].js_vlc_bits-2], 2, 2, 0); ccpl_huffcodes[q->subpacket[i].js_vlc_bits - 2], 2, 2, 0);
av_log(q->avctx,AV_LOG_DEBUG,"subpacket %i Joint-stereo VLC used.\n",i); av_log(q->avctx, AV_LOG_DEBUG, "subpacket %i Joint-stereo VLC used.\n", i);
} }
} }
av_log(q->avctx,AV_LOG_DEBUG,"VLC tables initialized.\n"); av_log(q->avctx, AV_LOG_DEBUG, "VLC tables initialized.\n");
return result; return result;
} }
static av_cold int init_cook_mlt(COOKContext *q) { static av_cold int init_cook_mlt(COOKContext *q)
{
int j, ret; int j, ret;
int mlt_size = q->samples_per_channel; int mlt_size = q->samples_per_channel;
...@@ -222,35 +225,36 @@ static av_cold int init_cook_mlt(COOKContext *q) { ...@@ -222,35 +225,36 @@ static av_cold int init_cook_mlt(COOKContext *q) {
/* Initialize the MLT window: simple sine window. */ /* Initialize the MLT window: simple sine window. */
ff_sine_window_init(q->mlt_window, mlt_size); ff_sine_window_init(q->mlt_window, mlt_size);
for(j=0 ; j<mlt_size ; j++) for (j = 0; j < mlt_size; j++)
q->mlt_window[j] *= sqrt(2.0 / q->samples_per_channel); q->mlt_window[j] *= sqrt(2.0 / q->samples_per_channel);
/* Initialize the MDCT. */ /* Initialize the MDCT. */
if ((ret = ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size)+1, 1, 1.0/32768.0))) { if ((ret = ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size) + 1, 1, 1.0 / 32768.0))) {
av_free(q->mlt_window); av_free(q->mlt_window);
return ret; return ret;
} }
av_log(q->avctx,AV_LOG_DEBUG,"MDCT initialized, order = %d.\n", av_log(q->avctx, AV_LOG_DEBUG, "MDCT initialized, order = %d.\n",
av_log2(mlt_size)+1); av_log2(mlt_size) + 1);
return 0; return 0;
} }
static const float *maybe_reformat_buffer32 (COOKContext *q, const float *ptr, int n) static const float *maybe_reformat_buffer32(COOKContext *q, const float *ptr, int n)
{ {
if (1) if (1)
return ptr; return ptr;
} }
static av_cold void init_cplscales_table (COOKContext *q) { static av_cold void init_cplscales_table(COOKContext *q)
{
int i; int i;
for (i=0;i<5;i++) for (i = 0; i < 5; i++)
q->cplscales[i] = maybe_reformat_buffer32 (q, cplscales[i], (1<<(i+2))-1); q->cplscales[i] = maybe_reformat_buffer32(q, cplscales[i], (1 << (i + 2)) - 1);
} }
/*************** init functions end ***********/ /*************** init functions end ***********/
#define DECODE_BYTES_PAD1(bytes) (3 - ((bytes)+3) % 4) #define DECODE_BYTES_PAD1(bytes) (3 - ((bytes) + 3) % 4)
#define DECODE_BYTES_PAD2(bytes) ((bytes) % 4 + DECODE_BYTES_PAD1(2 * (bytes))) #define DECODE_BYTES_PAD2(bytes) ((bytes) % 4 + DECODE_BYTES_PAD1(2 * (bytes)))
/** /**
...@@ -273,27 +277,27 @@ static av_cold void init_cplscales_table (COOKContext *q) { ...@@ -273,27 +277,27 @@ static av_cold void init_cplscales_table (COOKContext *q) {
* @param out pointer to byte array of outdata * @param out pointer to byte array of outdata
* @param bytes number of bytes * @param bytes number of bytes
*/ */
static inline int decode_bytes(const uint8_t *inbuffer, uint8_t *out, int bytes)
static inline int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){ {
static const uint32_t tab[4] = { static const uint32_t tab[4] = {
AV_BE2NE32C(0x37c511f2), AV_BE2NE32C(0xf237c511), AV_BE2NE32C(0x37c511f2), AV_BE2NE32C(0xf237c511),
AV_BE2NE32C(0x11f237c5), AV_BE2NE32C(0xc511f237), AV_BE2NE32C(0x11f237c5), AV_BE2NE32C(0xc511f237),
}; };
int i, off; int i, off;
uint32_t c; uint32_t c;
const uint32_t* buf; const uint32_t *buf;
uint32_t* obuf = (uint32_t*) out; uint32_t *obuf = (uint32_t *) out;
/* FIXME: 64 bit platforms would be able to do 64 bits at a time. /* FIXME: 64 bit platforms would be able to do 64 bits at a time.
* I'm too lazy though, should be something like * I'm too lazy though, should be something like
* for(i=0 ; i<bitamount/64 ; i++) * for (i = 0; i < bitamount / 64; i++)
* (int64_t)out[i] = 0x37c511f237c511f2^av_be2ne64(int64_t)in[i]); * (int64_t) out[i] = 0x37c511f237c511f2 ^ av_be2ne64(int64_t) in[i]);
* Buffer alignment needs to be checked. */ * Buffer alignment needs to be checked. */
off = (intptr_t)inbuffer & 3; off = (intptr_t) inbuffer & 3;
buf = (const uint32_t*) (inbuffer - off); buf = (const uint32_t *) (inbuffer - off);
c = tab[off]; c = tab[off];
bytes += 3 + off; bytes += 3 + off;
for (i = 0; i < bytes/4; i++) for (i = 0; i < bytes / 4; i++)
obuf[i] = c ^ buf[i]; obuf[i] = c ^ buf[i];
return off; return off;
...@@ -302,12 +306,11 @@ static inline int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes) ...@@ -302,12 +306,11 @@ static inline int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes)
/** /**
* Cook uninit * Cook uninit
*/ */
static av_cold int cook_decode_close(AVCodecContext *avctx) static av_cold int cook_decode_close(AVCodecContext *avctx)
{ {
int i; int i;
COOKContext *q = avctx->priv_data; COOKContext *q = avctx->priv_data;
av_log(avctx,AV_LOG_DEBUG, "Deallocating memory.\n"); av_log(avctx, AV_LOG_DEBUG, "Deallocating memory.\n");
/* Free allocated memory buffers. */ /* Free allocated memory buffers. */
av_free(q->mlt_window); av_free(q->mlt_window);
...@@ -317,17 +320,14 @@ static av_cold int cook_decode_close(AVCodecContext *avctx) ...@@ -317,17 +320,14 @@ static av_cold int cook_decode_close(AVCodecContext *avctx)
ff_mdct_end(&q->mdct_ctx); ff_mdct_end(&q->mdct_ctx);
/* Free the VLC tables. */ /* Free the VLC tables. */
for (i=0 ; i<13 ; i++) { for (i = 0; i < 13; i++)
free_vlc(&q->envelope_quant_index[i]); free_vlc(&q->envelope_quant_index[i]);
} for (i = 0; i < 7; i++)
for (i=0 ; i<7 ; i++) {
free_vlc(&q->sqvh[i]); free_vlc(&q->sqvh[i]);
} for (i = 0; i < q->num_subpackets; i++)
for (i=0 ; i<q->num_subpackets ; i++) {
free_vlc(&q->subpacket[i].ccpl); free_vlc(&q->subpacket[i].ccpl);
}
av_log(avctx,AV_LOG_DEBUG,"Memory deallocated.\n"); av_log(avctx, AV_LOG_DEBUG, "Memory deallocated.\n");
return 0; return 0;
} }
...@@ -338,22 +338,26 @@ static av_cold int cook_decode_close(AVCodecContext *avctx) ...@@ -338,22 +338,26 @@ static av_cold int cook_decode_close(AVCodecContext *avctx)
* @param gb pointer to the GetBitContext * @param gb pointer to the GetBitContext
* @param gaininfo array[9] of gain indexes * @param gaininfo array[9] of gain indexes
*/ */
static void decode_gain_info(GetBitContext *gb, int *gaininfo) static void decode_gain_info(GetBitContext *gb, int *gaininfo)
{ {
int i, n; int i, n;
while (get_bits1(gb)) {} while (get_bits1(gb)) {
n = get_bits_count(gb) - 1; //amount of elements*2 to update /* NOTHING */
}
n = get_bits_count(gb) - 1; // amount of elements*2 to update
i = 0; i = 0;
while (n--) { while (n--) {
int index = get_bits(gb, 3); int index = get_bits(gb, 3);
int gain = get_bits1(gb) ? get_bits(gb, 4) - 7 : -1; int gain = get_bits1(gb) ? get_bits(gb, 4) - 7 : -1;
while (i <= index) gaininfo[i++] = gain; while (i <= index)
gaininfo[i++] = gain;
} }
while (i <= 8) gaininfo[i++] = 0; while (i <= 8)
gaininfo[i++] = 0;
} }
/** /**
...@@ -362,25 +366,28 @@ static void decode_gain_info(GetBitContext *gb, int *gaininfo) ...@@ -362,25 +366,28 @@ static void decode_gain_info(GetBitContext *gb, int *gaininfo)
* @param q pointer to the COOKContext * @param q pointer to the COOKContext
* @param quant_index_table pointer to the array * @param quant_index_table pointer to the array
*/ */
static void decode_envelope(COOKContext *q, COOKSubpacket *p,
int *quant_index_table)
{
int i, j, vlc_index;
static void decode_envelope(COOKContext *q, COOKSubpacket *p, int* quant_index_table) { quant_index_table[0] = get_bits(&q->gb, 6) - 6; // This is used later in categorize
int i,j, vlc_index;
quant_index_table[0]= get_bits(&q->gb,6) - 6; //This is used later in categorize
for (i=1 ; i < p->total_subbands ; i++){ for (i = 1; i < p->total_subbands; i++) {
vlc_index=i; vlc_index = i;
if (i >= p->js_subband_start * 2) { if (i >= p->js_subband_start * 2) {
vlc_index-=p->js_subband_start; vlc_index -= p->js_subband_start;
} else { } else {
vlc_index/=2; vlc_index /= 2;
if(vlc_index < 1) vlc_index = 1; if (vlc_index < 1)
vlc_index = 1;
} }
if (vlc_index>13) vlc_index = 13; //the VLC tables >13 are identical to No. 13 if (vlc_index > 13)
vlc_index = 13; // the VLC tables >13 are identical to No. 13
j = get_vlc2(&q->gb, q->envelope_quant_index[vlc_index-1].table, j = get_vlc2(&q->gb, q->envelope_quant_index[vlc_index - 1].table,
q->envelope_quant_index[vlc_index-1].bits,2); q->envelope_quant_index[vlc_index - 1].bits, 2);
quant_index_table[i] = quant_index_table[i-1] + j - 12; //differential encoding quant_index_table[i] = quant_index_table[i - 1] + j - 12; // differential encoding
} }
} }
...@@ -392,22 +399,22 @@ static void decode_envelope(COOKContext *q, COOKSubpacket *p, int* quant_index_t ...@@ -392,22 +399,22 @@ static void decode_envelope(COOKContext *q, COOKSubpacket *p, int* quant_index_t
* @param category pointer to the category array * @param category pointer to the category array
* @param category_index pointer to the category_index array * @param category_index pointer to the category_index array
*/ */
static void categorize(COOKContext *q, COOKSubpacket *p, int *quant_index_table,
static void categorize(COOKContext *q, COOKSubpacket *p, int* quant_index_table, int *category, int *category_index)
int* category, int* category_index){ {
int exp_idx, bias, tmpbias1, tmpbias2, bits_left, num_bits, index, v, i, j; int exp_idx, bias, tmpbias1, tmpbias2, bits_left, num_bits, index, v, i, j;
int exp_index2[102]; int exp_index2[102];
int exp_index1[102]; int exp_index1[102];
int tmp_categorize_array[128*2]; int tmp_categorize_array[128 * 2];
int tmp_categorize_array1_idx=p->numvector_size; int tmp_categorize_array1_idx = p->numvector_size;
int tmp_categorize_array2_idx=p->numvector_size; int tmp_categorize_array2_idx = p->numvector_size;
bits_left = p->bits_per_subpacket - get_bits_count(&q->gb); bits_left = p->bits_per_subpacket - get_bits_count(&q->gb);
if(bits_left > q->samples_per_channel) { if (bits_left > q->samples_per_channel) {
bits_left = q->samples_per_channel + bits_left = q->samples_per_channel +
((bits_left - q->samples_per_channel)*5)/8; ((bits_left - q->samples_per_channel) * 5) / 8;
//av_log(q->avctx, AV_LOG_ERROR, "bits_left = %d\n",bits_left); //av_log(q->avctx, AV_LOG_ERROR, "bits_left = %d\n",bits_left);
} }
...@@ -415,25 +422,24 @@ static void categorize(COOKContext *q, COOKSubpacket *p, int* quant_index_table, ...@@ -415,25 +422,24 @@ static void categorize(COOKContext *q, COOKSubpacket *p, int* quant_index_table,
memset(&exp_index2, 0, sizeof(exp_index2)); memset(&exp_index2, 0, sizeof(exp_index2));
memset(&tmp_categorize_array, 0, sizeof(tmp_categorize_array)); memset(&tmp_categorize_array, 0, sizeof(tmp_categorize_array));
bias=-32; bias = -32;
/* Estimate bias. */ /* Estimate bias. */
for (i=32 ; i>0 ; i=i/2){ for (i = 32; i > 0; i = i / 2) {
num_bits = 0; num_bits = 0;
index = 0; index = 0;
for (j=p->total_subbands ; j>0 ; j--){ for (j = p->total_subbands; j > 0; j--) {
exp_idx = av_clip((i - quant_index_table[index] + bias) / 2, 0, 7); exp_idx = av_clip((i - quant_index_table[index] + bias) / 2, 0, 7);
index++; index++;
num_bits+=expbits_tab[exp_idx]; num_bits += expbits_tab[exp_idx];
}
if(num_bits >= bits_left - 32){
bias+=i;
} }
if (num_bits >= bits_left - 32)
bias += i;
} }
/* Calculate total number of bits. */ /* Calculate total number of bits. */
num_bits=0; num_bits = 0;
for (i=0 ; i<p->total_subbands ; i++) { for (i = 0; i < p->total_subbands; i++) {
exp_idx = av_clip((bias - quant_index_table[i]) / 2, 0, 7); exp_idx = av_clip((bias - quant_index_table[i]) / 2, 0, 7);
num_bits += expbits_tab[exp_idx]; num_bits += expbits_tab[exp_idx];
exp_index1[i] = exp_idx; exp_index1[i] = exp_idx;
...@@ -441,50 +447,51 @@ static void categorize(COOKContext *q, COOKSubpacket *p, int* quant_index_table, ...@@ -441,50 +447,51 @@ static void categorize(COOKContext *q, COOKSubpacket *p, int* quant_index_table,
} }
tmpbias1 = tmpbias2 = num_bits; tmpbias1 = tmpbias2 = num_bits;
for (j = 1 ; j < p->numvector_size ; j++) { for (j = 1; j < p->numvector_size; j++) {
if (tmpbias1 + tmpbias2 > 2*bits_left) { /* ---> */ if (tmpbias1 + tmpbias2 > 2 * bits_left) { /* ---> */
int max = -999999; int max = -999999;
index=-1; index = -1;
for (i=0 ; i<p->total_subbands ; i++){ for (i = 0; i < p->total_subbands; i++) {
if (exp_index1[i] < 7) { if (exp_index1[i] < 7) {
v = (-2*exp_index1[i]) - quant_index_table[i] + bias; v = (-2 * exp_index1[i]) - quant_index_table[i] + bias;
if ( v >= max) { if (v >= max) {
max = v; max = v;
index = i; index = i;
} }
} }
} }
if(index==-1)break; if (index == -1)
break;
tmp_categorize_array[tmp_categorize_array1_idx++] = index; tmp_categorize_array[tmp_categorize_array1_idx++] = index;
tmpbias1 -= expbits_tab[exp_index1[index]] - tmpbias1 -= expbits_tab[exp_index1[index]] -
expbits_tab[exp_index1[index]+1]; expbits_tab[exp_index1[index] + 1];
++exp_index1[index]; ++exp_index1[index];
} else { /* <--- */ } else { /* <--- */
int min = 999999; int min = 999999;
index=-1; index = -1;
for (i=0 ; i<p->total_subbands ; i++){ for (i = 0; i < p->total_subbands; i++) {
if(exp_index2[i] > 0){ if (exp_index2[i] > 0) {
v = (-2*exp_index2[i])-quant_index_table[i]+bias; v = (-2 * exp_index2[i]) - quant_index_table[i] + bias;
if ( v < min) { if (v < min) {
min = v; min = v;
index = i; index = i;
} }
} }
} }
if(index == -1)break; if (index == -1)
break;
tmp_categorize_array[--tmp_categorize_array2_idx] = index; tmp_categorize_array[--tmp_categorize_array2_idx] = index;
tmpbias2 -= expbits_tab[exp_index2[index]] - tmpbias2 -= expbits_tab[exp_index2[index]] -
expbits_tab[exp_index2[index]-1]; expbits_tab[exp_index2[index] - 1];
--exp_index2[index]; --exp_index2[index];
} }
} }
for(i=0 ; i<p->total_subbands ; i++) for (i = 0; i < p->total_subbands; i++)
category[i] = exp_index2[i]; category[i] = exp_index2[i];
for(i=0 ; i<p->numvector_size-1 ; i++) for (i = 0; i < p->numvector_size - 1; i++)
category_index[i] = tmp_categorize_array[tmp_categorize_array2_idx++]; category_index[i] = tmp_categorize_array[tmp_categorize_array2_idx++];
} }
...@@ -495,13 +502,12 @@ static void categorize(COOKContext *q, COOKSubpacket *p, int* quant_index_table, ...@@ -495,13 +502,12 @@ static void categorize(COOKContext *q, COOKSubpacket *p, int* quant_index_table,
* @param category pointer to the category array * @param category pointer to the category array
* @param category_index pointer to the category_index array * @param category_index pointer to the category_index array
*/ */
static inline void expand_category(COOKContext *q, int *category,
static inline void expand_category(COOKContext *q, int* category, int *category_index)
int* category_index){ {
int i; int i;
for(i=0 ; i<q->num_vectors ; i++){ for (i = 0; i < q->num_vectors; i++)
++category[category_index[i]]; ++category[category_index[i]];
}
} }
/** /**
...@@ -514,23 +520,25 @@ static inline void expand_category(COOKContext *q, int* category, ...@@ -514,23 +520,25 @@ static inline void expand_category(COOKContext *q, int* category,
* @param subband_coef_sign signs of coefficients * @param subband_coef_sign signs of coefficients
* @param mlt_p pointer into the mlt buffer * @param mlt_p pointer into the mlt buffer
*/ */
static void scalar_dequant_float(COOKContext *q, int index, int quant_index, static void scalar_dequant_float(COOKContext *q, int index, int quant_index,
int* subband_coef_index, int* subband_coef_sign, int *subband_coef_index, int *subband_coef_sign,
float* mlt_p){ float *mlt_p)
{
int i; int i;
float f1; float f1;
for(i=0 ; i<SUBBAND_SIZE ; i++) { for (i = 0; i < SUBBAND_SIZE; i++) {
if (subband_coef_index[i]) { if (subband_coef_index[i]) {
f1 = quant_centroid_tab[index][subband_coef_index[i]]; f1 = quant_centroid_tab[index][subband_coef_index[i]];
if (subband_coef_sign[i]) f1 = -f1; if (subband_coef_sign[i])
f1 = -f1;
} else { } else {
/* noise coding if subband_coef_index[i] == 0 */ /* noise coding if subband_coef_index[i] == 0 */
f1 = dither_tab[index]; f1 = dither_tab[index];
if (av_lfg_get(&q->random_state) < 0x80000000) f1 = -f1; if (av_lfg_get(&q->random_state) < 0x80000000)
f1 = -f1;
} }
mlt_p[i] = f1 * rootpow2tab[quant_index+63]; mlt_p[i] = f1 * rootpow2tab[quant_index + 63];
} }
} }
/** /**
...@@ -541,35 +549,35 @@ static void scalar_dequant_float(COOKContext *q, int index, int quant_index, ...@@ -541,35 +549,35 @@ static void scalar_dequant_float(COOKContext *q, int index, int quant_index,
* @param subband_coef_index array of indexes to quant_centroid_tab * @param subband_coef_index array of indexes to quant_centroid_tab
* @param subband_coef_sign signs of coefficients * @param subband_coef_sign signs of coefficients
*/ */
static int unpack_SQVH(COOKContext *q, COOKSubpacket *p, int category,
static int unpack_SQVH(COOKContext *q, COOKSubpacket *p, int category, int* subband_coef_index, int *subband_coef_index, int *subband_coef_sign)
int* subband_coef_sign) { {
int i,j; int i, j;
int vlc, vd ,tmp, result; int vlc, vd, tmp, result;
vd = vd_tab[category]; vd = vd_tab[category];
result = 0; result = 0;
for(i=0 ; i<vpr_tab[category] ; i++){ for (i = 0; i < vpr_tab[category]; i++) {
vlc = get_vlc2(&q->gb, q->sqvh[category].table, q->sqvh[category].bits, 3); vlc = get_vlc2(&q->gb, q->sqvh[category].table, q->sqvh[category].bits, 3);
if (p->bits_per_subpacket < get_bits_count(&q->gb)){ if (p->bits_per_subpacket < get_bits_count(&q->gb)) {
vlc = 0; vlc = 0;
result = 1; result = 1;
} }
for(j=vd-1 ; j>=0 ; j--){ for (j = vd - 1; j >= 0; j--) {
tmp = (vlc * invradix_tab[category])/0x100000; tmp = (vlc * invradix_tab[category]) / 0x100000;
subband_coef_index[vd*i+j] = vlc - tmp * (kmax_tab[category]+1); subband_coef_index[vd * i + j] = vlc - tmp * (kmax_tab[category] + 1);
vlc = tmp; vlc = tmp;
} }
for(j=0 ; j<vd ; j++){ for (j = 0; j < vd; j++) {
if (subband_coef_index[i*vd + j]) { if (subband_coef_index[i * vd + j]) {
if(get_bits_count(&q->gb) < p->bits_per_subpacket){ if (get_bits_count(&q->gb) < p->bits_per_subpacket) {
subband_coef_sign[i*vd+j] = get_bits1(&q->gb); subband_coef_sign[i * vd + j] = get_bits1(&q->gb);
} else { } else {
result=1; result = 1;
subband_coef_sign[i*vd+j]=0; subband_coef_sign[i * vd + j] = 0;
} }
} else { } else {
subband_coef_sign[i*vd+j]=0; subband_coef_sign[i * vd + j] = 0;
} }
} }
} }
...@@ -585,10 +593,9 @@ static int unpack_SQVH(COOKContext *q, COOKSubpacket *p, int category, int* subb ...@@ -585,10 +593,9 @@ static int unpack_SQVH(COOKContext *q, COOKSubpacket *p, int category, int* subb
* @param quant_index_table pointer to the array * @param quant_index_table pointer to the array
* @param mlt_buffer pointer to mlt coefficients * @param mlt_buffer pointer to mlt coefficients
*/ */
static void decode_vectors(COOKContext *q, COOKSubpacket *p, int *category,
int *quant_index_table, float *mlt_buffer)
static void decode_vectors(COOKContext* q, COOKSubpacket* p, int* category, {
int *quant_index_table, float* mlt_buffer){
/* A zero in this table means that the subband coefficient is /* A zero in this table means that the subband coefficient is
random noise coded. */ random noise coded. */
int subband_coef_index[SUBBAND_SIZE]; int subband_coef_index[SUBBAND_SIZE];
...@@ -596,28 +603,29 @@ static void decode_vectors(COOKContext* q, COOKSubpacket* p, int* category, ...@@ -596,28 +603,29 @@ static void decode_vectors(COOKContext* q, COOKSubpacket* p, int* category,
positive multiplicator. */ positive multiplicator. */
int subband_coef_sign[SUBBAND_SIZE]; int subband_coef_sign[SUBBAND_SIZE];
int band, j; int band, j;
int index=0; int index = 0;
for(band=0 ; band<p->total_subbands ; band++){ for (band = 0; band < p->total_subbands; band++) {
index = category[band]; index = category[band];
if(category[band] < 7){ if (category[band] < 7) {
if(unpack_SQVH(q, p, category[band], subband_coef_index, subband_coef_sign)){ if (unpack_SQVH(q, p, category[band], subband_coef_index, subband_coef_sign)) {
index=7; index = 7;
for(j=0 ; j<p->total_subbands ; j++) category[band+j]=7; for (j = 0; j < p->total_subbands; j++)
category[band + j] = 7;
} }
} }
if(index>=7) { if (index >= 7) {
memset(subband_coef_index, 0, sizeof(subband_coef_index)); memset(subband_coef_index, 0, sizeof(subband_coef_index));
memset(subband_coef_sign, 0, sizeof(subband_coef_sign)); memset(subband_coef_sign, 0, sizeof(subband_coef_sign));
} }
q->scalar_dequant(q, index, quant_index_table[band], q->scalar_dequant(q, index, quant_index_table[band],
subband_coef_index, subband_coef_sign, subband_coef_index, subband_coef_sign,
&mlt_buffer[band * SUBBAND_SIZE]); &mlt_buffer[band * SUBBAND_SIZE]);
} }
if(p->total_subbands*SUBBAND_SIZE >= q->samples_per_channel){ /* FIXME: should this be removed, or moved into loop above? */
if (p->total_subbands * SUBBAND_SIZE >= q->samples_per_channel)
return; return;
} /* FIXME: should this be removed, or moved into loop above? */
} }
...@@ -627,9 +635,8 @@ static void decode_vectors(COOKContext* q, COOKSubpacket* p, int* category, ...@@ -627,9 +635,8 @@ static void decode_vectors(COOKContext* q, COOKSubpacket* p, int* category,
* @param q pointer to the COOKContext * @param q pointer to the COOKContext
* @param mlt_buffer pointer to mlt coefficients * @param mlt_buffer pointer to mlt coefficients
*/ */
static void mono_decode(COOKContext *q, COOKSubpacket *p, float *mlt_buffer)
static void mono_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer) { {
int category_index[128]; int category_index[128];
int quant_index_table[102]; int quant_index_table[102];
int category[128]; int category[128];
...@@ -638,7 +645,7 @@ static void mono_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer) { ...@@ -638,7 +645,7 @@ static void mono_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer) {
memset(&category_index, 0, sizeof(category_index)); memset(&category_index, 0, sizeof(category_index));
decode_envelope(q, p, quant_index_table); decode_envelope(q, p, quant_index_table);
q->num_vectors = get_bits(&q->gb,p->log2_numvector_size); q->num_vectors = get_bits(&q->gb, p->log2_numvector_size);
categorize(q, p, quant_index_table, category, category_index); categorize(q, p, quant_index_table, category, category_index);
expand_category(q, category, category_index); expand_category(q, category, category_index);
decode_vectors(q, p, category, quant_index_table, mlt_buffer); decode_vectors(q, p, category, quant_index_table, mlt_buffer);
...@@ -653,22 +660,21 @@ static void mono_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer) { ...@@ -653,22 +660,21 @@ static void mono_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer) {
* @param gain_index index for the block multiplier * @param gain_index index for the block multiplier
* @param gain_index_next index for the next block multiplier * @param gain_index_next index for the next block multiplier
*/ */
static void interpolate_float(COOKContext *q, float *buffer,
static void interpolate_float(COOKContext *q, float* buffer, int gain_index, int gain_index_next)
int gain_index, int gain_index_next){ {
int i; int i;
float fc1, fc2; float fc1, fc2;
fc1 = pow2tab[gain_index+63]; fc1 = pow2tab[gain_index + 63];
if(gain_index == gain_index_next){ //static gain if (gain_index == gain_index_next) { // static gain
for(i=0 ; i<q->gain_size_factor ; i++){ for (i = 0; i < q->gain_size_factor; i++)
buffer[i]*=fc1; buffer[i] *= fc1;
} } else { // smooth gain
} else { //smooth gain fc2 = q->gain_table[11 + (gain_index_next - gain_index)];
fc2 = q->gain_table[11 + (gain_index_next-gain_index)]; for (i = 0; i < q->gain_size_factor; i++) {
for(i=0 ; i<q->gain_size_factor ; i++){ buffer[i] *= fc1;
buffer[i]*=fc1; fc1 *= fc2;
fc1*=fc2;
} }
} }
} }
...@@ -681,9 +687,8 @@ static void interpolate_float(COOKContext *q, float* buffer, ...@@ -681,9 +687,8 @@ static void interpolate_float(COOKContext *q, float* buffer,
* @param gains_ptr current and previous gains * @param gains_ptr current and previous gains
* @param previous_buffer pointer to the previous buffer to be used for overlapping * @param previous_buffer pointer to the previous buffer to be used for overlapping
*/ */
static void imlt_window_float(COOKContext *q, float *inbuffer,
static void imlt_window_float (COOKContext *q, float *inbuffer, cook_gains *gains_ptr, float *previous_buffer)
cook_gains *gains_ptr, float *previous_buffer)
{ {
const float fc = pow2tab[gains_ptr->previous[0] + 63]; const float fc = pow2tab[gains_ptr->previous[0] + 63];
int i; int i;
...@@ -694,10 +699,9 @@ static void imlt_window_float (COOKContext *q, float *inbuffer, ...@@ -694,10 +699,9 @@ static void imlt_window_float (COOKContext *q, float *inbuffer,
*/ */
/* Apply window and overlap */ /* Apply window and overlap */
for(i = 0; i < q->samples_per_channel; i++){ for (i = 0; i < q->samples_per_channel; i++)
inbuffer[i] = inbuffer[i] * fc * q->mlt_window[i] - inbuffer[i] = inbuffer[i] * fc * q->mlt_window[i] -
previous_buffer[i] * q->mlt_window[q->samples_per_channel - 1 - i]; previous_buffer[i] * q->mlt_window[q->samples_per_channel - 1 - i];
}
} }
/** /**
...@@ -711,9 +715,8 @@ static void imlt_window_float (COOKContext *q, float *inbuffer, ...@@ -711,9 +715,8 @@ static void imlt_window_float (COOKContext *q, float *inbuffer,
* @param gains_ptr current and previous gains * @param gains_ptr current and previous gains
* @param previous_buffer pointer to the previous buffer to be used for overlapping * @param previous_buffer pointer to the previous buffer to be used for overlapping
*/ */
static void imlt_gain(COOKContext *q, float *inbuffer, static void imlt_gain(COOKContext *q, float *inbuffer,
cook_gains *gains_ptr, float* previous_buffer) cook_gains *gains_ptr, float *previous_buffer)
{ {
float *buffer0 = q->mono_mdct_output; float *buffer0 = q->mono_mdct_output;
float *buffer1 = q->mono_mdct_output + q->samples_per_channel; float *buffer1 = q->mono_mdct_output + q->samples_per_channel;
...@@ -722,14 +725,13 @@ static void imlt_gain(COOKContext *q, float *inbuffer, ...@@ -722,14 +725,13 @@ static void imlt_gain(COOKContext *q, float *inbuffer,
/* Inverse modified discrete cosine transform */ /* Inverse modified discrete cosine transform */
q->mdct_ctx.imdct_calc(&q->mdct_ctx, q->mono_mdct_output, inbuffer); q->mdct_ctx.imdct_calc(&q->mdct_ctx, q->mono_mdct_output, inbuffer);
q->imlt_window (q, buffer1, gains_ptr, previous_buffer); q->imlt_window(q, buffer1, gains_ptr, previous_buffer);
/* Apply gain profile */ /* Apply gain profile */
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++)
if (gains_ptr->now[i] || gains_ptr->now[i + 1]) if (gains_ptr->now[i] || gains_ptr->now[i + 1])
q->interpolate(q, &buffer1[q->gain_size_factor * i], q->interpolate(q, &buffer1[q->gain_size_factor * i],
gains_ptr->now[i], gains_ptr->now[i + 1]); gains_ptr->now[i], gains_ptr->now[i + 1]);
}
/* Save away the current to be previous block. */ /* Save away the current to be previous block. */
memcpy(previous_buffer, buffer0, memcpy(previous_buffer, buffer0,
...@@ -749,19 +751,18 @@ static void decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab) ...@@ -749,19 +751,18 @@ static void decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab)
int i; int i;
int vlc = get_bits1(&q->gb); int vlc = get_bits1(&q->gb);
int start = cplband[p->js_subband_start]; int start = cplband[p->js_subband_start];
int end = cplband[p->subbands-1]; int end = cplband[p->subbands - 1];
int length = end - start + 1; int length = end - start + 1;
if (start > end) if (start > end)
return; return;
if (vlc) { if (vlc)
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
decouple_tab[start + i] = get_vlc2(&q->gb, p->ccpl.table, p->ccpl.bits, 2); decouple_tab[start + i] = get_vlc2(&q->gb, p->ccpl.table, p->ccpl.bits, 2);
} else { else
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
decouple_tab[start + i] = get_bits(&q->gb, p->js_vlc_bits); decouple_tab[start + i] = get_bits(&q->gb, p->js_vlc_bits);
}
} }
/* /*
...@@ -775,18 +776,18 @@ static void decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab) ...@@ -775,18 +776,18 @@ static void decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab)
* @param mlt_buffer1 pointer to left channel mlt coefficients * @param mlt_buffer1 pointer to left channel mlt coefficients
* @param mlt_buffer2 pointer to right channel mlt coefficients * @param mlt_buffer2 pointer to right channel mlt coefficients
*/ */
static void decouple_float (COOKContext *q, static void decouple_float(COOKContext *q,
COOKSubpacket *p, COOKSubpacket *p,
int subband, int subband,
float f1, float f2, float f1, float f2,
float *decode_buffer, float *decode_buffer,
float *mlt_buffer1, float *mlt_buffer2) float *mlt_buffer1, float *mlt_buffer2)
{ {
int j, tmp_idx; int j, tmp_idx;
for (j=0 ; j<SUBBAND_SIZE ; j++) { for (j = 0; j < SUBBAND_SIZE; j++) {
tmp_idx = ((p->js_subband_start + subband)*SUBBAND_SIZE)+j; tmp_idx = ((p->js_subband_start + subband) * SUBBAND_SIZE) + j;
mlt_buffer1[SUBBAND_SIZE*subband + j] = f1 * decode_buffer[tmp_idx]; mlt_buffer1[SUBBAND_SIZE * subband + j] = f1 * decode_buffer[tmp_idx];
mlt_buffer2[SUBBAND_SIZE*subband + j] = f2 * decode_buffer[tmp_idx]; mlt_buffer2[SUBBAND_SIZE * subband + j] = f2 * decode_buffer[tmp_idx];
} }
} }
...@@ -797,15 +798,15 @@ static void decouple_float (COOKContext *q, ...@@ -797,15 +798,15 @@ static void decouple_float (COOKContext *q,
* @param mlt_buffer1 pointer to left channel mlt coefficients * @param mlt_buffer1 pointer to left channel mlt coefficients
* @param mlt_buffer2 pointer to right channel mlt coefficients * @param mlt_buffer2 pointer to right channel mlt coefficients
*/ */
static void joint_decode(COOKContext *q, COOKSubpacket *p, float *mlt_buffer1,
static void joint_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer1, float *mlt_buffer2)
float* mlt_buffer2) { {
int i,j; int i, j;
int decouple_tab[SUBBAND_SIZE]; int decouple_tab[SUBBAND_SIZE];
float *decode_buffer = q->decode_buffer_0; float *decode_buffer = q->decode_buffer_0;
int idx, cpl_tmp; int idx, cpl_tmp;
float f1,f2; float f1, f2;
const float* cplscale; const float *cplscale;
memset(decouple_tab, 0, sizeof(decouple_tab)); memset(decouple_tab, 0, sizeof(decouple_tab));
memset(decode_buffer, 0, sizeof(q->decode_buffer_0)); memset(decode_buffer, 0, sizeof(q->decode_buffer_0));
...@@ -817,23 +818,23 @@ static void joint_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer1, ...@@ -817,23 +818,23 @@ static void joint_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer1,
mono_decode(q, p, decode_buffer); mono_decode(q, p, decode_buffer);
/* The two channels are stored interleaved in decode_buffer. */ /* The two channels are stored interleaved in decode_buffer. */
for (i=0 ; i<p->js_subband_start ; i++) { for (i = 0; i < p->js_subband_start; i++) {
for (j=0 ; j<SUBBAND_SIZE ; j++) { for (j = 0; j < SUBBAND_SIZE; j++) {
mlt_buffer1[i*20+j] = decode_buffer[i*40+j]; mlt_buffer1[i * 20 + j] = decode_buffer[i * 40 + j];
mlt_buffer2[i*20+j] = decode_buffer[i*40+20+j]; mlt_buffer2[i * 20 + j] = decode_buffer[i * 40 + 20 + j];
} }
} }
/* When we reach js_subband_start (the higher frequencies) /* When we reach js_subband_start (the higher frequencies)
the coefficients are stored in a coupling scheme. */ the coefficients are stored in a coupling scheme. */
idx = (1 << p->js_vlc_bits) - 1; idx = (1 << p->js_vlc_bits) - 1;
for (i=p->js_subband_start ; i<p->subbands ; i++) { for (i = p->js_subband_start; i < p->subbands; i++) {
cpl_tmp = cplband[i]; cpl_tmp = cplband[i];
idx -=decouple_tab[cpl_tmp]; idx -= decouple_tab[cpl_tmp];
cplscale = q->cplscales[p->js_vlc_bits-2]; //choose decoupler table cplscale = q->cplscales[p->js_vlc_bits - 2]; // choose decoupler table
f1 = cplscale[decouple_tab[cpl_tmp]]; f1 = cplscale[decouple_tab[cpl_tmp]];
f2 = cplscale[idx-1]; f2 = cplscale[idx - 1];
q->decouple (q, p, i, f1, f2, decode_buffer, mlt_buffer1, mlt_buffer2); q->decouple(q, p, i, f1, f2, decode_buffer, mlt_buffer1, mlt_buffer2);
idx = (1 << p->js_vlc_bits) - 1; idx = (1 << p->js_vlc_bits) - 1;
} }
} }
...@@ -846,15 +847,14 @@ static void joint_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer1, ...@@ -846,15 +847,14 @@ static void joint_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer1,
* @param inbuffer pointer to raw stream data * @param inbuffer pointer to raw stream data
* @param gains_ptr array of current/prev gain pointers * @param gains_ptr array of current/prev gain pointers
*/ */
static inline void decode_bytes_and_gain(COOKContext *q, COOKSubpacket *p,
static inline void const uint8_t *inbuffer,
decode_bytes_and_gain(COOKContext *q, COOKSubpacket *p, const uint8_t *inbuffer, cook_gains *gains_ptr)
cook_gains *gains_ptr)
{ {
int offset; int offset;
offset = decode_bytes(inbuffer, q->decoded_bytes_buffer, offset = decode_bytes(inbuffer, q->decoded_bytes_buffer,
p->bits_per_subpacket/8); p->bits_per_subpacket / 8);
init_get_bits(&q->gb, q->decoded_bytes_buffer + offset, init_get_bits(&q->gb, q->decoded_bytes_buffer + offset,
p->bits_per_subpacket); p->bits_per_subpacket);
decode_gain_info(&q->gb, gains_ptr->now); decode_gain_info(&q->gb, gains_ptr->now);
...@@ -863,7 +863,7 @@ decode_bytes_and_gain(COOKContext *q, COOKSubpacket *p, const uint8_t *inbuffer, ...@@ -863,7 +863,7 @@ decode_bytes_and_gain(COOKContext *q, COOKSubpacket *p, const uint8_t *inbuffer,
FFSWAP(int *, gains_ptr->now, gains_ptr->previous); FFSWAP(int *, gains_ptr->now, gains_ptr->previous);
} }
/** /**
* Saturate the output signal and interleave. * Saturate the output signal and interleave.
* *
* @param q pointer to the COOKContext * @param q pointer to the COOKContext
...@@ -891,11 +891,9 @@ static void saturate_output_float(COOKContext *q, int chan, float *out) ...@@ -891,11 +891,9 @@ static void saturate_output_float(COOKContext *q, int chan, float *out)
* @param out pointer to the output buffer * @param out pointer to the output buffer
* @param chan 0: left or single channel, 1: right channel * @param chan 0: left or single channel, 1: right channel
*/ */
static inline void mlt_compensate_output(COOKContext *q, float *decode_buffer,
static inline void cook_gains *gains_ptr, float *previous_buffer,
mlt_compensate_output(COOKContext *q, float *decode_buffer, float *out, int chan)
cook_gains *gains_ptr, float *previous_buffer,
float *out, int chan)
{ {
imlt_gain(q, decode_buffer, gains_ptr, previous_buffer); imlt_gain(q, decode_buffer, gains_ptr, previous_buffer);
if (out) if (out)
...@@ -916,11 +914,10 @@ static void decode_subpacket(COOKContext *q, COOKSubpacket *p, ...@@ -916,11 +914,10 @@ static void decode_subpacket(COOKContext *q, COOKSubpacket *p,
{ {
int sub_packet_size = p->size; int sub_packet_size = p->size;
/* packet dump */ /* packet dump */
// for (i=0 ; i<sub_packet_size ; i++) { // for (i = 0; i < sub_packet_size ; i++)
// av_log(q->avctx, AV_LOG_ERROR, "%02x", inbuffer[i]); // av_log(q->avctx, AV_LOG_ERROR, "%02x", inbuffer[i]);
// } // av_log(q->avctx, AV_LOG_ERROR, "\n");
// av_log(q->avctx, AV_LOG_ERROR, "\n"); memset(q->decode_buffer_1, 0, sizeof(q->decode_buffer_1));
memset(q->decode_buffer_1,0,sizeof(q->decode_buffer_1));
decode_bytes_and_gain(q, p, inbuffer, &p->gains1); decode_bytes_and_gain(q, p, inbuffer, &p->gains1);
if (p->joint_stereo) { if (p->joint_stereo) {
...@@ -929,7 +926,7 @@ static void decode_subpacket(COOKContext *q, COOKSubpacket *p, ...@@ -929,7 +926,7 @@ static void decode_subpacket(COOKContext *q, COOKSubpacket *p,
mono_decode(q, p, q->decode_buffer_1); mono_decode(q, p, q->decode_buffer_1);
if (p->num_channels == 2) { if (p->num_channels == 2) {
decode_bytes_and_gain(q, p, inbuffer + sub_packet_size/2, &p->gains2); decode_bytes_and_gain(q, p, inbuffer + sub_packet_size / 2, &p->gains2);
mono_decode(q, p, q->decode_buffer_2); mono_decode(q, p, q->decode_buffer_2);
} }
} }
...@@ -937,16 +934,13 @@ static void decode_subpacket(COOKContext *q, COOKSubpacket *p, ...@@ -937,16 +934,13 @@ static void decode_subpacket(COOKContext *q, COOKSubpacket *p,
mlt_compensate_output(q, q->decode_buffer_1, &p->gains1, mlt_compensate_output(q, q->decode_buffer_1, &p->gains1,
p->mono_previous_buffer1, outbuffer, p->ch_idx); p->mono_previous_buffer1, outbuffer, p->ch_idx);
if (p->num_channels == 2) { if (p->num_channels == 2)
if (p->joint_stereo) { if (p->joint_stereo)
mlt_compensate_output(q, q->decode_buffer_2, &p->gains1, mlt_compensate_output(q, q->decode_buffer_2, &p->gains1,
p->mono_previous_buffer2, outbuffer, p->ch_idx + 1); p->mono_previous_buffer2, outbuffer, p->ch_idx + 1);
} else { else
mlt_compensate_output(q, q->decode_buffer_2, &p->gains2, mlt_compensate_output(q, q->decode_buffer_2, &p->gains2,
p->mono_previous_buffer2, outbuffer, p->ch_idx + 1); p->mono_previous_buffer2, outbuffer, p->ch_idx + 1);
}
}
} }
...@@ -955,7 +949,6 @@ static void decode_subpacket(COOKContext *q, COOKSubpacket *p, ...@@ -955,7 +949,6 @@ static void decode_subpacket(COOKContext *q, COOKSubpacket *p,
* *
* @param avctx pointer to the AVCodecContext * @param avctx pointer to the AVCodecContext
*/ */
static int cook_decode_frame(AVCodecContext *avctx, void *data, static int cook_decode_frame(AVCodecContext *avctx, void *data,
int *got_frame_ptr, AVPacket *avpkt) int *got_frame_ptr, AVPacket *avpkt)
{ {
...@@ -977,30 +970,37 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data, ...@@ -977,30 +970,37 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data,
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return ret; return ret;
} }
samples = (float *)q->frame.data[0]; samples = (float *) q->frame.data[0];
} }
/* estimate subpacket sizes */ /* estimate subpacket sizes */
q->subpacket[0].size = avctx->block_align; q->subpacket[0].size = avctx->block_align;
for(i=1;i<q->num_subpackets;i++){ for (i = 1; i < q->num_subpackets; i++) {
q->subpacket[i].size = 2 * buf[avctx->block_align - q->num_subpackets + i]; q->subpacket[i].size = 2 * buf[avctx->block_align - q->num_subpackets + i];
q->subpacket[0].size -= q->subpacket[i].size + 1; q->subpacket[0].size -= q->subpacket[i].size + 1;
if (q->subpacket[0].size < 0) { if (q->subpacket[0].size < 0) {
av_log(avctx,AV_LOG_DEBUG,"frame subpacket size total > avctx->block_align!\n"); av_log(avctx, AV_LOG_DEBUG,
"frame subpacket size total > avctx->block_align!\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
} }
/* decode supbackets */ /* decode supbackets */
for(i=0;i<q->num_subpackets;i++){ for (i = 0; i < q->num_subpackets; i++) {
q->subpacket[i].bits_per_subpacket = (q->subpacket[i].size*8)>>q->subpacket[i].bits_per_subpdiv; q->subpacket[i].bits_per_subpacket = (q->subpacket[i].size * 8) >>
q->subpacket[i].bits_per_subpdiv;
q->subpacket[i].ch_idx = chidx; q->subpacket[i].ch_idx = chidx;
av_log(avctx,AV_LOG_DEBUG,"subpacket[%i] size %i js %i %i block_align %i\n",i,q->subpacket[i].size,q->subpacket[i].joint_stereo,offset,avctx->block_align); av_log(avctx, AV_LOG_DEBUG,
"subpacket[%i] size %i js %i %i block_align %i\n",
i, q->subpacket[i].size, q->subpacket[i].joint_stereo, offset,
avctx->block_align);
decode_subpacket(q, &q->subpacket[i], buf + offset, samples); decode_subpacket(q, &q->subpacket[i], buf + offset, samples);
offset += q->subpacket[i].size; offset += q->subpacket[i].size;
chidx += q->subpacket[i].num_channels; chidx += q->subpacket[i].num_channels;
av_log(avctx,AV_LOG_DEBUG,"subpacket[%i] %i %i\n",i,q->subpacket[i].size * 8,get_bits_count(&q->gb)); av_log(avctx, AV_LOG_DEBUG, "subpacket[%i] %i %i\n",
i, q->subpacket[i].size * 8, get_bits_count(&q->gb));
} }
/* Discard the first two frames: no valid audio. */ /* Discard the first two frames: no valid audio. */
...@@ -1010,8 +1010,8 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data, ...@@ -1010,8 +1010,8 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data,
return avctx->block_align; return avctx->block_align;
} }
*got_frame_ptr = 1; *got_frame_ptr = 1;
*(AVFrame *)data = q->frame; *(AVFrame *) data = q->frame;
return avctx->block_align; return avctx->block_align;
} }
...@@ -1020,34 +1020,34 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data, ...@@ -1020,34 +1020,34 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data,
static void dump_cook_context(COOKContext *q) static void dump_cook_context(COOKContext *q)
{ {
//int i=0; //int i=0;
#define PRINT(a,b) av_log(q->avctx,AV_LOG_ERROR," %s = %d\n", a, b); #define PRINT(a, b) av_log(q->avctx, AV_LOG_ERROR, " %s = %d\n", a, b);
av_log(q->avctx,AV_LOG_ERROR,"COOKextradata\n"); av_log(q->avctx, AV_LOG_ERROR, "COOKextradata\n");
av_log(q->avctx,AV_LOG_ERROR,"cookversion=%x\n",q->subpacket[0].cookversion); av_log(q->avctx, AV_LOG_ERROR, "cookversion=%x\n", q->subpacket[0].cookversion);
if (q->subpacket[0].cookversion > STEREO) { if (q->subpacket[0].cookversion > STEREO) {
PRINT("js_subband_start",q->subpacket[0].js_subband_start); PRINT("js_subband_start", q->subpacket[0].js_subband_start);
PRINT("js_vlc_bits",q->subpacket[0].js_vlc_bits); PRINT("js_vlc_bits", q->subpacket[0].js_vlc_bits);
} }
av_log(q->avctx,AV_LOG_ERROR,"COOKContext\n"); av_log(q->avctx, AV_LOG_ERROR, "COOKContext\n");
PRINT("nb_channels",q->nb_channels); PRINT("nb_channels", q->nb_channels);
PRINT("bit_rate",q->bit_rate); PRINT("bit_rate", q->bit_rate);
PRINT("sample_rate",q->sample_rate); PRINT("sample_rate", q->sample_rate);
PRINT("samples_per_channel",q->subpacket[0].samples_per_channel); PRINT("samples_per_channel", q->subpacket[0].samples_per_channel);
PRINT("samples_per_frame",q->subpacket[0].samples_per_frame); PRINT("samples_per_frame", q->subpacket[0].samples_per_frame);
PRINT("subbands",q->subpacket[0].subbands); PRINT("subbands", q->subpacket[0].subbands);
PRINT("js_subband_start",q->subpacket[0].js_subband_start); PRINT("js_subband_start", q->subpacket[0].js_subband_start);
PRINT("log2_numvector_size",q->subpacket[0].log2_numvector_size); PRINT("log2_numvector_size", q->subpacket[0].log2_numvector_size);
PRINT("numvector_size",q->subpacket[0].numvector_size); PRINT("numvector_size", q->subpacket[0].numvector_size);
PRINT("total_subbands",q->subpacket[0].total_subbands); PRINT("total_subbands", q->subpacket[0].total_subbands);
} }
#endif #endif
static av_cold int cook_count_channels(unsigned int mask){ static av_cold int cook_count_channels(unsigned int mask)
{
int i; int i;
int channels = 0; int channels = 0;
for(i = 0;i<32;i++){ for (i = 0; i < 32; i++)
if(mask & (1<<i)) if (mask & (1 << i))
++channels; ++channels;
}
return channels; return channels;
} }
...@@ -1056,7 +1056,6 @@ static av_cold int cook_count_channels(unsigned int mask){ ...@@ -1056,7 +1056,6 @@ static av_cold int cook_count_channels(unsigned int mask){
* *
* @param avctx pointer to the AVCodecContext * @param avctx pointer to the AVCodecContext
*/ */
static av_cold int cook_decode_init(AVCodecContext *avctx) static av_cold int cook_decode_init(AVCodecContext *avctx)
{ {
COOKContext *q = avctx->priv_data; COOKContext *q = avctx->priv_data;
...@@ -1070,10 +1069,10 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) ...@@ -1070,10 +1069,10 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
/* Take care of the codec specific extradata. */ /* Take care of the codec specific extradata. */
if (extradata_size <= 0) { if (extradata_size <= 0) {
av_log(avctx,AV_LOG_ERROR,"Necessary extradata missing!\n"); av_log(avctx, AV_LOG_ERROR, "Necessary extradata missing!\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
av_log(avctx,AV_LOG_DEBUG,"codecdata_length=%d\n",avctx->extradata_size); av_log(avctx, AV_LOG_DEBUG, "codecdata_length=%d\n", avctx->extradata_size);
/* Take data from the AVCodecContext (RM container). */ /* Take data from the AVCodecContext (RM container). */
q->sample_rate = avctx->sample_rate; q->sample_rate = avctx->sample_rate;
...@@ -1083,17 +1082,17 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) ...@@ -1083,17 +1082,17 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
/* Initialize RNG. */ /* Initialize RNG. */
av_lfg_init(&q->random_state, 0); av_lfg_init(&q->random_state, 0);
while(edata_ptr < edata_ptr_end){ while (edata_ptr < edata_ptr_end) {
/* 8 for mono, 16 for stereo, ? for multichannel /* 8 for mono, 16 for stereo, ? for multichannel
Swap to right endianness so we don't need to care later on. */ Swap to right endianness so we don't need to care later on. */
if (extradata_size >= 8){ if (extradata_size >= 8) {
q->subpacket[s].cookversion = bytestream_get_be32(&edata_ptr); q->subpacket[s].cookversion = bytestream_get_be32(&edata_ptr);
q->subpacket[s].samples_per_frame = bytestream_get_be16(&edata_ptr); q->subpacket[s].samples_per_frame = bytestream_get_be16(&edata_ptr);
q->subpacket[s].subbands = bytestream_get_be16(&edata_ptr); q->subpacket[s].subbands = bytestream_get_be16(&edata_ptr);
extradata_size -= 8; extradata_size -= 8;
} }
if (extradata_size >= 8) { if (extradata_size >= 8) {
bytestream_get_be32(&edata_ptr); //Unknown unused bytestream_get_be32(&edata_ptr); // Unknown unused
q->subpacket[s].js_subband_start = bytestream_get_be16(&edata_ptr); q->subpacket[s].js_subband_start = bytestream_get_be16(&edata_ptr);
q->subpacket[s].js_vlc_bits = bytestream_get_be16(&edata_ptr); q->subpacket[s].js_vlc_bits = bytestream_get_be16(&edata_ptr);
extradata_size -= 8; extradata_size -= 8;
...@@ -1110,69 +1109,72 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) ...@@ -1110,69 +1109,72 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
/* Initialize version-dependent variables */ /* Initialize version-dependent variables */
av_log(avctx,AV_LOG_DEBUG,"subpacket[%i].cookversion=%x\n",s,q->subpacket[s].cookversion); av_log(avctx, AV_LOG_DEBUG, "subpacket[%i].cookversion=%x\n", s,
q->subpacket[s].cookversion);
q->subpacket[s].joint_stereo = 0; q->subpacket[s].joint_stereo = 0;
switch (q->subpacket[s].cookversion) { switch (q->subpacket[s].cookversion) {
case MONO: case MONO:
if (q->nb_channels != 1) { if (q->nb_channels != 1) {
av_log_ask_for_sample(avctx, "Container channels != 1.\n"); av_log_ask_for_sample(avctx, "Container channels != 1.\n");
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
} }
av_log(avctx,AV_LOG_DEBUG,"MONO\n"); av_log(avctx, AV_LOG_DEBUG, "MONO\n");
break; break;
case STEREO: case STEREO:
if (q->nb_channels != 1) { if (q->nb_channels != 1) {
q->subpacket[s].bits_per_subpdiv = 1; q->subpacket[s].bits_per_subpdiv = 1;
q->subpacket[s].num_channels = 2; q->subpacket[s].num_channels = 2;
} }
av_log(avctx,AV_LOG_DEBUG,"STEREO\n"); av_log(avctx, AV_LOG_DEBUG, "STEREO\n");
break; break;
case JOINT_STEREO: case JOINT_STEREO:
if (q->nb_channels != 2) { if (q->nb_channels != 2) {
av_log_ask_for_sample(avctx, "Container channels != 2.\n"); av_log_ask_for_sample(avctx, "Container channels != 2.\n");
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
} }
av_log(avctx,AV_LOG_DEBUG,"JOINT_STEREO\n"); av_log(avctx, AV_LOG_DEBUG, "JOINT_STEREO\n");
if (avctx->extradata_size >= 16){ if (avctx->extradata_size >= 16) {
q->subpacket[s].total_subbands = q->subpacket[s].subbands + q->subpacket[s].js_subband_start; q->subpacket[s].total_subbands = q->subpacket[s].subbands +
q->subpacket[s].joint_stereo = 1; q->subpacket[s].js_subband_start;
q->subpacket[s].num_channels = 2; q->subpacket[s].joint_stereo = 1;
} q->subpacket[s].num_channels = 2;
}
if (q->subpacket[s].samples_per_channel > 256) {
q->subpacket[s].log2_numvector_size = 6;
}
if (q->subpacket[s].samples_per_channel > 512) {
q->subpacket[s].log2_numvector_size = 7;
}
break;
case MC_COOK:
av_log(avctx, AV_LOG_DEBUG, "MULTI_CHANNEL\n");
if (extradata_size >= 4)
channel_mask |= q->subpacket[s].channel_mask = bytestream_get_be32(&edata_ptr);
if (cook_count_channels(q->subpacket[s].channel_mask) > 1) {
q->subpacket[s].total_subbands = q->subpacket[s].subbands +
q->subpacket[s].js_subband_start;
q->subpacket[s].joint_stereo = 1;
q->subpacket[s].num_channels = 2;
q->subpacket[s].samples_per_channel = q->subpacket[s].samples_per_frame >> 1;
if (q->subpacket[s].samples_per_channel > 256) { if (q->subpacket[s].samples_per_channel > 256) {
q->subpacket[s].log2_numvector_size = 6; q->subpacket[s].log2_numvector_size = 6;
} }
if (q->subpacket[s].samples_per_channel > 512) { if (q->subpacket[s].samples_per_channel > 512) {
q->subpacket[s].log2_numvector_size = 7; q->subpacket[s].log2_numvector_size = 7;
} }
break; } else
case MC_COOK: q->subpacket[s].samples_per_channel = q->subpacket[s].samples_per_frame;
av_log(avctx,AV_LOG_DEBUG,"MULTI_CHANNEL\n");
if(extradata_size >= 4)
channel_mask |= q->subpacket[s].channel_mask = bytestream_get_be32(&edata_ptr);
if(cook_count_channels(q->subpacket[s].channel_mask) > 1){
q->subpacket[s].total_subbands = q->subpacket[s].subbands + q->subpacket[s].js_subband_start;
q->subpacket[s].joint_stereo = 1;
q->subpacket[s].num_channels = 2;
q->subpacket[s].samples_per_channel = q->subpacket[s].samples_per_frame >> 1;
if (q->subpacket[s].samples_per_channel > 256) {
q->subpacket[s].log2_numvector_size = 6;
}
if (q->subpacket[s].samples_per_channel > 512) {
q->subpacket[s].log2_numvector_size = 7;
}
}else
q->subpacket[s].samples_per_channel = q->subpacket[s].samples_per_frame;
break; break;
default: default:
av_log_ask_for_sample(avctx, "Unknown Cook version.\n"); av_log_ask_for_sample(avctx, "Unknown Cook version.\n");
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
} }
if(s > 1 && q->subpacket[s].samples_per_channel != q->samples_per_channel) { if (s > 1 && q->subpacket[s].samples_per_channel != q->samples_per_channel) {
av_log(avctx,AV_LOG_ERROR,"different number of samples per channel!\n"); av_log(avctx, AV_LOG_ERROR, "different number of samples per channel!\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} else } else
q->samples_per_channel = q->subpacket[0].samples_per_channel; q->samples_per_channel = q->subpacket[0].samples_per_channel;
...@@ -1187,9 +1189,10 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) ...@@ -1187,9 +1189,10 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
} }
if ((q->subpacket[s].js_vlc_bits > 6) || (q->subpacket[s].js_vlc_bits < 2*q->subpacket[s].joint_stereo)) { if ((q->subpacket[s].js_vlc_bits > 6) ||
av_log(avctx,AV_LOG_ERROR,"js_vlc_bits = %d, only >= %d and <= 6 allowed!\n", (q->subpacket[s].js_vlc_bits < 2 * q->subpacket[s].joint_stereo)) {
q->subpacket[s].js_vlc_bits, 2*q->subpacket[s].joint_stereo); av_log(avctx, AV_LOG_ERROR, "js_vlc_bits = %d, only >= %d and <= 6 allowed!\n",
q->subpacket[s].js_vlc_bits, 2 * q->subpacket[s].joint_stereo);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
...@@ -1218,16 +1221,16 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) ...@@ -1218,16 +1221,16 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
return ret; return ret;
if(avctx->block_align >= UINT_MAX/2) if (avctx->block_align >= UINT_MAX / 2)
return AVERROR(EINVAL); return AVERROR(EINVAL);
/* Pad the databuffer with: /* Pad the databuffer with:
DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(), DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(),
FF_INPUT_BUFFER_PADDING_SIZE, for the bitstreamreader. */ FF_INPUT_BUFFER_PADDING_SIZE, for the bitstreamreader. */
q->decoded_bytes_buffer = q->decoded_bytes_buffer =
av_mallocz(avctx->block_align av_mallocz(avctx->block_align
+ DECODE_BYTES_PAD1(avctx->block_align) + DECODE_BYTES_PAD1(avctx->block_align)
+ FF_INPUT_BUFFER_PADDING_SIZE); + FF_INPUT_BUFFER_PADDING_SIZE);
if (q->decoded_bytes_buffer == NULL) if (q->decoded_bytes_buffer == NULL)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
...@@ -1245,7 +1248,8 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) ...@@ -1245,7 +1248,8 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
} }
/* Try to catch some obviously faulty streams, othervise it might be exploitable */ /* Try to catch some obviously faulty streams, othervise it might be exploitable */
if ((q->samples_per_channel == 256) || (q->samples_per_channel == 512) || (q->samples_per_channel == 1024)) { if ((q->samples_per_channel == 256) || (q->samples_per_channel == 512)
|| (q->samples_per_channel == 1024)) {
} else { } else {
av_log_ask_for_sample(avctx, av_log_ask_for_sample(avctx,
"unknown amount of samples_per_channel = %d\n", "unknown amount of samples_per_channel = %d\n",
...@@ -1257,7 +1261,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) ...@@ -1257,7 +1261,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
if (channel_mask) if (channel_mask)
avctx->channel_layout = channel_mask; avctx->channel_layout = channel_mask;
else else
avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; avctx->channel_layout = (avctx->channels == 2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
avcodec_get_frame_defaults(&q->frame); avcodec_get_frame_defaults(&q->frame);
avctx->coded_frame = &q->frame; avctx->coded_frame = &q->frame;
...@@ -1268,16 +1272,14 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) ...@@ -1268,16 +1272,14 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
return 0; return 0;
} }
AVCodec ff_cook_decoder = {
AVCodec ff_cook_decoder = .name = "cook",
{ .type = AVMEDIA_TYPE_AUDIO,
.name = "cook", .id = CODEC_ID_COOK,
.type = AVMEDIA_TYPE_AUDIO,
.id = CODEC_ID_COOK,
.priv_data_size = sizeof(COOKContext), .priv_data_size = sizeof(COOKContext),
.init = cook_decode_init, .init = cook_decode_init,
.close = cook_decode_close, .close = cook_decode_close,
.decode = cook_decode_frame, .decode = cook_decode_frame,
.capabilities = CODEC_CAP_DR1, .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("COOK"), .long_name = NULL_IF_CONFIG_SMALL("COOK"),
}; };
...@@ -1436,28 +1436,30 @@ static int mp_decode_layer3(MPADecodeContext *s) ...@@ -1436,28 +1436,30 @@ static int mp_decode_layer3(MPADecodeContext *s)
memcpy(s->last_buf + s->last_buf_size, ptr, EXTRABYTES); memcpy(s->last_buf + s->last_buf_size, ptr, EXTRABYTES);
s->in_gb = s->gb; s->in_gb = s->gb;
init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8); init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8);
#if CONFIG_SAFE_BITSTREAM_READER #if !UNCHECKED_BITSTREAM_READER
s->gb.size_in_bits_plus8 += EXTRABYTES * 8; s->gb.size_in_bits_plus8 += EXTRABYTES * 8;
#endif #endif
skip_bits_long(&s->gb, 8*(s->last_buf_size - main_data_begin)); s->last_buf_size <<= 3;
} for (gr = 0, ch = 0; gr < nb_granules && (s->last_buf_size >> 3) < main_data_begin; gr++, ch = 0) {
for (; ch < s->nb_channels && (s->last_buf_size >> 3) < main_data_begin; ch++) {
for (gr = 0; gr < nb_granules; gr++) { g = &s->granules[ch][gr];
for (ch = 0; ch < s->nb_channels; ch++) { s->last_buf_size += g->part2_3_length;
g = &s->granules[ch][gr];
if (get_bits_count(&s->gb) < 0) {
av_log(s->avctx, AV_LOG_DEBUG, "mdb:%d, lastbuf:%d skipping granule %d\n",
main_data_begin, s->last_buf_size, gr);
skip_bits_long(&s->gb, g->part2_3_length);
memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid)); memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));
if (get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer) {
skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits);
s->gb = s->in_gb;
s->in_gb.buffer = NULL;
}
continue;
} }
}
skip_bits_long(&s->gb, s->last_buf_size - 8 * main_data_begin);
if (get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer) {
skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits);
s->gb = s->in_gb;
s->in_gb.buffer = NULL;
}
} else {
gr = ch = 0;
}
for (; gr < nb_granules; gr++, ch = 0) {
for (; ch < s->nb_channels; ch++) {
g = &s->granules[ch][gr];
bits_pos = get_bits_count(&s->gb); bits_pos = get_bits_count(&s->gb);
if (!s->lsf) { if (!s->lsf) {
......
...@@ -371,7 +371,7 @@ static const AVOption options[]={ ...@@ -371,7 +371,7 @@ static const AVOption options[]={
{"float", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_AA_FLOAT }, INT_MIN, INT_MAX, V|D, "aa"}, {"float", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_AA_FLOAT }, INT_MIN, INT_MAX, V|D, "aa"},
#endif #endif
{"qns", "quantizer noise shaping", OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"qns", "quantizer noise shaping", OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
{"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.dbl = 1 }, 0, INT_MAX, V|E|D, "threads"}, {"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, V|E|D, "threads"},
{"auto", "detect a good number of threads", 0, AV_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"}, {"auto", "detect a good number of threads", 0, AV_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"},
{"me_threshold", "motion estimaton threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"me_threshold", "motion estimaton threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
{"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
......
...@@ -34,9 +34,11 @@ ...@@ -34,9 +34,11 @@
#if HAVE_SCHED_GETAFFINITY #if HAVE_SCHED_GETAFFINITY
#define _GNU_SOURCE #define _GNU_SOURCE
#include <sched.h> #include <sched.h>
#elif HAVE_GETSYSTEMINFO #endif
#if HAVE_GETSYSTEMINFO
#include <windows.h> #include <windows.h>
#elif HAVE_SYSCTL #endif
#if HAVE_SYSCTL
#if HAVE_SYS_PARAM_H #if HAVE_SYS_PARAM_H
#include <sys/param.h> #include <sys/param.h>
#endif #endif
...@@ -44,6 +46,9 @@ ...@@ -44,6 +46,9 @@
#include <sys/param.h> #include <sys/param.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
#if HAVE_SYSCONF
#include <unistd.h>
#endif
#include "avcodec.h" #include "avcodec.h"
#include "internal.h" #include "internal.h"
...@@ -178,6 +183,10 @@ static int get_logical_cpus(AVCodecContext *avctx) ...@@ -178,6 +183,10 @@ static int get_logical_cpus(AVCodecContext *avctx)
ret = sysctl(mib, 2, &nb_cpus, &len, NULL, 0); ret = sysctl(mib, 2, &nb_cpus, &len, NULL, 0);
if (ret == -1) if (ret == -1)
nb_cpus = 0; nb_cpus = 0;
#elif HAVE_SYSCONF && defined(_SC_NPROC_ONLN)
nb_cpus = sysconf(_SC_NPROC_ONLN);
#elif HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN)
nb_cpus = sysconf(_SC_NPROCESSORS_ONLN);
#endif #endif
av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus); av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);
return FFMIN(nb_cpus, MAX_AUTO_THREADS); return FFMIN(nb_cpus, MAX_AUTO_THREADS);
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#define LIBAVCODEC_VERSION_MAJOR 53 #define LIBAVCODEC_VERSION_MAJOR 53
#define LIBAVCODEC_VERSION_MINOR 49 #define LIBAVCODEC_VERSION_MINOR 49
#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_MICRO 101
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \ LIBAVCODEC_VERSION_MINOR, \
......
...@@ -2377,9 +2377,14 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) ...@@ -2377,9 +2377,14 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
int i, count, ret, read_size, j; int i, count, ret, read_size, j;
AVStream *st; AVStream *st;
AVPacket pkt1, *pkt; AVPacket pkt1, *pkt;
AVDictionary *one_thread_opt = NULL;
int64_t old_offset = avio_tell(ic->pb); int64_t old_offset = avio_tell(ic->pb);
int orig_nb_streams = ic->nb_streams; // new streams might appear, no options for those int orig_nb_streams = ic->nb_streams; // new streams might appear, no options for those
/* this function doesn't flush the decoders, so force thread count
* to 1 to fix behavior when thread count > number of frames in the file */
av_dict_set(&one_thread_opt, "threads", "1", 0);
for(i=0;i<ic->nb_streams;i++) { for(i=0;i<ic->nb_streams;i++) {
AVCodec *codec; AVCodec *codec;
st = ic->streams[i]; st = ic->streams[i];
...@@ -2404,17 +2409,18 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) ...@@ -2404,17 +2409,18 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
/* this function doesn't flush the decoders, so force thread count /* this function doesn't flush the decoders, so force thread count
* to 1 to fix behavior when thread count > number of frames in the file */ * to 1 to fix behavior when thread count > number of frames in the file */
if (options) if (options)
av_dict_set(&options[i], "threads", 0, 0); av_dict_set(&options[i], "threads", "1", 0);
/* Ensure that subtitle_header is properly set. */ /* Ensure that subtitle_header is properly set. */
if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
&& codec && !st->codec->codec) && codec && !st->codec->codec)
avcodec_open2(st->codec, codec, options ? &options[i] : NULL); avcodec_open2(st->codec, codec, options ? &options[i] : &one_thread_opt);
//try to just open decoders, in case this is enough to get parameters //try to just open decoders, in case this is enough to get parameters
if(!has_codec_parameters(st->codec)){ if(!has_codec_parameters(st->codec)){
if (codec && !st->codec->codec) if (codec && !st->codec->codec)
avcodec_open2(st->codec, codec, options ? &options[i] : NULL); avcodec_open2(st->codec, codec, options ? &options[i]
: &one_thread_opt);
} }
} }
...@@ -2556,7 +2562,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) ...@@ -2556,7 +2562,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
least one frame of codec data, this makes sure the codec initializes least one frame of codec data, this makes sure the codec initializes
the channel configuration and does not only trust the values from the container. the channel configuration and does not only trust the values from the container.
*/ */
try_decode_frame(st, pkt, (options && i < orig_nb_streams )? &options[i] : NULL); try_decode_frame(st, pkt, (options && i < orig_nb_streams )? &options[i]
: &one_thread_opt);
st->codec_info_nb_frames++; st->codec_info_nb_frames++;
count++; count++;
...@@ -2677,8 +2684,12 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) ...@@ -2677,8 +2684,12 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
#endif #endif
find_stream_info_err: find_stream_info_err:
for (i=0; i < ic->nb_streams; i++) for (i=0; i < ic->nb_streams; i++) {
if (ic->streams[i]->codec)
ic->streams[i]->codec->thread_count = 0;
av_freep(&ic->streams[i]->info); av_freep(&ic->streams[i]->info);
}
av_dict_free(&one_thread_opt);
return ret; return ret;
} }
......
...@@ -49,6 +49,7 @@ include $(SRC_PATH)/tests/fate/atrac.mak ...@@ -49,6 +49,7 @@ include $(SRC_PATH)/tests/fate/atrac.mak
include $(SRC_PATH)/tests/fate/audio.mak include $(SRC_PATH)/tests/fate/audio.mak
include $(SRC_PATH)/tests/fate/dct.mak include $(SRC_PATH)/tests/fate/dct.mak
include $(SRC_PATH)/tests/fate/demux.mak include $(SRC_PATH)/tests/fate/demux.mak
include $(SRC_PATH)/tests/fate/dfa.mak
include $(SRC_PATH)/tests/fate/dpcm.mak include $(SRC_PATH)/tests/fate/dpcm.mak
include $(SRC_PATH)/tests/fate/ea.mak include $(SRC_PATH)/tests/fate/ea.mak
include $(SRC_PATH)/tests/fate/fft.mak include $(SRC_PATH)/tests/fate/fft.mak
......
FATE_DFA += fate-dfa1
fate-dfa1: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0000.dfa
FATE_DFA += fate-dfa2
fate-dfa2: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0001.dfa
FATE_DFA += fate-dfa3
fate-dfa3: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0002.dfa
FATE_DFA += fate-dfa4
fate-dfa4: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0003.dfa
FATE_DFA += fate-dfa5
fate-dfa5: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0004.dfa
FATE_DFA += fate-dfa6
fate-dfa6: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0005.dfa
FATE_DFA += fate-dfa7
fate-dfa7: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0006.dfa
FATE_DFA += fate-dfa8
fate-dfa8: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0007.dfa
FATE_DFA += fate-dfa9
fate-dfa9: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0008.dfa
FATE_DFA += fate-dfa10
fate-dfa10: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0009.dfa
FATE_DFA += fate-dfa11
fate-dfa11: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0010.dfa
FATE_TESTS += $(FATE_DFA)
fate-dfa: $(FATE_DFA)
0, 0, 308224, 0x7264439e
0, 11520, 308224, 0xe1734f4b
0, 23040, 308224, 0x9cfe28a4
0, 34560, 308224, 0xebb6ec8b
0, 46080, 308224, 0xaef16ca7
0, 57600, 308224, 0x0390b439
0, 69120, 308224, 0xe69bd008
0, 80640, 308224, 0xa1818468
0, 92160, 308224, 0x9d6e7d82
0, 103680, 308224, 0x54971a9e
0, 115200, 308224, 0xe14e15a8
0, 126720, 308224, 0xa026cf3f
0, 138240, 308224, 0xf8921be4
0, 149760, 308224, 0xf49a42cc
0, 161280, 308224, 0xa4108f17
0, 172800, 308224, 0xfa79cbfe
0, 184320, 308224, 0x3431f47b
0, 195840, 308224, 0x72aa3426
0, 207360, 308224, 0x81159f85
0, 218880, 308224, 0x04bcb289
0, 230400, 308224, 0xb1dabbcd
0, 241920, 308224, 0x7e851c8c
0, 253440, 308224, 0x8bdea0bf
0, 264960, 308224, 0xecacdb11
0, 276480, 308224, 0xec4c6c41
0, 0, 65024, 0x8f31c3f0
0, 6390, 65024, 0x164a2d82
0, 12780, 65024, 0xbb72b738
0, 19170, 65024, 0x45b93e3a
0, 25560, 65024, 0xcc4019df
0, 31950, 65024, 0x64644557
0, 38340, 65024, 0xb4584b28
0, 44730, 65024, 0x1d87966a
0, 0, 65024, 0x10db5645
0, 6390, 65024, 0xb5d8a5bd
0, 12780, 65024, 0xc9555f27
0, 19170, 65024, 0x74c43f84
0, 25560, 65024, 0x5b2445b0
0, 31950, 65024, 0x8bd5be38
0, 38340, 65024, 0x75ec97da
0, 44730, 65024, 0x34416636
0, 51120, 65024, 0x9cc2abcf
0, 0, 308224, 0x8dc9803f
0, 6390, 308224, 0x06308b37
0, 12780, 308224, 0xb8cb7be6
0, 19170, 308224, 0xc538862b
0, 25560, 308224, 0x8d4b7702
0, 31950, 308224, 0x97a479f0
0, 38340, 308224, 0x63d08e67
0, 44730, 308224, 0x470e8a18
0, 51120, 308224, 0x08aa6be4
0, 57510, 308224, 0x3b2f6f9a
0, 63900, 308224, 0xf0f1490c
0, 70290, 308224, 0xcb8b2ec5
0, 76680, 308224, 0xab361e75
0, 83070, 308224, 0x485aed6d
0, 89460, 308224, 0xd3e7ecb7
0, 95850, 308224, 0xa2c0d561
0, 102240, 308224, 0xd8f8ccd4
0, 0, 65024, 0xbf9d558b
0, 9000, 65024, 0x4c7ea2ac
0, 18000, 65024, 0x4931827c
0, 27000, 65024, 0x5a9e09a7
0, 36000, 65024, 0x2b76eca9
0, 45000, 65024, 0xd5400a96
0, 54000, 65024, 0xcca17f23
0, 63000, 65024, 0xebca0dec
0, 72000, 65024, 0x07a73cfc
0, 81000, 65024, 0xdd5e4620
0, 0, 308224, 0x5a24821c
0, 12780, 308224, 0xa1ecf793
0, 25560, 308224, 0xcb91afa5
0, 38340, 308224, 0x8b7e85b9
0, 51120, 308224, 0xe4755628
0, 63900, 308224, 0xe4755628
0, 76680, 308224, 0xe4755628
0, 89460, 308224, 0xe4755628
0, 102240, 308224, 0xe4755628
0, 115020, 308224, 0xe4755628
0, 127800, 308224, 0xdd6ca523
0, 140580, 308224, 0x961ba417
0, 153360, 308224, 0x5ed15e7f
0, 0, 65024, 0x54831a1a
0, 9000, 65024, 0x110f5bad
0, 18000, 65024, 0xdd4f97fa
0, 27000, 65024, 0x1ab375b2
0, 36000, 65024, 0x311b51d3
0, 45000, 65024, 0xb0614f71
0, 54000, 65024, 0x6d968927
0, 63000, 65024, 0x28d85028
0, 72000, 65024, 0x74ea41f5
0, 81000, 65024, 0x3480b067
0, 90000, 65024, 0x3e1115d4
0, 99000, 65024, 0x0c715b57
0, 108000, 65024, 0x3acaaea3
0, 117000, 65024, 0x1b60f1e8
0, 126000, 65024, 0xcee14632
0, 0, 65024, 0x190f2398
0, 6390, 65024, 0x19d8c3e0
0, 12780, 65024, 0x848020a2
0, 19170, 65024, 0xbb64696f
0, 25560, 65024, 0x85886472
0, 31950, 65024, 0xc9c26668
0, 38340, 65024, 0xf24d1524
0, 44730, 65024, 0x64d98cd0
0, 51120, 65024, 0xa1323b5e
0, 57510, 65024, 0x9f48dcf9
0, 63900, 65024, 0x1a0591da
0, 70290, 65024, 0x8eabf12e
0, 0, 3648, 0xb6174031
0, 6390, 3648, 0x2e4649b0
0, 12780, 3648, 0xe05247cb
0, 19170, 3648, 0x003941f0
0, 25560, 3648, 0xa2563fed
0, 31950, 3648, 0x23d34cf1
0, 38340, 3648, 0x624f5173
0, 44730, 3648, 0xc07a491e
0, 51120, 3648, 0x74214090
0, 57510, 3648, 0xebfd469c
0, 63900, 3648, 0x60083f49
0, 70290, 3648, 0x6096486f
0, 0, 45932, 0xf9bc2e69
0, 6390, 45932, 0x5b8736ad
0, 12780, 45932, 0x4521ba17
0, 19170, 45932, 0xf3a374a9
0, 25560, 45932, 0x3fdfdc70
0, 31950, 45932, 0x4eb18dbb
0, 38340, 45932, 0x633c6377
0, 44730, 45932, 0x77dce8ba
0, 51120, 45932, 0x8246fecd
0, 57510, 45932, 0xe8864c0d
0, 63900, 45932, 0x995740d1
0, 70290, 45932, 0xc8a298ee
0, 76680, 45932, 0xa3535672
0, 83070, 45932, 0xb553f58b
0, 89460, 45932, 0x8a5b3b92
0, 95850, 45932, 0x1bcd50b0
0, 102240, 45932, 0xf22b0531
0, 108630, 45932, 0x5f62bc78
0, 115020, 45932, 0xc669075f
0, 121410, 45932, 0xae3b4e80
0, 127800, 45932, 0x3f52062f
0, 134190, 45932, 0xde97a978
0, 140580, 45932, 0x3ba7ca71
0, 146970, 45932, 0xe418aba1
0, 153360, 45932, 0xb8b3f24b
0, 159750, 45932, 0xd054791d
0, 166140, 45932, 0xddf121ce
0, 172530, 45932, 0xf0dcdd42
0, 178920, 45932, 0xd5aa9281
0, 185310, 45932, 0xffe8450b
0, 191700, 45932, 0x84f9424a
0, 198090, 45932, 0xe6c7592e
0, 204480, 45932, 0xc29c492d
0, 210870, 45932, 0x87186732
0, 217260, 45932, 0x02c73e12
0, 223650, 45932, 0x32eb90c8
0, 0, 77076, 0x33b3bf99
0, 6390, 77076, 0xde70a282
0, 12780, 77076, 0x8d4c10a4
0, 19170, 77076, 0xeb536bcc
0, 25560, 77076, 0x86cce3e8
0, 31950, 77076, 0x292df285
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment