---
I don't have samples for it so it's rather theoretical.
---
 libavcodec/imc.c |  151 ++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 102 insertions(+), 49 deletions(-)

diff --git a/libavcodec/imc.c b/libavcodec/imc.c
index e3f5e15..a451bc8 100644
--- a/libavcodec/imc.c
+++ b/libavcodec/imc.c
@@ -65,7 +65,7 @@ typedef struct IMCChannel {
     int bandWidthT[BANDS];     ///< codewords per band
     int bitsBandT[BANDS];      ///< how many bits per codeword in band
     int CWlengthT[COEFFS];     ///< how many bits in each codeword
-    int levlCoeffBuf[BANDS];
+    int levlCoeffBuf[BANDS + 1];
     int bandFlagsBuf[BANDS];   ///< flags for each band
     int sumLenArr[BANDS];      ///< bits for all coeffs in band
     int skipFlagRaw[BANDS];    ///< skip flags are stored in raw form or not
@@ -336,6 +336,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;
+
+    levlCoeffs[0] = get_bits(&q->gb, 5);
+    levlCoeffs[1] = get_bits(&q->gb, 7);
+    for (i = 1; i < BANDS; i++)
+        levlCoeffs[i + 1] = get_bits(&q->gb, 4);
+}
+
 static void imc_decode_level_coefficients(IMCContext *q, int *levlCoeffBuf,
                                           float *flcoeffs1, float *flcoeffs2)
 {
@@ -390,6 +401,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 = levlCoeffBuf[0];
+    flcoeffs1[pos] = 20000.0 / pow (2, levlCoeffBuf[1] * 0.18945); // 0.18945 
= log2(10) * 0.05703125
+    flcoeffs2[pos] = log2f(flcoeffs1[0]);
+    tmp  = flcoeffs1[pos];
+    tmp2 = flcoeffs2[pos];
+
+    levlCoeffBuf += 2;
+    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
  */
@@ -781,11 +814,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,9 +826,15 @@ 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_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)
+    if (stream_format_code & 0x1)
+        imc_decode_level_coefficients_raw(q, chctx->levlCoeffBuf,
+                                          chctx->flcoeffs1, chctx->flcoeffs2);
+    else if (stream_format_code & 0x4)
         imc_decode_level_coefficients(q, chctx->levlCoeffBuf,
                                       chctx->flcoeffs1, chctx->flcoeffs2);
     else
@@ -810,20 +844,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
+    if (stream_format_code & 0x1) {
+        for (i = 0; i < BANDS; i++) {
             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);
-    }
+            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];
+        }
 
-    imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2, 
chctx->bandWidthT, chctx->flcoeffs3, chctx->flcoeffs5);
+        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);
+    }
 
     bitscount = 0;
     /* first 4 bands will be assigned 5 bits per coefficient */
@@ -835,7 +880,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 +905,48 @@ 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;
-    }
+    if (stream_format_code & 1) {
+        for (i = 0; i < BANDS; i++)
+            chctx->skipFlags[i] = 0;
+    } else {
+        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);
+        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])];
+        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;
+        /* 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;
+        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];
             }
-            bits   += chctx->skipFlagBits[i];
-            summer -= chctx->skipFlagBits[i];
         }
+        imc_adjust_bit_allocation(q, chctx, summer);
     }
-    imc_adjust_bit_allocation(q, chctx, summer);
 
     for (i = 0; i < BANDS; i++) {
         chctx->sumLenArr[i] = 0;
-- 
1.7.9.5

_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to