[FFmpeg-soc] [soc]: r4182 - dcaenc/dcaenc.c

bwolowiec subversion at mplayerhq.hu
Sun Mar 22 18:13:07 CET 2009


Author: bwolowiec
Date: Sun Mar 22 18:13:06 2009
New Revision: 4182

Log:
Improve DCA encoder.

Modified:
   dcaenc/dcaenc.c

Modified: dcaenc/dcaenc.c
==============================================================================
--- dcaenc/dcaenc.c	Sun Mar 22 17:24:02 2009	(r4181)
+++ dcaenc/dcaenc.c	Sun Mar 22 18:13:06 2009	(r4182)
@@ -23,19 +23,27 @@
 #include "avcodec.h"
 #include "bitstream.h"
 #include "dcaenc.h"
+#include "dcadata.h"
 
-#define MAX_CHANNELS (2)
+#define MAX_CHANNELS (6)
 #define DCA_SUBBANDS_32 (32)
 #define DCA_MAX_FRAME_SIZE (16383)
-#define FIXED_FRAME_SIZE (7167)
+#define DCA_HEADER_SIZE 13
+
+#define SUBFRAMES 2
+#define SUBSUBFRAMES 2
+#define PCM_SAMPLES (SUBFRAMES*SUBSUBFRAMES*8)
 
 typedef struct {
     PutBitContext pb;
     int32_t history[MAX_CHANNELS][512]; /* This is a circular buffer */
     int start[MAX_CHANNELS];
+    int frame_size;
+    int prim_channels;
+    int sample_rate_code;
 
     int32_t pcm[DCA_SUBBANDS_32];
-    int32_t subband[64][MAX_CHANNELS][DCA_SUBBANDS_32]; /* [sample][channel][subband] */
+    int32_t subband[PCM_SAMPLES][MAX_CHANNELS][DCA_SUBBANDS_32]; /* [sample][channel][subband] */
 } DCAContext;
 
 static int32_t cos_table[128];
@@ -134,21 +142,19 @@ static void put_frame_header(DCAContext 
     /* CRC is not present */
     put_bits(&c->pb, 1, 0);
 
-    /* Number of PCM sample blocks: 64
-       (larger values are unusable with 1:1 compression due to high bitrate
-       and frame size limitation) */
-    put_bits(&c->pb, 7, 63);
+    /* Number of PCM sample blocks */
+    put_bits(&c->pb, 7, PCM_SAMPLES-1);
 
     /* Primary frame byte size: 7168 */
-    put_bits(&c->pb, 14, FIXED_FRAME_SIZE);
+    put_bits(&c->pb, 14, c->frame_size-1);
 
     /* Audio channel arrangement: L + R (stereo) */
-    put_bits(&c->pb, 6, 2);
+    put_bits(&c->pb, 6, c->prim_channels==2?2:9); //FIXME
 
-    /* Core audio sampling frequency: 44100 Hz */
-    put_bits(&c->pb, 4, 8);
+    /* Core audio sampling frequency */
+    put_bits(&c->pb, 4, c->sample_rate_code);
 
-    /* Transmission bit rate: 1411.2 kbps */
+    /* Transmission bit rate: 1411.2 kbps */ //FIXME
     put_bits(&c->pb, 5, 0x16);
 
     /* Embedded down mix: disabled */
@@ -206,48 +212,55 @@ static void put_frame_header(DCAContext 
 
 static void put_primary_audio_header(DCAContext *c)
 {
-    /* Number of subframes: 2 */
-    put_bits(&c->pb, 4, 1);
+    /* From dca.c */
+    static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 };
+    static const int thr[11] = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 };
 
-    /* Number of primary audio channels: 2 */
-    put_bits(&c->pb, 3, 1);
+    int ch, i;
+    /* Number of subframes */
+    put_bits(&c->pb, 4, SUBFRAMES-1);
+
+    /* Number of primary audio channels */
+    put_bits(&c->pb, 3, c->prim_channels-1);
 
     /* Subband activity count: 27 + 27 */
-    put_bits(&c->pb, 5, 25);
-    put_bits(&c->pb, 5, 25);
+    for(ch=0; ch<c->prim_channels; ch++){
+        put_bits(&c->pb, 5, 25);
+    }
 
     /* High frequency VQ start subband: 27, 27 */
-    put_bits(&c->pb, 5, 26);
-    put_bits(&c->pb, 5, 26);
+    for(ch=0; ch<c->prim_channels; ch++){
+        put_bits(&c->pb, 5, 26);
+    }
 
     /* Joint intensity coding index: 0, 0 */
-    put_bits(&c->pb, 3, 0);
-    put_bits(&c->pb, 3, 0);
+    for(ch=0; ch<c->prim_channels; ch++){
+        put_bits(&c->pb, 3, 0);
+    }
 
     /* Transient mode codebook: A4, A4 (arbitrary) */
-    put_bits(&c->pb, 2, 0);
-    put_bits(&c->pb, 2, 0);
+    for(ch=0; ch<c->prim_channels; ch++){
+        put_bits(&c->pb, 2, 0);
+    }
 
     /* Scale factor code book: 7 bit linear, 7-bit sqrt table (for each channel) */
-    put_bits(&c->pb, 3, 6);
-    put_bits(&c->pb, 3, 6);
+    for(ch=0; ch<c->prim_channels; ch++){
+        put_bits(&c->pb, 3, 6);
+    }
 
     /* Bit allocation quantizer select: linear 5-bit */
-    put_bits(&c->pb, 3, 6);
-    put_bits(&c->pb, 3, 6);
+    for(ch=0; ch<c->prim_channels; ch++){
+        put_bits(&c->pb, 3, 6);
+    }
 
     /* Quantization index codebook select: dummy data
        to avoid transmission of scale factor adjustment */
-    put_bits(&c->pb, 1, 1); put_bits(&c->pb, 1, 1);
-    put_bits(&c->pb, 2, 3); put_bits(&c->pb, 2, 3);
-    put_bits(&c->pb, 2, 3); put_bits(&c->pb, 2, 3);
-    put_bits(&c->pb, 2, 3); put_bits(&c->pb, 2, 3);
-    put_bits(&c->pb, 2, 3); put_bits(&c->pb, 2, 3);
-    put_bits(&c->pb, 3, 7); put_bits(&c->pb, 3, 7);
-    put_bits(&c->pb, 3, 7); put_bits(&c->pb, 3, 7);
-    put_bits(&c->pb, 3, 7); put_bits(&c->pb, 3, 7);
-    put_bits(&c->pb, 3, 7); put_bits(&c->pb, 3, 7);
-    put_bits(&c->pb, 3, 7); put_bits(&c->pb, 3, 7);
+
+    for(i=1; i<11; i++){
+        for(ch=0; ch<c->prim_channels; ch++){
+            put_bits(&c->pb, bitlen[i], thr[i]);
+        }
+    }
 
     /* Scale factor adjustment index: not transmitted */
 }
