changeset 2432:d9cf90e66883 libavcodec

Decode MP3 in ADU format
author rtognimp
date Sat, 15 Jan 2005 14:59:47 +0000
parents d67740c88f86
children 0934621b6453
files allcodecs.c avcodec.h mpegaudiodec.c
diffstat 3 files changed, 78 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/allcodecs.c	Sat Jan 15 14:05:37 2005 +0000
+++ b/allcodecs.c	Sat Jan 15 14:59:47 2005 +0000
@@ -142,6 +142,7 @@
 #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);
--- a/avcodec.h	Sat Jan 15 14:05:37 2005 +0000
+++ b/avcodec.h	Sat Jan 15 14:59:47 2005 +0000
@@ -17,7 +17,7 @@
 
 #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 @@
     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 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;
--- a/mpegaudiodec.c	Sat Jan 15 14:05:37 2005 +0000
+++ b/mpegaudiodec.c	Sat Jan 15 14:59:47 2005 +0000
@@ -98,6 +98,7 @@
     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 @@
 #ifdef DEBUG
     s->frame_count = 0;
 #endif
+    if (avctx->codec_id == CODEC_ID_MP3ADU)
+        s->adu_mode = 1;
     return 0;
 }
 
@@ -2298,9 +2301,11 @@
         }
     }
 
+  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 @@
     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 @@
     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,
+};