[FFmpeg-soc] [soc] UNNAMED PROJECT

naufal11 at gmail.com naufal11 at gmail.com
Sat May 29 17:37:05 CEST 2010



- Log -----------------------------------------------------------------
commit 6e9317c15dc62a45a2325acc145c00e086f1026e
Author: Naufal <naufal11 at gmail.com>
Date:   Sat May 29 20:59:59 2010 +0530

    Add G723.1 decoder wireframe

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 764555e..d3cd00b 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -129,6 +129,7 @@ OBJS-$(CONFIG_FLIC_DECODER)            += flicvideo.o
 OBJS-$(CONFIG_FOURXM_DECODER)          += 4xm.o
 OBJS-$(CONFIG_FRAPS_DECODER)           += fraps.o huffman.o
 OBJS-$(CONFIG_FRWU_DECODER)            += frwu.o
+OBJS-$(CONFIG_G723_1_DECODER)          += g723_1.o
 OBJS-$(CONFIG_GIF_DECODER)             += gifdec.o lzw.o
 OBJS-$(CONFIG_GIF_ENCODER)             += gif.o lzwenc.o
 OBJS-$(CONFIG_H261_DECODER)            += h261dec.o h261.o \
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index a5d8ce1..696ed3c 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -227,6 +227,7 @@ void avcodec_register_all(void)
     REGISTER_DECODER (DSICINAUDIO, dsicinaudio);
     REGISTER_DECODER (EAC3, eac3);
     REGISTER_ENCDEC  (FLAC, flac);
