imc: support mode 1
authorKostya Shishkov <kostya.shishkov@gmail.com>
Thu, 11 Jul 2013 05:04:42 +0000 (07:04 +0200)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Mon, 26 Aug 2013 07:23:45 +0000 (09:23 +0200)
libavcodec/imc.c

index e3f5e15..b803176 100644 (file)
@@ -100,6 +100,8 @@ typedef struct {
     DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2];
     float *out_samples;
 
+    int coef0_pos;
+
     int8_t cyclTab[32], cyclTab2[32];
     float  weights1[31], weights2[31];
 } IMCContext;
@@ -336,6 +338,17 @@ static void imc_read_level_coeffs(IMCContext *q, int stream_format_code,
     }
 }
 
+static void imc_read_level_coeffs_raw(IMCContext *q, int stream_format_code,
+                                      int *levlCoeffs)
+{
+    int i;
+
+    q->coef0_pos  = get_bits(&q->gb, 5);
+    levlCoeffs[0] = get_bits(&q->gb, 7);
+    for (i = 1; i < BANDS; i++)
+        levlCoeffs[i] = get_bits(&q->gb, 4);
+}
+
 static void imc_decode_level_coefficients(IMCContext *q, int *levlCoeffBuf,
                                           float *flcoeffs1, float *flcoeffs2)
 {
@@ -390,6 +403,28 @@ static void imc_decode_level_coefficients2(IMCContext *q, int *levlCoeffBuf,
     }
 }
 
+static void imc_decode_level_coefficients_raw(IMCContext *q, int *levlCoeffBuf,
+                                              float *flcoeffs1, float *flcoeffs2)
+{
+    int i, level, pos;
+    float tmp, tmp2;
+
+    pos = q->coef0_pos;
+    flcoeffs1[pos] = 20000.0 / pow (2, levlCoeffBuf[0] * 0.18945); // 0.18945 = log2(10) * 0.05703125
+    flcoeffs2[pos] = log2f(flcoeffs1[0]);
+    tmp  = flcoeffs1[pos];
+    tmp2 = flcoeffs2[pos];
+
+    levlCoeffBuf++;
+    for (i = 0; i < BANDS; i++) {
+        if (i == pos)
+            continue;
+        level = *levlCoeffBuf++;
+        flcoeffs1[i] = tmp  * powf(10.0, -level * 0.4375); //todo tab
+        flcoeffs2[i] = tmp2 - 1.4533435415 * level; // 1.4533435415 = log2(10) * 0.4375
+    }
+}
+
 /**
  * Perform bit allocation depending on bits available
  */
@@ -762,12 +797,56 @@ static int imc_get_coeffs(IMCContext *q, IMCChannel *chctx)
     return 0;
 }
 
+static void imc_refine_bit_allocation(IMCContext *q, IMCChannel *chctx)
+{
+    int i, j;
+    int bits, summer;
+
+    for (i = 0; i < BANDS; i++) {
+        chctx->sumLenArr[i]   = 0;
+        chctx->skipFlagRaw[i] = 0;
+        for (j = band_tab[i]; j < band_tab[i + 1]; j++)
+            chctx->sumLenArr[i] += chctx->CWlengthT[j];
+        if (chctx->bandFlagsBuf[i])
+            if ((((band_tab[i + 1] - band_tab[i]) * 1.5) > chctx->sumLenArr[i]) && (chctx->sumLenArr[i] > 0))
+                chctx->skipFlagRaw[i] = 1;
+    }
+
+    imc_get_skip_coeff(q, chctx);
+
+    for (i = 0; i < BANDS; i++) {
+        chctx->flcoeffs6[i] = chctx->flcoeffs1[i];
+        /* band has flag set and at least one coded coefficient */
+        if (chctx->bandFlagsBuf[i] && (band_tab[i + 1] - band_tab[i]) != chctx->skipFlagCount[i]) {
+            chctx->flcoeffs6[i] *= q->sqrt_tab[ band_tab[i + 1] - band_tab[i]] /
+                                   q->sqrt_tab[(band_tab[i + 1] - band_tab[i] - chctx->skipFlagCount[i])];
+        }
+    }
+
+    /* calculate bits left, bits needed and adjust bit allocation */
+    bits = summer = 0;
+
+    for (i = 0; i < BANDS; i++) {
+        if (chctx->bandFlagsBuf[i]) {
+            for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
+                if (chctx->skipFlags[j]) {
+                    summer += chctx->CWlengthT[j];
+                    chctx->CWlengthT[j] = 0;
+                }
+            }
+            bits   += chctx->skipFlagBits[i];
+            summer -= chctx->skipFlagBits[i];
+        }
+    }
+    imc_adjust_bit_allocation(q, chctx, summer);
+}
+
 static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
 {
     int stream_format_code;
     int imc_hdr, i, j, ret;
     int flag;
-    int bits, summer;
+    int bits;
     int counter, bitscount;
     IMCChannel *chctx = q->chctx + ch;
 
@@ -781,11 +860,6 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
     }
     stream_format_code = get_bits(&q->gb, 3);
 
-    if (stream_format_code & 1) {
-        avpriv_request_sample(avctx, "Stream format %X", stream_format_code);
-        return AVERROR_PATCHWELCOME;
-    }
-
     if (stream_format_code & 0x04)
         chctx->decoder_reset = 1;
 
@@ -798,7 +872,13 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
     }
 
     flag = get_bits1(&q->gb);
