- Log ----------------------------------------------------------------- commit 6e9317c15dc62a45a2325acc145c00e086f1026e Author: Naufal <naufa...@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 _______________________________________________ FFmpeg-soc mailing list FFmpeg-soc@mplayerhq.hu https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc