|
|
|
@ -277,16 +277,30 @@ static int init_cook_mlt(COOKContext *q) { |
|
|
|
|
/**
|
|
|
|
|
* Cook indata decoding, every 32 bits are XORed with 0x37c511f2. |
|
|
|
|
* Why? No idea, some checksum/error detection method maybe. |
|
|
|
|
* |
|
|
|
|
* Out buffer size: extra bytes are needed to cope with |
|
|
|
|
* padding/missalignment. |
|
|
|
|
* Subpackets passed to the decoder can contain two, consecutive |
|
|
|
|
* half-subpackets, of identical but arbitrary size. |
|
|
|
|
* 1234 1234 1234 1234 extraA extraB |
|
|
|
|
* Case 1: AAAA BBBB 0 0 |
|
|
|
|
* Case 2: AAAA ABBB BB-- 3 3 |
|
|
|
|
* Case 3: AAAA AABB BBBB 2 2 |
|
|
|
|
* Case 4: AAAA AAAB BBBB BB-- 1 5 |
|
|
|
|
* |
|
|
|
|
* Nice way to waste CPU cycles. |
|
|
|
|
* |
|
|
|
|
* @param in pointer to 32bit array of indata |
|
|
|
|
* @param bits amount of bits |
|
|
|
|
* @param out pointer to 32bit array of outdata |
|
|
|
|
* @param inbuffer pointer to byte array of indata |
|
|
|
|
* @param out pointer to byte array of outdata |
|
|
|
|
* @param bytes number of bytes |
|
|
|
|
*/ |
|
|
|
|
#define DECODE_BYTES_PAD1(bytes) (3 - ((bytes)+3) % 4) |
|
|
|
|
#define DECODE_BYTES_PAD2(bytes) ((bytes) % 4 + DECODE_BYTES_PAD1(2 * (bytes))) |
|
|
|
|
|
|
|
|
|
static inline void decode_bytes(uint8_t* inbuffer, uint8_t* out, int bytes){ |
|
|
|
|
int i; |
|
|
|
|
uint32_t* buf = (uint32_t*) inbuffer; |
|
|
|
|
static inline int decode_bytes(uint8_t* inbuffer, uint8_t* out, int bytes){ |
|
|
|
|
int i, off; |
|
|
|
|
uint32_t c; |
|
|
|
|
uint32_t* buf; |
|
|
|
|
uint32_t* obuf = (uint32_t*) out; |
|
|
|
|
/* FIXME: 64 bit platforms would be able to do 64 bits at a time.
|
|
|
|
|
* I'm too lazy though, should be something like |
|
|
|
@ -294,14 +308,14 @@ static inline void decode_bytes(uint8_t* inbuffer, uint8_t* out, int bytes){ |
|
|
|
|
* (int64_t)out[i] = 0x37c511f237c511f2^be2me_64(int64_t)in[i]); |
|
|
|
|
* Buffer alignment needs to be checked. */ |
|
|
|
|
|
|
|
|
|
off = (uint32_t)inbuffer % 4; |
|
|
|
|
buf = (uint32_t*) (inbuffer - off); |
|
|
|
|
c = be2me_32((0x37c511f2 >> (off*8)) | (0x37c511f2 << (32-(off*8)))); |
|
|
|
|
bytes += 3 + off; |
|
|
|
|
for (i = 0; i < bytes/4; i++) |
|
|
|
|
obuf[i] = c ^ buf[i]; |
|
|
|
|
|
|
|
|
|
for(i=0 ; i<bytes/4 ; i++){ |
|
|
|
|
#ifdef WORDS_BIGENDIAN |
|
|
|
|
obuf[i] = 0x37c511f2^buf[i]; |
|
|
|
|
#else |
|
|
|
|
obuf[i] = 0xf211c537^buf[i]; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
return off; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -947,6 +961,28 @@ static void joint_decode(COOKContext *q, float* mlt_buffer1, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* First part of subpacket decoding: |
|
|
|
|
* decode raw stream bytes and read gain info. |
|
|
|
|
* |
|
|
|
|
* @param q pointer to the COOKContext |
|
|
|
|
* @param inbuffer pointer to raw stream data |
|
|
|
|
* @param gain_ptr array of current/prev gain pointers |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
static inline void |
|
|
|
|
decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, COOKgain *gain_ptr) |
|
|
|
|
{ |
|
|
|
|
int offset; |
|
|
|
|
|
|
|
|
|
offset = decode_bytes(inbuffer, q->decoded_bytes_buffer, |
|
|
|
|
q->bits_per_subpacket/8); |
|
|
|
|
init_get_bits(&q->gb, q->decoded_bytes_buffer + offset, |
|
|
|
|
q->bits_per_subpacket); |
|
|
|
|
decode_gain_info(&q->gb, gain_ptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Cook subpacket decoding. This function returns one decoded subpacket, |
|
|
|
|
* usually 1024 samples per channel. |
|
|
|
@ -970,11 +1006,9 @@ static int decode_subpacket(COOKContext *q, uint8_t *inbuffer, |
|
|
|
|
// }
|
|
|
|
|
// av_log(NULL, AV_LOG_ERROR, "\n");
|
|
|
|
|
|
|
|
|
|
decode_bytes(inbuffer, q->decoded_bytes_buffer, sub_packet_size); |
|
|
|
|
init_get_bits(&q->gb, q->decoded_bytes_buffer, sub_packet_size*8); |
|
|
|
|
decode_gain_info(&q->gb, &q->gain_current); |
|
|
|
|
|
|
|
|
|
if(q->nb_channels==2 && q->joint_stereo==1){ |
|
|
|
|
decode_bytes_and_gain(q, inbuffer, &q->gain_current); |
|
|
|
|
|
|
|
|
|
joint_decode(q, q->decode_buf_ptr[0], q->decode_buf_ptr[2]); |
|
|
|
|
|
|
|
|
|
/* Swap buffer pointers. */ |
|
|
|
@ -1014,6 +1048,8 @@ static int decode_subpacket(COOKContext *q, uint8_t *inbuffer, |
|
|
|
|
|
|
|
|
|
} else if (q->nb_channels==2 && q->joint_stereo==0) { |
|
|
|
|
/* channel 0 */ |
|
|
|
|
decode_bytes_and_gain(q, inbuffer, &q->gain_current); |
|
|
|
|
|
|
|
|
|
mono_decode(q, q->decode_buf_ptr2[0]); |
|
|
|
|
|
|
|
|
|
tmp_ptr = q->decode_buf_ptr2[0]; |
|
|
|
@ -1035,17 +1071,17 @@ static int decode_subpacket(COOKContext *q, uint8_t *inbuffer, |
|
|
|
|
value = lrintf(q->mono_mdct_output[j]); |
|
|
|
|
if(value < -32768) value = -32768; |
|
|
|
|
else if(value > 32767) value = 32767; |
|
|
|
|
outbuffer[2*j+1] = value; |
|
|
|
|
outbuffer[2*j] = value; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* channel 1 */ |
|
|
|
|
//av_log(NULL,AV_LOG_ERROR,"bits = %d\n",get_bits_count(&q->gb));
|
|
|
|
|
init_get_bits(&q->gb, q->decoded_bytes_buffer, sub_packet_size*8+q->bits_per_subpacket); |
|
|
|
|
decode_bytes_and_gain(q, inbuffer + sub_packet_size/2, |
|
|
|
|
&q->gain_channel2[0]); |
|
|
|
|
|
|
|
|
|
q->gain_now_ptr = &q->gain_channel2[0]; |
|
|
|
|
q->gain_previous_ptr = &q->gain_channel2[1]; |
|
|
|
|
|
|
|
|
|
decode_gain_info(&q->gb, &q->gain_channel2[0]); |
|
|
|
|
mono_decode(q, q->decode_buf_ptr[0]); |
|
|
|
|
|
|
|
|
|
tmp_ptr = q->decode_buf_ptr[0]; |
|
|
|
@ -1067,10 +1103,12 @@ static int decode_subpacket(COOKContext *q, uint8_t *inbuffer, |
|
|
|
|
value = lrintf(q->mono_mdct_output[j]); |
|
|
|
|
if(value < -32768) value = -32768; |
|
|
|
|
else if(value > 32767) value = 32767; |
|
|
|
|
outbuffer[2*j] = value; |
|
|
|
|
outbuffer[2*j+1] = value; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
decode_bytes_and_gain(q, inbuffer, &q->gain_current); |
|
|
|
|
|
|
|
|
|
mono_decode(q, q->decode_buf_ptr[0]); |
|
|
|
|
|
|
|
|
|
/* Swap buffer pointers. */ |
|
|
|
@ -1258,9 +1296,21 @@ static int cook_decode_init(AVCodecContext *avctx) |
|
|
|
|
if(avctx->block_align >= UINT_MAX/2) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
/* Pad the databuffer with FF_INPUT_BUFFER_PADDING_SIZE,
|
|
|
|
|
this is for the bitstreamreader. */ |
|
|
|
|
if ((q->decoded_bytes_buffer = av_mallocz((avctx->block_align+(4-avctx->block_align%4) + FF_INPUT_BUFFER_PADDING_SIZE)*sizeof(uint8_t))) == NULL) |
|
|
|
|
/* Pad the databuffer with:
|
|
|
|
|
DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(), |
|
|
|
|
FF_INPUT_BUFFER_PADDING_SIZE, for the bitstreamreader. */ |
|
|
|
|
if (q->nb_channels==2 && q->joint_stereo==0) { |
|
|
|
|
q->decoded_bytes_buffer = |
|
|
|
|
av_mallocz(avctx->block_align/2 |
|
|
|
|
+ DECODE_BYTES_PAD2(avctx->block_align/2) |
|
|
|
|
+ FF_INPUT_BUFFER_PADDING_SIZE); |
|
|
|
|
} else { |
|
|
|
|
q->decoded_bytes_buffer = |
|
|
|
|
av_mallocz(avctx->block_align |
|
|
|
|
+ DECODE_BYTES_PAD1(avctx->block_align) |
|
|
|
|
+ FF_INPUT_BUFFER_PADDING_SIZE); |
|
|
|
|
} |
|
|
|
|
if (q->decoded_bytes_buffer == NULL) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
q->decode_buf_ptr[0] = q->decode_buffer_1; |
|
|
|
|