[FFmpeg-soc] G723.1 Frame Parser
Stefano Sabatini
stefano.sabatini-lala at poste.it
Wed Mar 31 01:55:18 CEST 2010
On date Tuesday 2010-03-30 17:46:43 +0530, Mohamed Naufal encoded:
> Hi
>
> Here is the code for a frame parser i wrote for the g723.1 codec as my GSoC
> qualification task
>
> #include <stdint.h>
> #include "libavutil/intreadwrite.h"
>
> #include "avcodec.h"
> #include "get_bits.h"
>
> #define PITCH_MIN 18
> #define FRM_LEN 240
> #define SFRM_LEN (FRM_LEN/4)
> #define AD_CB_SIZE_HIGH_RATE 85 ///< 85 entry codebook for Frame6k3s
> #define AD_CB_SIZE_LOW_RATE 170 ///< 170 entry codebook for
> Frame5k3s
>
> /*
> * G723.1 frame types
> */
> typedef enum {
> Frame6k3, ///< 6.3 kbps frame rate
> Frame5k3, ///< 5.3 kbps frame rate
> FrameSID, ///< silence insertion descriptor frame
> FrameUntransmitted
vertical align
> } FrameType;
>
> typedef enum {
> Rate6k3,
> Rate5k3
> } Rate;
>
> /*
> * G723.1 unpacked data subframe
> */
> typedef struct {
> uint16_t ad_cb_lag; ///< adaptive codebook lag
> uint16_t pitch_lag;
> uint16_t combined_gain;
> uint16_t pulse_pos;
> uint16_t pulse_sign;
> uint16_t grid_index;
> uint16_t amp_index; ///< for SID frames
> } G723_1_Subframe;
>
> /*
> * G723.1 unpacked data frame
> */
> typedef struct {
> uint32_t lsp_index;
> G723_1_Subframe subframe[4];
> } G723_1_Frame;
>
> typedef struct g723_1_context {
> G723_1_Frame frame;
> FrameType cur_frame_type;
> Rate cur_rate;
> int is_bad_frame;
> } G723_1_Context;
>
> /*
> * Unpack the frame into parameters
nit: Unpacks ... missing final dot.
> *
> * @param p the context
> * @param buf pointer to the input buffer
> * @param buf_size size of the input buffer
> */
> static void unpack_bitstream(G723_1_Context *p, const uint8_t *buf,
> int buf_size)
> {
> GetBitContext gb;
> G723_1_Frame *frame = &p->frame;
> uint32_t temp;
>
> 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;
>
> frame->lsp_index = get_bits(&gb, 24);
>
> if (p->cur_frame_type == FrameSID) {
> frame->subframe[0].amp_index = get_bits(&gb, 6);
> return;
> }
>
> // Extract the info common to both rates
> p->cur_rate = (p->cur_frame_type == 0) ? Rate6k3 : Rate5k3;
>
> temp = get_bits(&gb, 7);
> if (temp <= 123) { // test if forbidden code
> frame->subframe[0].pitch_lag = temp + PITCH_MIN;
> }else {
> p->is_bad_frame = 1; // transmission error
> return;
> }
>
> frame->subframe[1].ad_cb_lag = get_bits(&gb, 2);
>
> temp = get_bits(&gb, 7);
> if (temp <= 123) {
> frame->subframe[1].pitch_lag = temp + PITCH_MIN;
> }else {
nit++: } else {
here and below.
> p->is_bad_frame = 1;
> return;
> }
>
> frame->subframe[3].ad_cb_lag = get_bits(&gb, 2);
>
> frame->subframe[0].ad_cb_lag = 1;
> frame->subframe[2].ad_cb_lag = 1;
>
> frame->subframe[0].combined_gain = get_bits(&gb, 12);
> frame->subframe[1].combined_gain = get_bits(&gb, 12);
> frame->subframe[2].combined_gain = get_bits(&gb, 12);
> frame->subframe[3].combined_gain = get_bits(&gb, 12);
>
> frame->subframe[0].grid_index = get_bits(&gb, 1);
> frame->subframe[1].grid_index = get_bits(&gb, 1);
> frame->subframe[2].grid_index = get_bits(&gb, 1);
> frame->subframe[3].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 13bit combined position index
> temp = get_bits(&gb, 13);
> frame->subframe[0].pulse_pos = (temp / 90) / 9;
> frame->subframe[1].pulse_pos = (temp / 90) % 9;
> frame->subframe[2].pulse_pos = (temp % 90) / 9;
> frame->subframe[3].pulse_pos = (temp % 90) % 9;
>
> frame->subframe[0].pulse_pos = (frame->subframe[0].pulse_pos << 16)
> +
> get_bits(&gb, 16);
> frame->subframe[1].pulse_pos = (frame->subframe[1].pulse_pos << 14)
> +
> get_bits(&gb, 14);
> frame->subframe[2].pulse_pos = (frame->subframe[2].pulse_pos << 16)
> +
> get_bits(&gb, 16);
> frame->subframe[3].pulse_pos = (frame->subframe[3].pulse_pos << 14)
> +
> get_bits(&gb, 14);
>
> frame->subframe[0].pulse_sign = get_bits(&gb, 6);
> frame->subframe[1].pulse_sign = get_bits(&gb, 5);
> frame->subframe[2].pulse_sign = get_bits(&gb, 6);
> frame->subframe[3].pulse_sign = get_bits(&gb, 5);
> }else { // Frame5k3
> frame->subframe[0].pulse_pos = get_bits(&gb, 12);
> frame->subframe[1].pulse_pos = get_bits(&gb, 12);
> frame->subframe[2].pulse_pos = get_bits(&gb, 12);
> frame->subframe[3].pulse_pos = get_bits(&gb, 12);
>
> frame->subframe[0].pulse_sign = get_bits(&gb, 4);
> frame->subframe[1].pulse_sign = get_bits(&gb, 4);
> frame->subframe[2].pulse_sign = get_bits(&gb, 4);
> frame->subframe[3].pulse_sign = get_bits(&gb, 4);
> }
> }
>
> static int g723_1_parse_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;
>
> unpack_bitstream(p, buf, buf_size);
>
> if (p->is_bad_frame) {
> av_log_error(avctx, AV_LOG_ERROR, "Bad frame\n");
> return AVERROR_INVALIDDATA;
> }
>
> return 0;
> }
>
> AVCodec g723_1_decoder = {
> .name = "g723_1",
> .type = CODEC_TYPE_AUDIO,
AVMEDIA_TYPE_AUDIO
> .id = CODEC_ID_G723_1,
> .priv_data_size = sizeof(G723_1_Context),
> .decode = g723_1_parse_frame,
> .long_name = NULL_IF_CONFIG_SMALL("G.723.1"),
> };
Regards.
More information about the FFmpeg-soc
mailing list