-    imc_read_level_coeffs(q, stream_format_code, chctx->levlCoeffBuf);
+    if (stream_format_code & 0x1)
+        imc_decode_level_coefficients_raw(q, chctx->levlCoeffBuf,
+                                          chctx->flcoeffs1, chctx->flcoeffs2);
+    else if (stream_format_code & 0x1)
+        imc_read_level_coeffs_raw(q, stream_format_code, chctx->levlCoeffBuf);
+    else
+        imc_read_level_coeffs(q, stream_format_code, chctx->levlCoeffBuf);
 
     if (stream_format_code & 0x4)
         imc_decode_level_coefficients(q, chctx->levlCoeffBuf,
@@ -810,20 +890,31 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
     memcpy(chctx->old_floor, chctx->flcoeffs1, 32 * sizeof(float));
 
     counter = 0;
-    for (i = 0; i < BANDS; i++) {
-        if (chctx->levlCoeffBuf[i] == 16) {
-            chctx->bandWidthT[i] = 0;
-            counter++;
-        } else
-            chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i];
-    }
-    memset(chctx->bandFlagsBuf, 0, BANDS * sizeof(int));
-    for (i = 0; i < BANDS - 1; i++) {
-        if (chctx->bandWidthT[i])
-            chctx->bandFlagsBuf[i] = get_bits1(&q->gb);
-    }
+    if (stream_format_code & 0x1) {
+        for (i = 0; i < BANDS; i++) {
+            chctx->bandWidthT[i]   = band_tab[i + 1] - band_tab[i];
+            chctx->bandFlagsBuf[i] = 0;
+            chctx->flcoeffs3[i]    = chctx->flcoeffs2[i] * 2;
+            chctx->flcoeffs5[i]    = 1.0;
+        }
+    } else {
+        for (i = 0; i < BANDS; i++) {
+            if (chctx->levlCoeffBuf[i] == 16) {
+                chctx->bandWidthT[i] = 0;
+                counter++;
+            } else
+                chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i];
+        }
+
+        memset(chctx->bandFlagsBuf, 0, BANDS * sizeof(int));
+        for (i = 0; i < BANDS - 1; i++)
+            if (chctx->bandWidthT[i])
+                chctx->bandFlagsBuf[i] = get_bits1(&q->gb);
 
-    imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2, chctx->bandWidthT, chctx->flcoeffs3, chctx->flcoeffs5);
+        imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2,
+                             chctx->bandWidthT, chctx->flcoeffs3,
+                             chctx->flcoeffs5);
+    }
 
     bitscount = 0;
     /* first 4 bands will be assigned 5 bits per coefficient */
@@ -835,7 +926,10 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
         chctx->CWlengthT[1] = 5;
         chctx->CWlengthT[2] = 5;
         for (i = 1; i < 4; i++) {
-            bits = (chctx->levlCoeffBuf[i] == 16) ? 0 : 5;
+            if (stream_format_code & 0x1)
+                bits = 5;
+            else
+                bits = (chctx->levlCoeffBuf[i] == 16) ? 0 : 5;
             chctx->bitsBandT[i] = bits;
             for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
                 chctx->CWlengthT[j] = bits;
@@ -857,43 +951,12 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
         return ret;
     }
 
-    for (i = 0; i < BANDS; i++) {
-        chctx->sumLenArr[i]   = 0;
-        chctx->skipFlagRaw[i] = 0;
-        for (j = band_tab[i]; j < band_tab[i + 1]; j++)
-            chctx->sumLenArr[i] += chctx->CWlengthT[j];
-        if (chctx->bandFlagsBuf[i])
-            if ((((band_tab[i + 1] - band_tab[i]) * 1.5) > chctx->sumLenArr[i]) && (chctx->sumLenArr[i] > 0))
-                chctx->skipFlagRaw[i] = 1;
-    }
-
-    imc_get_skip_coeff(q, chctx);
-
-    for (i = 0; i < BANDS; i++) {
-        chctx->flcoeffs6[i] = chctx->flcoeffs1[i];
-        /* band has flag set and at least one coded coefficient */
-        if (chctx->bandFlagsBuf[i] && (band_tab[i + 1] - band_tab[i]) != chctx->skipFlagCount[i]) {
-            chctx->flcoeffs6[i] *= q->sqrt_tab[ band_tab[i + 1] - band_tab[i]] /
-                                   q->sqrt_tab[(band_tab[i + 1] - band_tab[i] - chctx->skipFlagCount[i])];
-        }
-    }
-
-    /* calculate bits left, bits needed and adjust bit allocation */
-    bits = summer = 0;
-
-    for (i = 0; i < BANDS; i++) {
-        if (chctx->bandFlagsBuf[i]) {
-            for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
-                if (chctx->skipFlags[j]) {
-                    summer += chctx->CWlengthT[j];
-                    chctx->CWlengthT[j] = 0;
-                }
-            }
-            bits   += chctx->skipFlagBits[i];
-            summer -= chctx->skipFlagBits[i];
-        }
+    if (stream_format_code & 0x1) {
+        for (i = 0; i < BANDS; i++)
+            chctx->skipFlags[i] = 0;
+    } else {
+        imc_refine_bit_allocation(q, chctx);
     }
-    imc_adjust_bit_allocation(q, chctx, summer);
 
     for (i = 0; i < BANDS; i++) {
         chctx->sumLenArr[i] = 0;