@@ -260,35 +273,36 @@ static uint32_t quantize(int32_t d)
 }
 
 
-static void put_subframe(DCAContext *c, int32_t subband_data[32][2][32])
+static void put_subframe(DCAContext *c, int32_t subband_data[8*SUBSUBFRAMES][MAX_CHANNELS][32])
 {
     int i, sub, ss, ch;
-
-    /* Subsubframes count: 4 */
-    put_bits(&c->pb, 2, 3);
+    /* Subsubframes count */
+    put_bits(&c->pb, 2, SUBSUBFRAMES -1);
 
     /* Partial subsubframe sample count: dummy */
     put_bits(&c->pb, 3, 0);
 
     /* Prediction mode: no ADPCM, in each channel and subband */
-    for (ch = 0; ch < 2; ch++)
+    for (ch = 0; ch < c->prim_channels; ch++)
         for (sub = 0; sub < 27; sub++)
             put_bits(&c->pb, 1, 0);
 
     /* Prediction VQ addres: not transmitted */
     /* Bit allocation index: 19 = "16 bits", for each channel and subband */
-    for (ch = 0; ch < 2; ch++)
+    for (ch = 0; ch < c->prim_channels; ch++)
         for (sub = 0; sub < 27; sub++)
             put_bits(&c->pb, 5, 19);
 
-    /* Transition mode: none for each channel and subband */
-    for (ch = 0; ch < 2; ch++)
-        for (sub = 0; sub < 27; sub++)
-            put_bits(&c->pb, 1, 0); /* according to Huffman codebook A4 */
+    if(SUBSUBFRAMES>1){
+        /* Transition mode: none for each channel and subband */
+        for (ch = 0; ch < c->prim_channels; ch++)
+            for (sub = 0; sub < 27; sub++)
+                put_bits(&c->pb, 1, 0); /* according to Huffman codebook A4 */
+    }
 
     /* Scale factors: the same for each channel and subband,
        encoded according to Table D.1.2 */
-    for (ch = 0; ch < 2; ch++)
+    for (ch = 0; ch < c->prim_channels; ch++)
         for (sub = 0; sub < 27; sub++)
             put_bits(&c->pb, 7, 110);
 
@@ -301,8 +315,8 @@ static void put_subframe(DCAContext *c, 
     /* LFE data: none */
     /* Audio data: 4 subsubframes */
 
-    for (ss = 0; ss < 4 ; ss++)
-        for (ch = 0; ch < 2; ch++)
+    for (ss = 0; ss < SUBSUBFRAMES ; ss++)
+        for (ch = 0; ch < c->prim_channels; ch++)
             for (sub = 0; sub < 27; sub++)
                 for (i = 0; i < 8; i++)
                     put_bits(&c->pb, 16, quantize(subband_data[ss * 8 + i][ch][sub]));
@@ -310,17 +324,21 @@ static void put_subframe(DCAContext *c, 
     put_bits(&c->pb, 16, 0xffff);
 }
 
-void put_frame(DCAContext *c, int32_t subband_data[64][2][32], uint8_t *frame)
+void put_frame(DCAContext *c, int32_t subband_data[PCM_SAMPLES][MAX_CHANNELS][32], uint8_t *frame)
 {
-    int channel;
-    init_put_bits(&c->pb, frame, DCA_MAX_FRAME_SIZE);
+    int i;
+    init_put_bits(&c->pb, frame + DCA_HEADER_SIZE, DCA_MAX_FRAME_SIZE-DCA_HEADER_SIZE);
 
-    put_frame_header(c);
     put_primary_audio_header(c);
-    for (channel=0 ; channel<2; channel++)
-        put_subframe(c, &subband_data[32 * channel]);
+    for(i=0; i<SUBFRAMES; i++)
+        put_subframe(c, &subband_data[SUBSUBFRAMES * 8 * i]);
 
     flush_put_bits(&c->pb);
+    c->frame_size = (put_bits_count(&c->pb)>>3) + DCA_HEADER_SIZE;
+
+    init_put_bits(&c->pb, frame, DCA_HEADER_SIZE);
+    put_frame_header(c);
+    flush_put_bits(&c->pb);
 }
 
 static int DCA_encode_frame(AVCodecContext *avctx,
@@ -333,11 +351,11 @@ static int DCA_encode_frame(AVCodecConte
 //    if (buf_size < MAX_CHANNELS*2048*sizeof(int16_t))
 //        return -1;
 
-    for (i = 0; i < 64; i ++) /* i is the decimated sample number */
-        for (channel=0; channel<2 ; channel++) {
+    for (i = 0; i < PCM_SAMPLES; i ++) /* i is the decimated sample number */
+        for (channel=0; channel<c->prim_channels; channel++) {
             /* Get 32 PCM samples */
             for (k = 0; k < 32; k++) { /* k is the sample number in a 32-sample block */
-                c->pcm[k] = samples[2 * (32*i+k) + channel] << 16;
+                c->pcm[k] = samples[avctx->channels * (32*i+k) + channel] << 16;
             }
             /* Put subband samples into the proper place */
             qmf_decompose(c, c->pcm, &c->subband[i][channel][0], channel);
@@ -345,18 +363,31 @@ static int DCA_encode_frame(AVCodecConte
 
     put_frame(c, c->subband, frame);
 
-    return put_bits_count(&c->pb)>>3;
+    return c->frame_size;
 }
 
 static int DCA_encode_init(AVCodecContext *avctx) {
-    //DCAContext *c = avctx->priv_data;
+    DCAContext *c = avctx->priv_data;
+    int i;
 
-    if(avctx->channels != 2 || avctx->sample_rate != 44100) {
-        av_log(avctx, AV_LOG_ERROR, "Only 44.1 kHz stereo is supported at the moment!\n");
+    c->prim_channels = FFMIN(avctx->channels, 5); //XXX only 5 channels
+
+    for(i=0; i<16; i++){
+        if(dca_sample_rates[i] == avctx->sample_rate)
+            break;
+    }
+    if(i==16){
+        av_log(avctx, AV_LOG_ERROR, "Sample rate %iHz not supported\n", avctx->sample_rate);
         return -1;
     }
+    c->sample_rate_code = i;
 
-    avctx->frame_size = 2048;
+    if(avctx->channels != 2 && avctx->channels != 6) {
+        av_log(avctx, AV_LOG_ERROR, "Only stereo and 5.1 supported at the moment!\n");
+        return -1;
+    }
+
+    avctx->frame_size = 32 * PCM_SAMPLES;
 
     qmf_init();
     return 0;


More information about the FFmpeg-soc mailing list