+    REGISTER_DECODER (G723_1, g723_1);
     REGISTER_DECODER (IMC, imc);
     REGISTER_DECODER (MACE3, mace3);
     REGISTER_DECODER (MACE6, mace6);
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 60aa876..3f2a2a9 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -336,6 +336,7 @@ enum CodecID {
     CODEC_ID_ATRAC1,
     CODEC_ID_BINKAUDIO_RDFT,
     CODEC_ID_BINKAUDIO_DCT,
+    CODEC_ID_G723_1,
 
     /* subtitle codecs */
     CODEC_ID_DVD_SUBTITLE= 0x17000,
diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c
new file mode 100755
index 0000000..7a62b91
--- /dev/null
+++ b/libavcodec/g723_1.c
@@ -0,0 +1,191 @@
+#include "avcodec.h"
+#define ALT_BITSTREAM_READER_LE
+#include "get_bits.h"
+
+#define SUBFRAMES    4
+#define FRAME_LEN    240
+#define SUBFRAME_LEN (FRAME_LEN / SUBFRAMES)
+#define PITCH_MIN    18
+#define GAIN_LEVELS  24
+
+/*
+ * G723.1 frame types
+ */
+typedef enum {
+    Frame6k3 = 0,       ///< 6.3 kbps frame rate
+    Frame5k3,           ///< 5.3 kbps frame rate
+    FrameSID,           ///< Silence Insertion Descriptor frame
+    FrameUntransmitted
+} FrameType;
+
+static const uint8_t frame_size[4] = {24, 20, 4, 1};
+
+typedef enum {
+    Rate6k3,
+    Rate5k3
+} Rate;
+
+/*
+ * G723.1 unpacked data subframe
+ */
+typedef struct {
+    uint16_t ad_cb_lag;     ///< adaptive codebook lag
+    uint16_t ad_cb_gain;
+    uint16_t trans_gain;
+    uint16_t pulse_pos;
+    uint16_t pulse_sign;
+    uint16_t grid_index;
+    uint16_t amp_index;
+} G723_1_Subframe;
+
+typedef struct g723_1_context {
+    uint32_t lsp_index;
+    uint16_t pitch_lag[2];
+    G723_1_Subframe subframe[4];
+    FrameType cur_frame_type;
+    Rate cur_rate;
+} G723_1_Context;
+
+static av_cold int g723_1_decode_init(AVCodecContext *avctx)
+{
+    avctx->sample_fmt  = SAMPLE_FMT_S16;
+    avctx->channels    = 1;
+    avctx->sample_rate = 8000;
+    return 0;
+}
+
+/*
+ * Unpack the frame into parameters.
+ *
+ * @param p           the context
+ * @param buf         pointer to the input buffer
+ * @param buf_size    size of the input buffer
+ */
+static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf,
+                            int buf_size)
+{
+    GetBitContext gb;
+    int ad_cb_len;
+    int temp, i;
+
+    init_get_bits(&gb, buf, buf_size * 8);
+
+    // Extract frame type and rate info
+    p->cur_frame_type = get_bits(&gb, 2);
+
+    if (p->cur_frame_type == FrameUntransmitted)
+        return 0;
+
+    p->lsp_index = get_bits(&gb, 24);
+
+    if (p->cur_frame_type == FrameSID) {
+        p->subframe[0].amp_index = get_bits(&gb, 6);
+        return 0;
+    }
+
+    // Extract the info common to both rates
+    p->cur_rate = p->cur_frame_type ? Rate5k3 : Rate6k3;
+
+    p->pitch_lag[0] = get_bits(&gb, 7);
+    if (p->pitch_lag[0] > 123)       // test if forbidden code
+        return -1;
+    p->pitch_lag[0] += PITCH_MIN;
+    p->subframe[1].ad_cb_lag = get_bits(&gb, 2);
+
+    p->pitch_lag[1] = get_bits(&gb, 7);
+    if (p->pitch_lag[1] > 123)
+        return -1;
+    p->pitch_lag[1]  += PITCH_MIN;
+    p->subframe[3].ad_cb_lag  = get_bits(&gb, 2);
+    p->subframe[0].ad_cb_lag  = 1;
+    p->subframe[2].ad_cb_lag  = 1;
+
+    for (i = 0; i < SUBFRAMES; i++) {
+        // Extract combined gain
+        temp =  get_bits(&gb, 12);
+        ad_cb_len  = 170;
+        p->subframe[i].trans_gain = 0;
+        if (p->cur_rate == Rate6k3 && p->pitch_lag[i >> 1] < SUBFRAME_LEN - 2) {
+            p->subframe[i].trans_gain = temp >> 11;
+            temp &= 0x7ff;
+            ad_cb_len = 85;
+        }
+        p->subframe[i].ad_cb_gain = FASTDIV(temp, GAIN_LEVELS);
+        if (p->subframe[i].ad_cb_gain < ad_cb_len) {
+            p->subframe[i].amp_index = temp - p->subframe[i].ad_cb_gain * GAIN_LEVELS;
+        } else {
+            return -1;
+        }
+    }
+
+    for (i = 0; i < SUBFRAMES; i++)
+        p->subframe[i].grid_index = get_bits(&gb, 1);
+
+    if (p->cur_frame_type == Frame6k3) {
+        skip_bits(&gb, 1);  // skip reserved bit
+
+        // Compute pulse_pos index using the 13-bit combined position index
+        temp = get_bits(&gb, 13);
+        p->subframe[0].pulse_pos = temp / 810;
+
+        temp -= p->subframe[0].pulse_pos * 810;
+        p->subframe[1].pulse_pos = FASTDIV(temp, 90);
+
+        temp -= p->subframe[1].pulse_pos * 90;
+        p->subframe[2].pulse_pos = FASTDIV(temp, 9);
+        p->subframe[3].pulse_pos = temp - p->subframe[2].pulse_pos * 9;
+
+        p->subframe[0].pulse_pos = (p->subframe[0].pulse_pos << 16) +
+                                       get_bits(&gb, 16);
+        p->subframe[1].pulse_pos = (p->subframe[1].pulse_pos << 14) +
+                                       get_bits(&gb, 14);
+        p->subframe[2].pulse_pos = (p->subframe[2].pulse_pos << 16) +
+                                       get_bits(&gb, 16);
+        p->subframe[3].pulse_pos = (p->subframe[3].pulse_pos << 14) +
+                                       get_bits(&gb, 14);
+
+        p->subframe[0].pulse_sign = get_bits(&gb, 6);
+        p->subframe[1].pulse_sign = get_bits(&gb, 5);
+        p->subframe[2].pulse_sign = get_bits(&gb, 6);
+        p->subframe[3].pulse_sign = get_bits(&gb, 5);
+    } else { // Frame5k3
+        for (i = 0; i < SUBFRAMES; i++)
+            p->subframe[i].pulse_pos  = get_bits(&gb, 12);
+
+        for (i = 0; i < SUBFRAMES; i++)
+            p->subframe[i].pulse_sign = get_bits(&gb, 4);
+    }
+
+    return 0;
+}
+
+static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
+                              int *data_size, AVPacket *avpkt)
+{
+    G723_1_Context *p  = avctx->priv_data;
+    const uint8_t *buf = avpkt->data;
+    int buf_size       = avpkt->size;
+
+    if (!buf_size || buf_size < frame_size[buf[0] & 3]) {
+        *data_size = 0;
+        return buf_size;
+    }
+
+    if (unpack_bitstream(p, buf, buf_size) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "G723.1: Bad frame\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    return frame_size[p->cur_frame_type];
+}
+
+AVCodec g723_1_decoder = {
+    .name           = "g723_1",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = CODEC_ID_G723_1,
+    .priv_data_size = sizeof(G723_1_Context),
+    .init           = g723_1_decode_init,
+    .decode         = g723_1_decode_frame,
+    .long_name      = NULL_IF_CONFIG_SMALL("G.723.1"),
+    .capabilities   = CODEC_CAP_SUBFRAMES,
+};
diff --git a/libavformat/rtp.c b/libavformat/rtp.c
index a8dcfd7..b7ab999 100644
--- a/libavformat/rtp.c
+++ b/libavformat/rtp.c
@@ -43,7 +43,7 @@ static const struct
 {
   {0, "PCMU",        AVMEDIA_TYPE_AUDIO,   CODEC_ID_PCM_MULAW, 8000, 1},
   {3, "GSM",         AVMEDIA_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
-  {4, "G723",        AVMEDIA_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
+  {4, "G723",        AVMEDIA_TYPE_AUDIO,   CODEC_ID_G723_1, 8000, 1},
   {5, "DVI4",        AVMEDIA_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
   {6, "DVI4",        AVMEDIA_TYPE_AUDIO,   CODEC_ID_NONE, 16000, 1},
   {7, "LPC",         AVMEDIA_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},

-----------------------------------------------------------------------

Summary of changes:
 libavcodec/Makefile    |    1 +
 libavcodec/allcodecs.c |    1 +
 libavcodec/avcodec.h   |    1 +
 libavcodec/g723_1.c    |  191 ++++++++++++++++++++++++++++++++++++++++++++++++
 libavformat/rtp.c      |    2 +-
 5 files changed, 195 insertions(+), 1 deletions(-)
 create mode 100755 libavcodec/g723_1.c


-- 
http://github.com/naufal/ffmpeg-soc


More information about the FFmpeg-soc mailing list