Commit 48752ab1 authored by banan's avatar banan

decode_subpacket cleanup by Ian Braithwaite ian braithwaite dot dk.


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@7753 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent e1628aeb
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "avcodec.h" #include "avcodec.h"
#include "bitstream.h" #include "bitstream.h"
#include "dsputil.h" #include "dsputil.h"
#include "common.h"
#include "cookdata.h" #include "cookdata.h"
...@@ -112,13 +113,12 @@ typedef struct { ...@@ -112,13 +113,12 @@ typedef struct {
int mlt_size; //modulated lapped transform size int mlt_size; //modulated lapped transform size
/* gain buffers */ /* gain buffers */
COOKgain* gain_now_ptr; COOKgain *gain_ptr1[2];
COOKgain* gain_previous_ptr; COOKgain *gain_ptr2[2];
COOKgain gain_current; COOKgain gain_1;
COOKgain gain_now; COOKgain gain_2;
COOKgain gain_previous; COOKgain gain_3;
COOKgain gain_channel1[2]; COOKgain gain_4;
COOKgain gain_channel2[2];
/* VLC data */ /* VLC data */
int js_vlc_bits; int js_vlc_bits;
...@@ -136,15 +136,10 @@ typedef struct { ...@@ -136,15 +136,10 @@ typedef struct {
uint8_t* decoded_bytes_buffer; uint8_t* decoded_bytes_buffer;
float mono_mdct_output[2048] __attribute__((aligned(16))); float mono_mdct_output[2048] __attribute__((aligned(16)));
float* previous_buffer_ptr[2];
float mono_previous_buffer1[1024]; float mono_previous_buffer1[1024];
float mono_previous_buffer2[1024]; float mono_previous_buffer2[1024];
float* decode_buf_ptr[4];
float* decode_buf_ptr2[2];
float decode_buffer_1[1024]; float decode_buffer_1[1024];
float decode_buffer_2[1024]; float decode_buffer_2[1024];
float decode_buffer_3[1024];
float decode_buffer_4[1024];
} COOKContext; } COOKContext;
/* debug functions */ /* debug functions */
...@@ -971,7 +966,8 @@ static void joint_decode(COOKContext *q, float* mlt_buffer1, ...@@ -971,7 +966,8 @@ static void joint_decode(COOKContext *q, float* mlt_buffer1,
*/ */
static inline void static inline void
decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, COOKgain *gain_ptr) decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer,
COOKgain *gain_ptr[])
{ {
int offset; int offset;
...@@ -979,7 +975,42 @@ decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, COOKgain *gain_ptr) ...@@ -979,7 +975,42 @@ decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, COOKgain *gain_ptr)
q->bits_per_subpacket/8); q->bits_per_subpacket/8);
init_get_bits(&q->gb, q->decoded_bytes_buffer + offset, init_get_bits(&q->gb, q->decoded_bytes_buffer + offset,
q->bits_per_subpacket); q->bits_per_subpacket);
decode_gain_info(&q->gb, gain_ptr); decode_gain_info(&q->gb, gain_ptr[0]);
/* Swap current and previous gains */
FFSWAP(COOKgain *, gain_ptr[0], gain_ptr[1]);
}
/**
* Final part of subpacket decoding:
* Apply modulated lapped transform, gain compensation,
* clip and convert to integer.
*
* @param q pointer to the COOKContext
* @param decode_buffer pointer to the mlt coefficients
* @param gain_ptr array of current/prev gain pointers
* @param previous_buffer pointer to the previous buffer to be used for overlapping
* @param out pointer to the output buffer
* @param chan 0: left or single channel, 1: right channel
*/
static inline void
mlt_compensate_output(COOKContext *q, float *decode_buffer,
COOKgain *gain_ptr[], float *previous_buffer,
int16_t *out, int chan)
{
int j;
cook_imlt(q, decode_buffer, q->mono_mdct_output, q->mlt_tmp);
gain_compensate(q, q->mono_mdct_output, gain_ptr[0],
gain_ptr[1], previous_buffer);
/* Clip and convert floats to 16 bits.
*/
for (j = 0; j < q->samples_per_channel; j++) {
out[chan + q->nb_channels * j] =
clip(lrintf(q->mono_mdct_output[j]), -32768, 32767);
}
} }
...@@ -996,144 +1027,37 @@ decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, COOKgain *gain_ptr) ...@@ -996,144 +1027,37 @@ decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, COOKgain *gain_ptr)
static int decode_subpacket(COOKContext *q, uint8_t *inbuffer, static int decode_subpacket(COOKContext *q, uint8_t *inbuffer,
int sub_packet_size, int16_t *outbuffer) { int sub_packet_size, int16_t *outbuffer) {
int i,j;
int value;
float* tmp_ptr;
/* packet dump */ /* packet dump */
// for (i=0 ; i<sub_packet_size ; i++) { // for (i=0 ; i<sub_packet_size ; i++) {
// av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]); // av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]);
// } // }
// av_log(NULL, AV_LOG_ERROR, "\n"); // av_log(NULL, AV_LOG_ERROR, "\n");
if(q->nb_channels==2 && q->joint_stereo==1){ decode_bytes_and_gain(q, inbuffer, q->gain_ptr1);
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. */
tmp_ptr = q->decode_buf_ptr[1];
q->decode_buf_ptr[1] = q->decode_buf_ptr[0];
q->decode_buf_ptr[0] = tmp_ptr;
tmp_ptr = q->decode_buf_ptr[3];
q->decode_buf_ptr[3] = q->decode_buf_ptr[2];
q->decode_buf_ptr[2] = tmp_ptr;
/* FIXME: Rethink the gainbuffer handling, maybe a rename?
now/previous swap */
q->gain_now_ptr = &q->gain_now;
q->gain_previous_ptr = &q->gain_previous;
for (i=0 ; i<q->nb_channels ; i++){
cook_imlt(q, q->decode_buf_ptr[i*2], q->mono_mdct_output, q->mlt_tmp);
gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr,
q->gain_previous_ptr, q->previous_buffer_ptr[0]);
/* Swap out the previous buffer. */
tmp_ptr = q->previous_buffer_ptr[0];
q->previous_buffer_ptr[0] = q->previous_buffer_ptr[1];
q->previous_buffer_ptr[1] = tmp_ptr;
/* Clip and convert the floats to 16 bits. */
for (j=0 ; j<q->samples_per_frame ; j++){
value = lrintf(q->mono_mdct_output[j]);
if(value < -32768) value = -32768;
else if(value > 32767) value = 32767;
outbuffer[2*j+i] = value;
}
}
memcpy(&q->gain_now, &q->gain_previous, sizeof(COOKgain));
memcpy(&q->gain_previous, &q->gain_current, sizeof(COOKgain));
} 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]); if (q->joint_stereo) {
joint_decode(q, q->decode_buffer_1, q->decode_buffer_2);
tmp_ptr = q->decode_buf_ptr2[0]; } else {
q->decode_buf_ptr2[0] = q->decode_buf_ptr2[1]; mono_decode(q, q->decode_buffer_1);
q->decode_buf_ptr2[1] = tmp_ptr;
memcpy(&q->gain_channel1[0], &q->gain_current ,sizeof(COOKgain));
q->gain_now_ptr = &q->gain_channel1[0];
q->gain_previous_ptr = &q->gain_channel1[1];
cook_imlt(q, q->decode_buf_ptr2[0], q->mono_mdct_output,q->mlt_tmp);
gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr,
q->gain_previous_ptr, q->mono_previous_buffer1);
memcpy(&q->gain_channel1[1], &q->gain_channel1[0],sizeof(COOKgain));
for (j=0 ; j<q->samples_per_frame ; j++){
value = lrintf(q->mono_mdct_output[j]);
if(value < -32768) value = -32768;
else if(value > 32767) value = 32767;
outbuffer[2*j] = value;
}
/* channel 1 */ if (q->nb_channels == 2) {
//av_log(NULL,AV_LOG_ERROR,"bits = %d\n",get_bits_count(&q->gb));
decode_bytes_and_gain(q, inbuffer + sub_packet_size/2, decode_bytes_and_gain(q, inbuffer + sub_packet_size/2,
&q->gain_channel2[0]); q->gain_ptr2);
mono_decode(q, q->decode_buffer_2);
q->gain_now_ptr = &q->gain_channel2[0]; }
q->gain_previous_ptr = &q->gain_channel2[1]; }
mono_decode(q, q->decode_buf_ptr[0]);
tmp_ptr = q->decode_buf_ptr[0];
q->decode_buf_ptr[0] = q->decode_buf_ptr[1];
q->decode_buf_ptr[1] = tmp_ptr;
cook_imlt(q, q->decode_buf_ptr[0], q->mono_mdct_output,q->mlt_tmp);
gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr,
q->gain_previous_ptr, q->mono_previous_buffer2);
/* Swap out the previous buffer. */
tmp_ptr = q->previous_buffer_ptr[0];
q->previous_buffer_ptr[0] = q->previous_buffer_ptr[1];
q->previous_buffer_ptr[1] = tmp_ptr;
memcpy(&q->gain_channel2[1], &q->gain_channel2[0] ,sizeof(COOKgain));
for (j=0 ; j<q->samples_per_frame ; j++){ mlt_compensate_output(q, q->decode_buffer_1, q->gain_ptr1,
value = lrintf(q->mono_mdct_output[j]); q->mono_previous_buffer1, outbuffer, 0);
if(value < -32768) value = -32768;
else if(value > 32767) value = 32767;
outbuffer[2*j+1] = value;
}
} else { if (q->nb_channels == 2) {
decode_bytes_and_gain(q, inbuffer, &q->gain_current); if (q->joint_stereo) {
mlt_compensate_output(q, q->decode_buffer_2, q->gain_ptr1,
mono_decode(q, q->decode_buf_ptr[0]); q->mono_previous_buffer2, outbuffer, 1);
} else {
/* Swap buffer pointers. */ mlt_compensate_output(q, q->decode_buffer_2, q->gain_ptr2,
tmp_ptr = q->decode_buf_ptr[1]; q->mono_previous_buffer2, outbuffer, 1);
q->decode_buf_ptr[1] = q->decode_buf_ptr[0];
q->decode_buf_ptr[0] = tmp_ptr;
/* FIXME: Rethink the gainbuffer handling, maybe a rename?
now/previous swap */
q->gain_now_ptr = &q->gain_now;
q->gain_previous_ptr = &q->gain_previous;
cook_imlt(q, q->decode_buf_ptr[0], q->mono_mdct_output,q->mlt_tmp);
gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr,
q->gain_previous_ptr, q->mono_previous_buffer1);
/* Clip and convert the floats to 16 bits */
for (j=0 ; j<q->samples_per_frame ; j++){
value = lrintf(q->mono_mdct_output[j]);
if(value < -32768) value = -32768;
else if(value > 32767) value = 32767;
outbuffer[j] = value;
} }
memcpy(&q->gain_now, &q->gain_previous, sizeof(COOKgain));
memcpy(&q->gain_previous, &q->gain_current, sizeof(COOKgain));
} }
return q->samples_per_frame * sizeof(int16_t); return q->samples_per_frame * sizeof(int16_t);
} }
...@@ -1236,6 +1160,7 @@ static int cook_decode_init(AVCodecContext *avctx) ...@@ -1236,6 +1160,7 @@ static int cook_decode_init(AVCodecContext *avctx)
/* Initialize version-dependent variables */ /* Initialize version-dependent variables */
av_log(NULL,AV_LOG_DEBUG,"e->cookversion=%x\n",e->cookversion); av_log(NULL,AV_LOG_DEBUG,"e->cookversion=%x\n",e->cookversion);
q->joint_stereo = 0;
switch (e->cookversion) { switch (e->cookversion) {
case MONO: case MONO:
if (q->nb_channels != 1) { if (q->nb_channels != 1) {
...@@ -1246,7 +1171,6 @@ static int cook_decode_init(AVCodecContext *avctx) ...@@ -1246,7 +1171,6 @@ static int cook_decode_init(AVCodecContext *avctx)
break; break;
case STEREO: case STEREO:
if (q->nb_channels != 1) { if (q->nb_channels != 1) {
q->joint_stereo = 0;
q->bits_per_subpacket = q->bits_per_subpacket/2; q->bits_per_subpacket = q->bits_per_subpacket/2;
} }
av_log(avctx,AV_LOG_DEBUG,"STEREO\n"); av_log(avctx,AV_LOG_DEBUG,"STEREO\n");
...@@ -1313,16 +1237,10 @@ static int cook_decode_init(AVCodecContext *avctx) ...@@ -1313,16 +1237,10 @@ static int cook_decode_init(AVCodecContext *avctx)
if (q->decoded_bytes_buffer == NULL) if (q->decoded_bytes_buffer == NULL)
return -1; return -1;
q->decode_buf_ptr[0] = q->decode_buffer_1; q->gain_ptr1[0] = &q->gain_1;
q->decode_buf_ptr[1] = q->decode_buffer_2; q->gain_ptr1[1] = &q->gain_2;
q->decode_buf_ptr[2] = q->decode_buffer_3; q->gain_ptr2[0] = &q->gain_3;
q->decode_buf_ptr[3] = q->decode_buffer_4; q->gain_ptr2[1] = &q->gain_4;
q->decode_buf_ptr2[0] = q->decode_buffer_3;
q->decode_buf_ptr2[1] = q->decode_buffer_4;
q->previous_buffer_ptr[0] = q->mono_previous_buffer1;
q->previous_buffer_ptr[1] = q->mono_previous_buffer2;
/* Initialize transform. */ /* Initialize transform. */
if ( init_cook_mlt(q) == 0 ) if ( init_cook_mlt(q) == 0 )
......
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