⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 amr_dec.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / AMR decoder module * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * *//*decoder Interface*/#include <gpac/modules/codec.h>#include <gpac/modules/service.h>#include <gpac/constants.h>#include "amr_nb/sp_dec.h"#include "amr_nb/d_homing.h"/*default size in CU of composition memory for audio*/#define DEFAULT_AUDIO_CM_SIZE			12/*default critical size in CU of composition memory for audio*/#define DEFAULT_AUDIO_CM_TRIGGER		4typedef struct{	u32 out_size;	/*AMR NB state vars*/	Speech_Decode_FrameState * speech_decoder_state;    enum RXFrameType rx_type;    enum Mode mode;   	s16 reset_flag, reset_flag_old;} AMRDec;#define AMRCTX() AMRDec *ctx = (AMRDec *) ifcg->privateStackstatic GF_Err AMR_AttachStream(GF_BaseDecoder *ifcg, u16 ES_ID, char *decSpecInfo, u32 decSpecInfoSize, u16 DependsOnES_ID, u32 objectTypeIndication, Bool UpStream){	GF_BitStream *bs;	u32 packed_size;	AMRCTX();	if (DependsOnES_ID) return GF_NOT_SUPPORTED;		if (strnicmp(decSpecInfo, "samr", 4) && strnicmp(decSpecInfo, "amr ", 4)) return GF_NOT_SUPPORTED;	ctx->reset_flag = 0;	ctx->reset_flag_old = 1;	ctx->mode = 0;	ctx->rx_type = 0;	ctx->speech_decoder_state = NULL;	if (Speech_Decode_Frame_init(&ctx->speech_decoder_state, "Decoder")) return GF_IO_ERR;	bs = gf_bs_new(decSpecInfo, decSpecInfoSize, GF_BITSTREAM_READ);	gf_bs_read_u32(bs);	gf_bs_read_u16(bs);	gf_bs_read_u16(bs);	gf_bs_read_u8(bs);	gf_bs_read_u8(bs);	packed_size = (u32) gf_bs_read_u8(bs);	gf_bs_del(bs);	/*max possible frames in a sample are seen in MP4, that's 15*/	if (!packed_size) packed_size = 15;		ctx->out_size = packed_size * 2 * 160;	return GF_OK;}static GF_Err AMR_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID){	AMRCTX();	Speech_Decode_Frame_exit(&ctx->speech_decoder_state);	ctx->speech_decoder_state = NULL;	return GF_OK;}static GF_Err AMR_GetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability *capability){	AMRCTX();	switch (capability->CapCode) {	/*not tested yet*/	case GF_CODEC_RESILIENT:		capability->cap.valueInt = 1;		break;	case GF_CODEC_OUTPUT_SIZE:		capability->cap.valueInt = ctx->out_size;		break;	case GF_CODEC_SAMPLERATE:		capability->cap.valueInt = 8000;		break;	case GF_CODEC_NB_CHAN:		capability->cap.valueInt = 1;		break;	case GF_CODEC_BITS_PER_SAMPLE:		capability->cap.valueInt = 16;		break;	case GF_CODEC_BUFFER_MIN:		capability->cap.valueInt = DEFAULT_AUDIO_CM_TRIGGER;		break;	case GF_CODEC_BUFFER_MAX:		capability->cap.valueInt = DEFAULT_AUDIO_CM_SIZE;		break;	case GF_CODEC_CU_DURATION:		capability->cap.valueInt = 160;		break;	case GF_CODEC_PADDING_BYTES:		capability->cap.valueInt = 4;		break;	case GF_CODEC_CHANNEL_CONFIG:		capability->cap.valueInt = GF_AUDIO_CH_FRONT_CENTER;		break;	default:		capability->cap.valueInt = 0;		break;	}	return GF_OK;}static GF_Err AMR_SetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability capability){	/*return unsupported to avoid confusion by the player (like SR changing ...) */	return GF_NOT_SUPPORTED;}/* frame size in serial bitstream file (frame type + serial stream + flags) */#define SERIAL_FRAMESIZE (270)static GF_Err AMR_ProcessData(GF_MediaDecoder *ifcg, 		char *inBuffer, u32 inBufferLength,		u16 ES_ID,		char *outBuffer, u32 *outBufferLength,		u8 PaddingBits, u32 mmlevel){    u32 offset = 0;    u8 toc, q, ft;    s16 *synth;    u8 *packed_bits;    s16 serial[SERIAL_FRAMESIZE];    s32 i;	AMRCTX();	/*if late or seeking don't decode (each frame is a RAP)*/	/*	switch (mmlevel) {	case GF_CODEC_LEVEL_SEEK:	case GF_CODEC_LEVEL_DROP:		*outBufferLength = 0;		return GF_OK;	default:		break;	}	*/	if (ctx->out_size > *outBufferLength) {		*outBufferLength = ctx->out_size;		return GF_BUFFER_TOO_SMALL;	}	    synth = (s16 *) outBuffer;	*outBufferLength = 0;    while (inBufferLength) {        toc = inBuffer[0];        /* read rest of the frame based on ToC byte */        q = (toc >> 2) & 0x01;        ft = (toc >> 3) & 0x0F;		packed_bits = inBuffer + 1;		offset = 1 + GF_AMR_FRAME_SIZE[ft];		/*Unsort and unpack bits*/		ctx->rx_type = UnpackBits(q, ft, packed_bits, &ctx->mode, &serial[1]);		if (ctx->rx_type == RX_NO_DATA) {			ctx->mode = ctx->speech_decoder_state->prev_mode;		} else {			ctx->speech_decoder_state->prev_mode = ctx->mode;		}    		/* if homed: check if this frame is another homing frame */		if (ctx->reset_flag_old == 1) {			/* only check until end of first subframe */			ctx->reset_flag = decoder_homing_frame_test_first(&serial[1], ctx->mode);		}		/* produce encoder homing frame if homed & input=decoder homing frame */		if ((ctx->reset_flag != 0) && (ctx->reset_flag_old != 0)) {			for (i = 0; i < L_FRAME; i++) {				synth[i] = EHF_MASK;			}		} else {     			/* decode frame */			Speech_Decode_Frame(ctx->speech_decoder_state, ctx->mode, &serial[1], ctx->rx_type, synth);		}		*outBufferLength += 160*2;		synth += 160;    		/* if not homed: check whether current frame is a homing frame */		if (ctx->reset_flag_old == 0) {			ctx->reset_flag = decoder_homing_frame_test(&serial[1], ctx->mode);		}		/* reset decoder if current frame is a homing frame */		if (ctx->reset_flag != 0) {			Speech_Decode_Frame_reset(ctx->speech_decoder_state);		}		ctx->reset_flag_old = ctx->reset_flag;		if (inBufferLength < offset) return GF_OK;		inBufferLength -= offset;		inBuffer += offset;		if (*outBufferLength > ctx->out_size) return GF_NON_COMPLIANT_BITSTREAM;    }	return GF_OK;}static u32 AMR_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, u32 ObjectType, char *decSpecInfo, u32 decSpecInfoSize, u32 PL){	/*we handle audio only*/	if (!ObjectType) return (StreamType==GF_STREAM_AUDIO) ? 1 : 0;	/*audio dec*/	if (!decSpecInfo || (StreamType != GF_STREAM_AUDIO) || (ObjectType != GPAC_EXTRA_CODECS_OTI)) return 0;	if (decSpecInfoSize<4) return 0;	if (!strnicmp(decSpecInfo, "samr", 4) || !strnicmp(decSpecInfo, "amr ", 4)) return 1;	return 0;}static const char *AMR_GetCodecName(GF_BaseDecoder *dec){	return "3GPP Fixed-Point AMR NB";}GF_MediaDecoder *NewAMRDecoder(){	AMRDec *dec;	GF_MediaDecoder *ifce;	GF_SAFEALLOC(ifce , GF_MediaDecoder);	dec = malloc(sizeof(AMRDec));	memset(dec, 0, sizeof(AMRDec));	ifce->privateStack = dec;	ifce->CanHandleStream = AMR_CanHandleStream;	/*setup our own interface*/		ifce->AttachStream = AMR_AttachStream;	ifce->DetachStream = AMR_DetachStream;	ifce->GetCapabilities = AMR_GetCapabilities;	ifce->SetCapabilities = AMR_SetCapabilities;	ifce->ProcessData = AMR_ProcessData;	ifce->GetName = AMR_GetCodecName;	GF_REGISTER_MODULE_INTERFACE(ifce, GF_MEDIA_DECODER_INTERFACE, "AMR-NB 3GPP decoder", "gpac distribution");	return ifce;}void DeleteAMRDecoder(GF_BaseDecoder *ifcg){	AMRCTX();	free(ctx);	free(ifcg);}Bool QueryInterface(u32 InterfaceType){	switch (InterfaceType) {	case GF_MEDIA_DECODER_INTERFACE: return 1;	case GF_NET_CLIENT_INTERFACE: return 1;	default: return 0;	}}GF_InputService *NewAESReader();void DeleteAESReader(void *ifce);GF_BaseInterface *LoadInterface(u32 InterfaceType){	switch (InterfaceType) {	case GF_MEDIA_DECODER_INTERFACE: return (GF_BaseInterface *) NewAMRDecoder();	case GF_NET_CLIENT_INTERFACE: return (GF_BaseInterface *) NewAESReader();	default: return NULL;	}}void ShutdownInterface(GF_BaseInterface *ifce){	switch (ifce->InterfaceType) {	case GF_MEDIA_DECODER_INTERFACE: DeleteAMRDecoder((GF_BaseDecoder *)ifce); break;	case GF_NET_CLIENT_INTERFACE:  DeleteAESReader(ifce); break;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -