Decode MP3 in ADU format
authorRoberto Togni <r_togni@tiscali.it>
Sat, 15 Jan 2005 14:59:47 +0000 (14:59 +0000)
committerRoberto Togni <r_togni@tiscali.it>
Sat, 15 Jan 2005 14:59:47 +0000 (14:59 +0000)
Originally committed as revision 3839 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/allcodecs.c
libavcodec/avcodec.h
libavcodec/mpegaudiodec.c

index 4e19069..62bfc54 100644 (file)
@@ -142,6 +142,7 @@ void avcodec_register_all(void)
 #endif
     register_avcodec(&mp2_decoder);
     register_avcodec(&mp3_decoder);
+    register_avcodec(&mp3adu_decoder);
     register_avcodec(&mace3_decoder);
     register_avcodec(&mace6_decoder);
     register_avcodec(&huffyuv_decoder);
index 77f00cd..921ea68 100644 (file)
@@ -17,7 +17,7 @@ extern "C" {
 
 #define FFMPEG_VERSION_INT     0x000409
 #define FFMPEG_VERSION         "0.4.9-pre1"
-#define LIBAVCODEC_BUILD       4737
+#define LIBAVCODEC_BUILD       4738
 
 #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT
 #define LIBAVCODEC_VERSION     FFMPEG_VERSION
@@ -159,6 +159,7 @@ enum CodecID {
     CODEC_ID_SONIC,
     CODEC_ID_SONIC_LS,
     CODEC_ID_FLAC,
+    CODEC_ID_MP3ADU,
     
     CODEC_ID_MPEG2TS= 0x20000, /* _FAKE_ codec to indicate a raw MPEG2 transport
                          stream (only used by libavformat) */
@@ -1906,6 +1907,7 @@ extern AVCodec sp5x_decoder;
 extern AVCodec png_decoder;
 extern AVCodec mp2_decoder;
 extern AVCodec mp3_decoder;
+extern AVCodec mp3adu_decoder;
 extern AVCodec mace3_decoder;
 extern AVCodec mace6_decoder;
 extern AVCodec huffyuv_decoder;
index 48a1684..50ccc15 100644 (file)
@@ -98,6 +98,7 @@ typedef struct MPADecodeContext {
     int frame_count;
 #endif
     void (*compute_antialias)(struct MPADecodeContext *s, struct GranuleDef *g);
+    int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3
 } MPADecodeContext;
 
 /* layer 3 "granule" */
@@ -532,6 +533,8 @@ static int decode_init(AVCodecContext * avctx)
 #ifdef DEBUG
     s->frame_count = 0;
 #endif
+    if (avctx->codec_id == CODEC_ID_MP3ADU)
+        s->adu_mode = 1;
     return 0;
 }
 
@@ -2298,9 +2301,11 @@ static int mp_decode_layer3(MPADecodeContext *s)
         }
     }
 
+  if (!s->adu_mode) {
     /* now we get bits from the main_data_begin offset */
     dprintf("seekback: %d\n", main_data_begin);
     seek_to_maindata(s, main_data_begin);
+  }
 
     for(gr=0;gr<nb_granules;gr++) {
         for(ch=0;ch<s->nb_channels;ch++) {
@@ -2669,6 +2674,62 @@ static int decode_frame(AVCodecContext * avctx,
     return buf_ptr - buf;
 }
 
+
+static int decode_frame_adu(AVCodecContext * avctx,
+                       void *data, int *data_size,
+                       uint8_t * buf, int buf_size)
+{
+    MPADecodeContext *s = avctx->priv_data;
+    uint32_t header;
+    int len, out_size;
+    short *out_samples = data;
+
+    len = buf_size;
+
+    // Discard too short frames
+    if (buf_size < HEADER_SIZE) {
+        *data_size = 0;
+        return buf_size;
+    }
+
+
+    if (len > MPA_MAX_CODED_FRAME_SIZE)
+        len = MPA_MAX_CODED_FRAME_SIZE;
+
+    memcpy(s->inbuf, buf, len);
+    s->inbuf_ptr = s->inbuf + len;
+
+    // Get header and restore sync word
+    header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
+              (s->inbuf[2] << 8) | s->inbuf[3] | 0xffe00000;
+
+    if (check_header(header) < 0) { // Bad header, discard frame
+        *data_size = 0;
+        return buf_size;
+    }
+
+    decode_header(s, header);
+    /* update codec info */
+    avctx->sample_rate = s->sample_rate;
+    avctx->channels = s->nb_channels;
+    avctx->bit_rate = s->bit_rate;
+    avctx->sub_id = s->layer;
+
+    avctx->frame_size=s->frame_size = len;
+
+    if (avctx->parse_only) {
+        /* simply return the frame data */
+        *(uint8_t **)data = s->inbuf;
+        out_size = s->inbuf_ptr - s->inbuf;
+    } else {
+        out_size = mp_decode_frame(s, out_samples);
+    }
+
+    *data_size = out_size;
+    return buf_size;
+}
+
+
 AVCodec mp2_decoder =
 {
     "mp2",
@@ -2694,3 +2755,16 @@ AVCodec mp3_decoder =
     decode_frame,
     CODEC_CAP_PARSE_ONLY,
 };
+
+AVCodec mp3adu_decoder =
+{
+    "mp3adu",
+    CODEC_TYPE_AUDIO,
+    CODEC_ID_MP3ADU,
+    sizeof(MPADecodeContext),
+    decode_init,
+    NULL,
+    NULL,
+    decode_frame_adu,
+    CODEC_CAP_PARSE_ONLY,
+};