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

📄 amr_float_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>#ifdef GPAC_HAS_AMR_FT/*AMR NB*/#include "amr_nb_ft/interf_dec.h"#endif#ifdef GPAC_HAS_AMR_FT_WB/*AMR WB*/#include "amr_wb_ft/dec_if.h"#endif/*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{	Bool is_amr_wb;	u32 sample_rate, out_size, num_samples;	u8 num_channels;	/*AMR NB state vars*/	int *nb_destate;    void *wb_destate;} AMRFTDec;#define AMRFTCTX() AMRFTDec *ctx = (AMRFTDec *) 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;	AMRFTCTX();	if (DependsOnES_ID) return GF_NOT_SUPPORTED;		/*AMRWB dec is another module*/	if (!strnicmp(decSpecInfo, "sawb", 4)) ctx->is_amr_wb = 1;	else if (!strnicmp(decSpecInfo, "samr", 4) || !strnicmp(decSpecInfo, "amr ", 4)) ctx->is_amr_wb = 0;	else return GF_NOT_SUPPORTED;	bs = gf_bs_new(decSpecInfo, decSpecInfoSize, GF_BITSTREAM_READ);	gf_bs_read_u32(bs);	gf_bs_read_u16(bs);	gf_bs_read_u16(bs);	ctx->num_channels = gf_bs_read_u8(bs);	gf_bs_read_u8(bs);	packed = gf_bs_read_u8(bs);	gf_bs_del(bs);	/*max possible frames in a sample are seen in MP4, that's 15*/	if (!packed) packed = 15;	if (ctx->is_amr_wb) {#ifdef GPAC_HAS_AMR_FT_WB		ctx->wb_destate = D_IF_init();		if (!ctx->wb_destate) return GF_IO_ERR;#else		return GF_NOT_SUPPORTED;#endif		ctx->num_samples = 320;		ctx->sample_rate = 16000;	} else {#ifdef GPAC_HAS_AMR_FT		ctx->nb_destate = Decoder_Interface_init();		if (!ctx->nb_destate) return GF_IO_ERR;#else		return GF_NOT_SUPPORTED;#endif		ctx->num_samples = 160;		ctx->sample_rate = 8000;	}	ctx->out_size = packed * 2 * ctx->num_samples * ctx->num_channels;	return GF_OK;}static GF_Err AMR_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID){	AMRFTCTX();#ifdef GPAC_HAS_AMR_FT	if (ctx->nb_destate) Decoder_Interface_exit(ctx->nb_destate);#endif	ctx->nb_destate = NULL;#ifdef GPAC_HAS_AMR_FT_WB	if (ctx->wb_destate) D_IF_exit(ctx->wb_destate);#endif	ctx->wb_destate = NULL;	ctx->sample_rate = ctx->out_size = ctx->num_samples = 0;	ctx->num_channels = 0;	return GF_OK;}static GF_Err AMR_GetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability *capability){	AMRFTCTX();	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 = ctx->sample_rate;		break;	case GF_CODEC_NB_CHAN:		capability->cap.valueInt = ctx->num_channels;		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;	/*FIXME: get exact sampling window*/	case GF_CODEC_CU_DURATION:		capability->cap.valueInt = ctx->num_samples;		break;	case GF_CODEC_PADDING_BYTES:		capability->cap.valueInt = 4;		break;	case GF_CODEC_CHANNEL_CONFIG:		if (ctx->num_channels==1) {			capability->cap.valueInt = GF_AUDIO_CH_FRONT_CENTER;		} else {			capability->cap.valueInt = GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT;		}		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;}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;    u8 toc, ft;	AMRFTCTX();	/*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;	}		*outBufferLength = 0;    while (inBufferLength) {		toc = inBuffer[0];		ft = (toc >> 3) & 0x0F;		offset = 0;		if (ctx->is_amr_wb) {#ifdef GPAC_HAS_AMR_FT_WB			D_IF_decode(ctx->wb_destate, inBuffer, (Word16 *) outBuffer, 0);			*outBufferLength += 320*2;			outBuffer += 320*2;			offset = GF_AMR_WB_FRAME_SIZE[ft] + 1;#endif		} else {#ifdef GPAC_HAS_AMR_FT			Decoder_Interface_Decode(ctx->nb_destate, inBuffer, (Word16 *) outBuffer, 0);			*outBufferLength += 160*2;			outBuffer += 160*2;			offset = GF_AMR_FRAME_SIZE[ft] + 1;#endif		}		/*don't complain but...*/		if (inBufferLength<offset) return GF_OK;		inBuffer += offset;		inBufferLength -= offset;	}	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;#ifdef GPAC_HAS_AMR_FT	if (!strnicmp(decSpecInfo, "samr", 4) || !strnicmp(decSpecInfo, "amr ", 4)) return 1;#endif#ifdef GPAC_HAS_AMR_FT_WB	if (!strnicmp(decSpecInfo, "sawb", 4)) return 1;#endif	return 0;}static const char *AMR_GetCodecName(GF_BaseDecoder *ifcg){	AMRFTCTX();	if (ctx->is_amr_wb) return "3GPP Floating-point AMR Wideband";	return "3GPP Floating-point AMR";}GF_MediaDecoder *NewAMRFTDecoder(){	AMRFTDec *dec;	GF_MediaDecoder *ifce;	GF_SAFEALLOC(ifce , GF_MediaDecoder);	dec = malloc(sizeof(AMRFTDec));	memset(dec, 0, sizeof(AMRFTDec));	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-FT 3GPP decoder", "gpac distribution");	return ifce;}void DeleteAMRFTDecoder(GF_BaseDecoder *ifcg){	AMRFTCTX();	free(ctx);	free(ifcg);}/*re-include AMR reader (we coul make it an independant module...)*/GF_InputService *NewAESReader();void DeleteAESReader(void *ifce);Bool QueryInterface(u32 InterfaceType){	switch (InterfaceType) {	case GF_MEDIA_DECODER_INTERFACE: return 1;	case GF_NET_CLIENT_INTERFACE: return 1;	default:		return 0;	}}GF_BaseInterface *LoadInterface(u32 InterfaceType){	switch (InterfaceType) {	case GF_MEDIA_DECODER_INTERFACE: return (GF_BaseInterface *)NewAMRFTDecoder();	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: DeleteAMRFTDecoder((GF_BaseDecoder *)ifce); break;	case GF_NET_CLIENT_INTERFACE:  DeleteAESReader(ifce); break;	}}

⌨️ 快捷键说明

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