📄 cook_fix_all.c
字号:
- idx -=decouple_tab[cpl_tmp];
- cplscale = (float*)cplscales[q->js_vlc_bits-2]; //choose decoupler table
- f1 = cplscale[decouple_tab[cpl_tmp]];
- f2 = cplscale[idx-1];
- for (j=0 ; j<SUBBAND_SIZE ; j++) {
- tmp_idx = ((q->js_subband_start + i)*20)+j;
- mlt_buffer1[20*i + j] = f1 * decode_buffer[tmp_idx];
- mlt_buffer2[20*i + j] = f2 * decode_buffer[tmp_idx];
- }
- idx = (1 << q->js_vlc_bits) - 1;
- }
-}
-
-/**
- * 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,
- cook_gains *gains_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, gains_ptr->now);
-
- /* Swap current and previous gains */
- FFSWAP(int *, gains_ptr->now, gains_ptr->previous);
-}
-
-/**
- * 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,
- cook_gains *gains, float *previous_buffer,
- int16_t *out, int chan)
-{
- float *output = q->mono_mdct_output + q->samples_per_channel;
- int j;
-
- imlt_gain(q, decode_buffer, gains, previous_buffer);
-
- /* Clip and convert floats to 16 bits.
- */
- for (j = 0; j < q->samples_per_channel; j++) {
- out[chan + q->nb_channels * j] =
- av_clip(lrintf(output[j]), -32768, 32767);
- }
-}
-
-
-/**
- * Cook subpacket decoding. This function returns one decoded subpacket,
- * usually 1024 samples per channel.
- *
- * @param q pointer to the COOKContext
- * @param inbuffer pointer to the inbuffer
- * @param sub_packet_size subpacket size
- * @param outbuffer pointer to the outbuffer
- */
-
-
-static int decode_subpacket(COOKContext *q, uint8_t *inbuffer,
- int sub_packet_size, int16_t *outbuffer) {
- /* packet dump */
-// for (i=0 ; i<sub_packet_size ; i++) {
-// av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]);
-// }
-// av_log(NULL, AV_LOG_ERROR, "\n");
-
- decode_bytes_and_gain(q, inbuffer, &q->gains1);
-
- if (q->joint_stereo) {
- joint_decode(q, q->decode_buffer_1, q->decode_buffer_2);
- } else {
- mono_decode(q, q->decode_buffer_1);
-
- if (q->nb_channels == 2) {
- decode_bytes_and_gain(q, inbuffer + sub_packet_size/2, &q->gains2);
- mono_decode(q, q->decode_buffer_2);
- }
- }
-
- mlt_compensate_output(q, q->decode_buffer_1, &q->gains1,
- q->mono_previous_buffer1, outbuffer, 0);
-
- if (q->nb_channels == 2) {
- if (q->joint_stereo) {
- mlt_compensate_output(q, q->decode_buffer_2, &q->gains1,
- q->mono_previous_buffer2, outbuffer, 1);
- } else {
- mlt_compensate_output(q, q->decode_buffer_2, &q->gains2,
- q->mono_previous_buffer2, outbuffer, 1);
- }
- }
- return q->samples_per_frame * sizeof(int16_t);
-}
-
-
-/**
- * Cook frame decoding
- *
- * @param avctx pointer to the AVCodecContext
- */
-
-static int cook_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- uint8_t *buf, int buf_size) {
- COOKContext *q = avctx->priv_data;
-
- if (buf_size < avctx->block_align)
- return buf_size;
-
- *data_size = decode_subpacket(q, buf, avctx->block_align, data);
-
- /* Discard the first two frames: no valid audio. */
- if (avctx->frame_number < 2) *data_size = 0;
-
- return avctx->block_align;
-}
-
-#ifdef COOKDEBUG
-static void dump_cook_context(COOKContext *q)
-{
- //int i=0;
-#define PRINT(a,b) av_log(NULL,AV_LOG_ERROR," %s = %d\n", a, b);
- av_log(NULL,AV_LOG_ERROR,"COOKextradata\n");
- av_log(NULL,AV_LOG_ERROR,"cookversion=%x\n",q->cookversion);
- if (q->cookversion > STEREO) {
- PRINT("js_subband_start",q->js_subband_start);
- PRINT("js_vlc_bits",q->js_vlc_bits);
- }
- av_log(NULL,AV_LOG_ERROR,"COOKContext\n");
- PRINT("nb_channels",q->nb_channels);
- PRINT("bit_rate",q->bit_rate);
- PRINT("sample_rate",q->sample_rate);
- PRINT("samples_per_channel",q->samples_per_channel);
- PRINT("samples_per_frame",q->samples_per_frame);
- PRINT("subbands",q->subbands);
- PRINT("random_state",q->random_state);
- PRINT("js_subband_start",q->js_subband_start);
- PRINT("log2_numvector_size",q->log2_numvector_size);
- PRINT("numvector_size",q->numvector_size);
- PRINT("total_subbands",q->total_subbands);
-}
-#endif
-
-/**
- * Cook initialization
- *
- * @param avctx pointer to the AVCodecContext
- */
-
-static int cook_decode_init(AVCodecContext *avctx)
-{
- COOKContext *q = avctx->priv_data;
- uint8_t *edata_ptr = avctx->extradata;
-
- /* Take care of the codec specific extradata. */
- if (avctx->extradata_size <= 0) {
- av_log(avctx,AV_LOG_ERROR,"Necessary extradata missing!\n");
- return -1;
- } else {
- /* 8 for mono, 16 for stereo, ? for multichannel
- Swap to right endianness so we don't need to care later on. */
- av_log(avctx,AV_LOG_DEBUG,"codecdata_length=%d\n",avctx->extradata_size);
- if (avctx->extradata_size >= 8){
- q->cookversion = bytestream_get_be32(&edata_ptr);
- q->samples_per_frame = bytestream_get_be16(&edata_ptr);
- q->subbands = bytestream_get_be16(&edata_ptr);
- }
- if (avctx->extradata_size >= 16){
- bytestream_get_be32(&edata_ptr); //Unknown unused
- q->js_subband_start = bytestream_get_be16(&edata_ptr);
- q->js_vlc_bits = bytestream_get_be16(&edata_ptr);
- }
- }
-
- /* Take data from the AVCodecContext (RM container). */
- q->sample_rate = avctx->sample_rate;
- q->nb_channels = avctx->channels;
- q->bit_rate = avctx->bit_rate;
-
- /* Initialize RNG. */
- av_init_random(1, &q->random_state);
-
- /* Initialize extradata related variables. */
- q->samples_per_channel = q->samples_per_frame / q->nb_channels;
- q->bits_per_subpacket = avctx->block_align * 8;
-
- /* Initialize default data states. */
- q->log2_numvector_size = 5;
- q->total_subbands = q->subbands;
-
- /* Initialize version-dependent variables */
- av_log(NULL,AV_LOG_DEBUG,"q->cookversion=%x\n",q->cookversion);
- q->joint_stereo = 0;
- switch (q->cookversion) {
- case MONO:
- if (q->nb_channels != 1) {
- av_log(avctx,AV_LOG_ERROR,"Container channels != 1, report sample!\n");
- return -1;
- }
- av_log(avctx,AV_LOG_DEBUG,"MONO\n");
- break;
- case STEREO:
- if (q->nb_channels != 1) {
- q->bits_per_subpacket = q->bits_per_subpacket/2;
- }
- av_log(avctx,AV_LOG_DEBUG,"STEREO\n");
- break;
- case JOINT_STEREO:
- if (q->nb_channels != 2) {
- av_log(avctx,AV_LOG_ERROR,"Container channels != 2, report sample!\n");
- return -1;
- }
- av_log(avctx,AV_LOG_DEBUG,"JOINT_STEREO\n");
- if (avctx->extradata_size >= 16){
- q->total_subbands = q->subbands + q->js_subband_start;
- q->joint_stereo = 1;
- }
- if (q->samples_per_channel > 256) {
- q->log2_numvector_size = 6;
- }
- if (q->samples_per_channel > 512) {
- q->log2_numvector_size = 7;
- }
- break;
- case MC_COOK:
- av_log(avctx,AV_LOG_ERROR,"MC_COOK not supported!\n");
- return -1;
- break;
- default:
- av_log(avctx,AV_LOG_ERROR,"Unknown Cook version, report sample!\n");
- return -1;
- break;
- }
-
- /* Initialize variable relations */
- q->numvector_size = (1 << q->log2_numvector_size);
-
- /* Generate tables */
- init_rootpow2table(q);
- init_pow2table(q);
- init_gain_table(q);
-
- if (init_cook_vlc_tables(q) != 0)
- return -1;
-
-
- if(avctx->block_align >= UINT_MAX/2)
- return -1;
-
- /* 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->gains1.now = q->gain_1;
- q->gains1.previous = q->gain_2;
- q->gains2.now = q->gain_3;
- q->gains2.previous = q->gain_4;
-
- /* Initialize transform. */
- if ( init_cook_mlt(q) != 0 )
- return -1;
-
- /* Try to catch some obviously faulty streams, othervise it might be exploitable */
- if (q->total_subbands > 53) {
- av_log(avctx,AV_LOG_ERROR,"total_subbands > 53, report sample!\n");
- return -1;
- }
- if (q->subbands > 50) {
- av_log(avctx,AV_LOG_ERROR,"subbands > 50, report sample!\n");
- return -1;
- }
- if ((q->samples_per_channel == 256) || (q->samples_per_channel == 512) || (q->samples_per_channel == 1024)) {
- } else {
- av_log(avctx,AV_LOG_ERROR,"unknown amount of samples_per_channel = %d, report sample!\n",q->samples_per_channel);
- return -1;
- }
- if ((q->js_vlc_bits > 6) || (q->js_vlc_bits < 0)) {
- av_log(avctx,AV_LOG_ERROR,"q->js_vlc_bits = %d, only >= 0 and <= 6 allowed!\n",q->js_vlc_bits);
- return -1;
- }
-
-#ifdef COOKDEBUG
- dump_cook_context(q);
-#endif
- return 0;
-}
-
-
-AVCodec cook_decoder =
-{
- .name = "cook",
- .type = CODEC_TYPE_AUDIO,
- .id = CODEC_ID_COOK,
- .priv_data_size = sizeof(COOKContext),
- .init = cook_decode_init,
- .close = cook_decode_close,
- .decode = cook_decode_frame,
-};
+/* Set up types and include cook data.
+ */
+typedef float Q_t;
+#define Q(x) (x)
+typedef float C_t;
+#define C(x) (x)
+#include "cookdata.h"
diff -urN svn/libavcodec/cookdata.h fixpoint/libavcodec/cookdata.h
--- svn/libavcodec/cookdata.h 2007-03-12 15:21:31.000000000 +0100
+++ fixpoint/libavcodec/cookdata.h 2007-03-18 22:31:46.000000000 +0100
@@ -32,20 +32,25 @@
52,47,43,37,29,22,16,0,
};
static const Q_t dither_tab[8] = {
Q(0.0), Q(0.0), Q(0.0), Q(0.0), Q(0.0), Q(0.176777), Q(0.25), Q(0.707107)
};
static const Q_t quant_centroid_tab[7][14] = {
{ Q(0.000), Q(0.392), Q(0.761), Q(1.120), Q(1.477), Q(1.832), Q(2.183),
Q(2.541), Q(2.893), Q(3.245), Q(3.598), Q(3.942), Q(4.288), Q(4.724) },
{ Q(0.000), Q(0.544), Q(1.060), Q(1.563), Q(2.068), Q(2.571), Q(3.072),
Q(3.562), Q(4.070), Q(4.620), Q(0.000), Q(0.000), Q(0.000), Q(0.000) },
{ Q(0.000), Q(0.746), Q(1.464), Q(2.180), Q(2.882), Q(3.584), Q(4.316),
Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000) },
{ Q(0.000), Q(1.006), Q(2.000), Q(2.993), Q(3.985), Q(0.000), Q(0.000),
Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000) },
{ Q(0.000), Q(1.321), Q(2.703), Q(3.983), Q(0.000), Q(0.000), Q(0.000),
Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000) },
{ Q(0.000), Q(1.657), Q(3.491), Q(0.000), Q(0.000), Q(0.000), Q(0.000),
Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000) },
{ Q(0.000), Q(1.964), Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000),
Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000), Q(0.000) }
};
static const int invradix_tab[7] = {
@@ -508,52 +513,62 @@
19,
};
static const C_t cplscale2[3] = {
C(0.953020632266998), C(0.707106769084930), C(0.302905440330505)
};
static const C_t cplscale3[7] = {
C(0.981279790401459), C(0.936997592449188), C(0.875934481620789),
C(0.707106769084930), C(0.482430040836334), C(0.349335819482803),
C(0.192587479948997)
};
static const C_t cplscale4[15] = {
C(0.991486728191376), C(0.973249018192291), C(0.953020632266998),
C(0.930133521556854), C(0.903453230857849), C(0.870746195316315),
C(0.826180458068848), C(0.707106769084930), C(0.563405573368073),
C(0.491732746362686), C(0.428686618804932), C(0.367221474647522),
C(0.302905440330505), C(0.229752898216248), C(0.130207896232605)
};
static const C_t cplscale5[31] = {
C(0.995926380157471), C(0.987517595291138), C(0.978726446628571),
C(0.969505727291107), C(0.959797799587250), C(0.949531257152557),
C(0.938616216182709), C(0.926936149597168), C(0.914336204528809),
C(0.900602877140045), C(0.885426938533783), C(0.868331849575043),
C(0.848510861396790), C(0.824381768703461), C(0.791833400726318),
C(0.707106769084930), C(0.610737144947052), C(0.566034197807312),
C(0.529177963733673), C(0.495983630418777), C(0.464778542518616),
C(0.434642940759659), C(0.404955863952637), C(0.375219136476517),
C(0.344963222742081), C(0.313672333955765), C(0.280692428350449),
C(0.245068684220314), C(0.205169528722763), C(0.157508864998817),
C(0.0901700109243393)
};
static const C_t cplscale6[63] = {
C(0.998005926609039), C(0.993956744670868), C(0.989822506904602),
C(0.985598564147949), C(0.981279790401459), C(0.976860702037811),
C(0.972335040569305), C(0.967696130275726), C(0.962936460971832),
C(0.958047747612000), C(0.953020632266998), C(0.947844684123993),
C(0.942508161067963), C(0.936997592449188), C(0.931297719478607),
C(0.925390899181366), C(0.919256627559662), C(0.912870943546295),
C(0.906205296516418), C(0.899225592613220), C(0.891890347003937),
C(0.884148240089417), C(0.875934481620789), C(0.867165684700012),
C(0.857730865478516), C(0.847477376461029), C(0.836184680461884),
C(0.823513329029083), C(0.808890223503113), C(0.791194140911102),
C(0.767520070075989), C(0.707106769084930), C(0.641024887561798),
C(0.611565053462982), C(0.587959706783295), C(0.567296981811523),
C(0.548448026180267), C(0.530831515789032), C(0.514098942279816),
C(0.498019754886627), C(0.482430040836334), C(0.467206478118896),
C(0.452251672744751), C(0.437485188245773), C(0.422837972640991),
C(0.408248275518417), C(0.393658757209778), C(0.379014074802399),
C(0.364258885383606), C(0.349335819482803), C(0.334183186292648),
C(0.318732559680939), C(0.302905440330505), C(0.286608695983887),
C(0.269728302955627), C(0.252119421958923), C(0.233590632677078),
C(0.213876649737358), C(0.192587479948997), C(0.169101938605309),
C(0.142307326197624), C(0.109772264957428), C(0.0631198287010193)
};
static const C_t* cplscales[5] = {
cplscale2, cplscale3, cplscale4, cplscale5, cplscale6,
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -