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

📄 aac_in.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / AAC reader 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.  *		 */#include <gpac/modules/service.h>#include <gpac/modules/codec.h>#include <gpac/avparse.h>#include <gpac/constants.h>typedef struct{	GF_ClientService *service;	Bool is_remote;		FILE *stream;	u32 duration;	Bool needs_connection;	u32 pad_bytes;	Bool done;	u32 is_inline;	LPNETCHANNEL ch;	unsigned char *data;	u32 data_size;	GF_SLHeader sl_hdr;	u32 sample_rate, oti, sr_idx, nb_ch, prof;	Double start_range, end_range;	u32 current_time, nb_samp;	/*file downloader*/	GF_DownloadSession * dnload;	Bool is_live;	char prev_data[1000];	u32 prev_size;	char *icy_name;	char *icy_genre;	char *icy_track_name;} AACReader;typedef struct{	Bool is_mp2, no_crc;	u32 profile, sr_idx, nb_ch, frame_size, hdr_size;} ADTSHeader;static Bool AAC_CanHandleURL(GF_InputService *plug, const char *url){	char *sExt;	sExt = strrchr(url, '.');	if (!sExt) return 0;	if (gf_term_check_extension(plug, "audio/x-m4a", "aac", "MPEG-4 AAC Music", sExt)) return 1;	if (gf_term_check_extension(plug, "audio/aac", "aac", "MPEG-4 AAC Music", sExt)) return 1;	if (gf_term_check_extension(plug, "audio/aacp", "aac", "MPEG-4 AACPlus Music", sExt)) return 1;	return 0;}static Bool aac_is_local(const char *url){	if (!strnicmp(url, "file://", 7)) return 1;	if (strstr(url, "://")) return 0;	return 1;}static GF_ESD *AAC_GetESD(AACReader *read){	GF_BitStream *dsi;	GF_ESD *esd;	u32 i, sbr_sr_idx;	esd = gf_odf_desc_esd_new(0);	esd->decoderConfig->streamType = GF_STREAM_AUDIO;	esd->decoderConfig->objectTypeIndication = read->oti;	esd->ESID = 1;	esd->OCRESID = 1;	esd->slConfig->timestampResolution = read->sample_rate;	if (read->is_live) esd->slConfig->useAccessUnitEndFlag = esd->slConfig->useAccessUnitStartFlag = 1;	dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);	/*write as regular AAC*/	gf_bs_write_int(dsi, read->prof, 5);	gf_bs_write_int(dsi, read->sr_idx, 4);	gf_bs_write_int(dsi, read->nb_ch, 4);	gf_bs_align(dsi);	/*always signal implicit S	BR in case it's used*/	sbr_sr_idx = read->sr_idx;	for (i=0; i<16; i++) {		if (GF_M4ASampleRates[i] == (u32) 2*read->sample_rate) {			sbr_sr_idx = i;			break;		}	}	gf_bs_write_int(dsi, 0x2b7, 11);	gf_bs_write_int(dsi, 5, 5);	gf_bs_write_int(dsi, 1, 1);	gf_bs_write_int(dsi, sbr_sr_idx, 4);	gf_bs_align(dsi);	gf_bs_get_content(dsi, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength);	gf_bs_del(dsi);	return esd;}static void AAC_SetupObject(AACReader *read){	GF_ESD *esd;	GF_ObjectDescriptor *od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);	od->objectDescriptorID = 1;	esd = AAC_GetESD(read);	esd->OCRESID = 0;	gf_list_add(od->ESDescriptors, esd);	gf_term_add_media(read->service, (GF_Descriptor*)od, 0);}static Bool ADTS_SyncFrame(GF_BitStream *bs, Bool is_complete, ADTSHeader *hdr){	u32 val, pos, start_pos;	start_pos = (u32) gf_bs_get_position(bs);	while (gf_bs_available(bs)) {		val = gf_bs_read_u8(bs);		if (val!=0xFF) continue;		val = gf_bs_read_int(bs, 4);		if (val != 0x0F) {			gf_bs_read_int(bs, 4);			continue;		}		hdr->is_mp2 = gf_bs_read_int(bs, 1);		gf_bs_read_int(bs, 2);		hdr->no_crc = gf_bs_read_int(bs, 1);		pos = (u32) gf_bs_get_position(bs) - 2;		hdr->profile = 1 + gf_bs_read_int(bs, 2);		hdr->sr_idx = gf_bs_read_int(bs, 4);		gf_bs_read_int(bs, 1);		hdr->nb_ch = gf_bs_read_int(bs, 3);		gf_bs_read_int(bs, 4);		hdr->frame_size = gf_bs_read_int(bs, 13);		gf_bs_read_int(bs, 11);		gf_bs_read_int(bs, 2);		hdr->hdr_size = 7;		if (!hdr->no_crc) {			gf_bs_read_u16(bs);			hdr->hdr_size = 9;		}		if (hdr->frame_size < hdr->hdr_size) {			gf_bs_seek(bs, pos+1);			continue;		}		hdr->frame_size -= hdr->hdr_size;		if (is_complete && (gf_bs_available(bs) == hdr->frame_size)) return 1;		else if (gf_bs_available(bs) <= hdr->frame_size) break;		gf_bs_skip_bytes(bs, hdr->frame_size);		val = gf_bs_read_u8(bs);		if (val!=0xFF) {			gf_bs_seek(bs, pos+1);			continue;		}		val = gf_bs_read_int(bs, 4);		if (val!=0x0F) {			gf_bs_read_int(bs, 4);			gf_bs_seek(bs, pos+1);			continue;		}		gf_bs_seek(bs, pos+hdr->hdr_size);		return 1;	}	gf_bs_seek(bs, start_pos);	return 0;}static Bool AAC_ConfigureFromFile(AACReader *read){	Bool sync;	GF_BitStream *bs;	ADTSHeader hdr;	if (!read->stream) return 0;	bs = gf_bs_from_file(read->stream, GF_BITSTREAM_READ);	sync = ADTS_SyncFrame(bs, !read->is_remote, &hdr);	if (!sync) {		gf_bs_del(bs);		return 0;	}	read->nb_ch = hdr.nb_ch;	read->prof = hdr.profile;	read->sr_idx = hdr.sr_idx;	read->oti = hdr.is_mp2 ? read->prof+0x66 : 0x40;	read->sample_rate = GF_M4ASampleRates[read->sr_idx];	read->duration = 0;		if (!read->is_remote) {		read->duration = 1024;		gf_bs_skip_bytes(bs, hdr.frame_size);		while (ADTS_SyncFrame(bs, !read->is_remote, &hdr)) {			read->duration += 1024;			gf_bs_skip_bytes(bs, hdr.frame_size);		}	}	gf_bs_del(bs);	fseek(read->stream, 0, SEEK_SET);	return 1;}static void AAC_RegulateDataRate(AACReader *read){	GF_NetworkCommand com;	memset(&com, 0, sizeof(GF_NetworkCommand));	com.command_type = GF_NET_CHAN_BUFFER_QUERY;	com.base.on_channel = read->ch;	while (read->ch) {		gf_term_on_command(read->service, &com, GF_OK);		if (com.buffer.occupancy < com.buffer.max) break;		gf_sleep(2);	}}static void AAC_OnLiveData(AACReader *read, char *data, u32 data_size){	u32 pos;	Bool sync;	GF_BitStream *bs;	ADTSHeader hdr;		read->data = realloc(read->data, sizeof(char)*(read->data_size+data_size) );	memcpy(read->data + read->data_size, data, sizeof(char)*data_size);	read->data_size += data_size;	if (read->needs_connection) {		read->needs_connection = 0;		bs = gf_bs_new(read->data, read->data_size, GF_BITSTREAM_READ);		sync = ADTS_SyncFrame(bs, 0, &hdr);		gf_bs_del(bs);		if (!sync) return;		read->nb_ch = hdr.nb_ch;		read->prof = hdr.profile;		read->sr_idx = hdr.sr_idx;		read->oti = hdr.is_mp2 ? read->prof+0x66-1 : 0x40;		read->sample_rate = GF_M4ASampleRates[read->sr_idx];		read->is_live = 1;		memset(&read->sl_hdr, 0, sizeof(GF_SLHeader));		gf_term_on_connect(read->service, NULL, GF_OK);		AAC_SetupObject(read);	}	if (!read->ch) return;	/*need a full adts header*/	if (read->data_size<=7) return;	bs = gf_bs_new(read->data, read->data_size, GF_BITSTREAM_READ);	hdr.frame_size = pos = 0;	while (ADTS_SyncFrame(bs, 0, &hdr)) {		pos = (u32) gf_bs_get_position(bs);		read->sl_hdr.accessUnitStartFlag = 1;		read->sl_hdr.accessUnitEndFlag = 1;		read->sl_hdr.AU_sequenceNumber++;		read->sl_hdr.compositionTimeStampFlag = 1;		read->sl_hdr.compositionTimeStamp += 1024;		gf_term_on_sl_packet(read->service, read->ch, read->data + pos, hdr.frame_size, &read->sl_hdr, GF_OK);		gf_bs_skip_bytes(bs, hdr.frame_size);	}	pos = (u32) gf_bs_get_position(bs);	gf_bs_del(bs);	if (pos) {		char *d;		read->data_size -= pos;		d = malloc(sizeof(char) * read->data_size);		memcpy(d, read->data + pos, sizeof(char) * read->data_size);		free(read->data);		read->data = d;	}	AAC_RegulateDataRate(read);}void AAC_NetIO(void *cbk, GF_NETIO_Parameter *param){	GF_Err e;	const char *szCache;	u32 total_size, bytes_done;	AACReader *read = (AACReader *) cbk;	e = param->error;	/*done*/	if (param->msg_type==GF_NETIO_DATA_TRANSFERED) {		if (read->stream) {			read->is_remote = 0;			e = GF_EOS;		} else {			return;		}	} else if (param->msg_type==GF_NETIO_PARSE_HEADER) {		if (!strcmp(param->name, "icy-name")) {			if (read->icy_name) free(read->icy_name);			read->icy_name = strdup(param->value);		}		if (!strcmp(param->name, "icy-genre")) {			if (read->icy_genre) free(read->icy_genre);			read->icy_genre = strdup(param->value);		}		if (!strcmp(param->name, "icy-meta")) {			GF_NetworkCommand com;			char *meta;			if (read->icy_track_name) free(read->icy_track_name);			read->icy_track_name = NULL;			meta = param->value;			while (meta && meta[0]) {				char *sep = strchr(meta, ';');				if (sep) sep[0] = 0;					if (!strnicmp(meta, "StreamTitle=", 12)) {					read->icy_track_name = strdup(meta+12);				}				if (!sep) break;				sep[0] = ';';				meta = sep+1;			}			com.base.command_type = GF_NET_SERVICE_INFO;			gf_term_on_command(read->service, &com, GF_OK);		}		return;	} else {		/*handle service message*/		gf_term_download_update_stats(read->dnload);		if (param->msg_type!=GF_NETIO_DATA_EXCHANGE) return;	}	/*data fetching or EOS*/	if (e >= GF_OK) {		if (read->needs_connection) {			gf_dm_sess_get_stats(read->dnload, NULL, NULL, &total_size, NULL, NULL, NULL);			if (!total_size) read->is_live = 1;		}		if (read->is_live) {			if (!e) AAC_OnLiveData(read, param->data, param->size);			return;		}		if (read->stream) return;		/*open service*/		szCache = gf_dm_sess_get_cache_name(read->dnload);		if (!szCache) e = GF_IO_ERR;		else {			read->stream = fopen((char *) szCache, "rb");			if (!read->stream) e = GF_SERVICE_ERROR;			else {				/*if full file at once (in cache) parse duration*/				if (e==GF_EOS) read->is_remote = 0;				e = GF_OK;				/*not enough data*/				if (!AAC_ConfigureFromFile(read)) {

⌨️ 快捷键说明

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