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

📄 swf_parse.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
	SWFSound *snd;	GF_SAFEALLOC(snd , SWFSound);	snd->ID = swf_get_16(read);	snd->format = swf_read_int(read, 4);	snd->sound_rate = swf_read_int(read, 2);	snd->bits_per_sample = swf_read_int(read, 1) ? 16 : 8;	snd->stereo = swf_read_int(read, 1);	snd->sample_count = swf_get_32(read);	switch (snd->format) {	/*raw PCM*/	case 0:		swf_report(read, GF_NOT_SUPPORTED, "Raw PCM Audio not supported");		free(snd);		break;	/*ADPCM*/	case 1:		swf_report(read, GF_NOT_SUPPORTED, "AD-PCM Audio not supported");		free(snd);		break;	/*MP3*/	case 2:	{		unsigned char bytes[4];		char szName[1024];		u32 hdr, alloc_size, size, tot_size;		char *frame;		sprintf(szName, "swf_sound_%d.mp3", snd->ID);		if (read->localPath) {			snd->szFileName = (char*)malloc(sizeof(char)*GF_MAX_PATH);			strcpy(snd->szFileName, read->localPath);			strcat(snd->szFileName, szName);		} else {			snd->szFileName = strdup(szName);		}		snd->output = fopen(snd->szFileName, "wb");		alloc_size = 1;		frame = (char*)malloc(sizeof(char));		snd->frame_delay_ms = swf_get_16(read);		snd->frame_delay_ms = 0;		tot_size = 9;		/*parse all frames*/		while (1) {			bytes[0] = swf_read_int(read, 8);			bytes[1] = swf_read_int(read, 8);			bytes[2] = swf_read_int(read, 8);			bytes[3] = swf_read_int(read, 8);			hdr = GF_4CC(bytes[0], bytes[1], bytes[2], bytes[3]);			size = gf_mp3_frame_size(hdr);			if (alloc_size<size-4) {				frame = (char*)realloc(frame, sizeof(char)*(size-4));				alloc_size = size-4;			}			/*watchout for truncated framesif */			if (tot_size + size >= read->size) size = read->size - tot_size;			swf_read_data(read, frame, size-4);			fwrite(bytes, sizeof(char)*4, 1, snd->output);			fwrite(frame, sizeof(char)*(size-4), 1, snd->output);			if (tot_size + size >= read->size) break;			tot_size += size;		}		free(frame);		return gf_list_add(read->sounds, snd);	}	case 3:		swf_report(read, GF_NOT_SUPPORTED, "Unrecognized sound format");		free(snd);		break;	}	return GF_OK;}typedef struct{	u32 sync_flags;	u32 in_point, out_point;	u32 nb_loops;} SoundInfo; SoundInfo swf_skip_soundinfo(SWFReader *read){	SoundInfo si;	u32 sync_flags = swf_read_int(read, 4);	Bool has_env = swf_read_int(read, 1);	Bool has_loops = swf_read_int(read, 1);	Bool has_out_pt = swf_read_int(read, 1);	Bool has_in_pt = swf_read_int(read, 1);	memset(&si, 0, sizeof(SoundInfo));	si.sync_flags = sync_flags;	if (has_in_pt) si.in_point = swf_get_32(read);	if (has_out_pt) si.out_point = swf_get_32(read);	if (has_loops) si.nb_loops = swf_get_16(read);	/*we ignore the envelope*/	if (has_env) {		u32 i;		u32 nb_ctrl = swf_read_int(read, 8);		for (i=0; i<nb_ctrl; i++) {			swf_read_int(read, 32);	/*mark44*/			swf_read_int(read, 16);	/*l0*/			swf_read_int(read, 16);	/*l1*/		}	}	return si;}SWFSound *sndswf_get_sound(SWFReader *read, u32 ID){	u32 i;	SWFSound *snd;	i=0;	while ((snd = (SWFSound *)gf_list_enum(read->sounds, &i))) {		if (snd->ID==ID) return snd;	}	return NULL;}GF_Err swf_setup_sound(SWFReader *read, SWFSound *snd){	GF_Err e;	GF_ObjectDescriptor *od;	GF_ESD *esd;	GF_MuxInfo *mux;	GF_Node *n, *par;	GF_FieldInfo info;	u32 ID;	char szDEF[100];	e = swf_init_od(read);	if (e) return e;	/*create audio object*/	od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);	if (!od) return GF_OUT_OF_MEM;	od->objectDescriptorID = swf_get_od_id(read);	esd = (GF_ESD *) gf_odf_desc_new(GF_ODF_ESD_TAG);	if (!esd) return GF_OUT_OF_MEM;	esd->ESID = swf_get_es_id(read);	if (snd->ID) {		/*sound runs on its own timeline*/		esd->OCRESID = esd->ESID;	} else {		/*soundstream runs on movie/sprite timeline*/		esd->OCRESID = read->bifs_es->ESID;	}	gf_list_add(od->ESDescriptors, esd);	/*setup mux info*/	mux = (GF_MuxInfo*)gf_odf_desc_new(GF_ODF_MUXINFO_TAG);	mux->file_name = strdup(snd->szFileName);	mux->startTime = snd->frame_delay_ms;	/*MP3 in, destroy file once done*/	if (snd->format==2) mux->delete_file = 1;	gf_list_add(esd->extensionDescriptors, mux);	/*by default insert OD at begining*/	e = swf_insert_od(read, 0, od);	if (e) {		gf_odf_desc_del((GF_Descriptor *) od);		return e;	}	/*create sound & audio clip*/	n = SWF_NewNode(read, TAG_MPEG4_Sound2D);	gf_node_insert_child(read->root, n, 0);	gf_node_register(n, read->root);	par = n;	n = SWF_NewNode(read, TAG_MPEG4_AudioClip);	/*soundStream doesn't have ID and doesn't need to be accessed*/	if (snd->ID) {		sprintf(szDEF, "Sound%d", snd->ID);		read->load->ctx->max_node_id++;		ID = read->load->ctx->max_node_id;		gf_node_set_id(n, ID, szDEF);	}	((M_Sound2D *)par)->source = n;	gf_node_register(n, par);	/*assign URL*/	gf_node_get_field_by_name(n, "url", &info);	gf_sg_vrml_mf_alloc(info.far_ptr, info.fieldType, 1);	((MFURL *)info.far_ptr)->vals[0].OD_ID = od->objectDescriptorID;	snd->is_setup = 1;	return GF_OK;}GF_Err swf_start_sound(SWFReader *read){	char szDEF[100];	GF_Command *com;	GF_FieldInfo info;	GF_Node *sound2D;	GF_CommandField *f;	SWFSound *snd;	u32 ID = swf_get_16(read);	SoundInfo si = swf_skip_soundinfo(read);	snd = sndswf_get_sound(read, ID);	if (!snd) {		swf_report(read, GF_BAD_PARAM, "Cannot find sound with ID %d", ID);		return GF_OK;	}	if (!snd->is_setup) {		GF_Err e = swf_setup_sound(read, snd);		if (e) return e;	}	sprintf(szDEF, "Sound%d", snd->ID);	sound2D = gf_sg_find_node_by_name(read->load->scene_graph, szDEF);	/*check flags*/	if (si.sync_flags & 0x2) {		/*need a STOP*/		com = gf_sg_command_new(read->load->scene_graph, GF_SG_FIELD_REPLACE);		com->node = sound2D;		gf_node_register(com->node, NULL);		gf_node_get_field_by_name(sound2D, "stopTime", &info);		f = gf_sg_command_field_new(com);		f->field_ptr = gf_sg_vrml_field_pointer_new(GF_SG_VRML_SFTIME);		f->fieldType = GF_SG_VRML_SFTIME;		f->fieldIndex = info.fieldIndex;		/*replace by "now"*/		*(SFTime *)f->field_ptr = ((Double)(s64) read->bifs_au->timing) / read->bifs_es->timeScale;		*(SFTime *)f->field_ptr = 0;		gf_list_add(read->bifs_au->commands, com);	}	com = gf_sg_command_new(read->load->scene_graph, GF_SG_FIELD_REPLACE);	com->node = sound2D;	gf_node_register(com->node, NULL);	gf_node_get_field_by_name(sound2D, "startTime", &info);	f = gf_sg_command_field_new(com);	f->field_ptr = gf_sg_vrml_field_pointer_new(GF_SG_VRML_SFTIME);	f->fieldType = GF_SG_VRML_SFTIME;	f->fieldIndex = info.fieldIndex;	/*replace by "now"*/	*(SFTime *)f->field_ptr = ((Double)(s64) read->bifs_au->timing) / read->bifs_es->timeScale;	*(SFTime *)f->field_ptr = 0;	gf_list_add(read->bifs_au->commands, com);	return GF_OK;}GF_Err swf_soundstream_hdr(SWFReader *read){	u8 rec_mix;	u32 samplesperframe;	SWFSound *snd;	if (read->sound_stream) {		swf_report(read, GF_BAD_PARAM, "More than one sound stream for current timeline!!");		return swf_func_skip(read);	}		GF_SAFEALLOC(snd, SWFSound);	rec_mix = swf_read_int(read, 8);	/*0: uncompressed, 1: ADPCM, 2: MP3*/	snd->format = swf_read_int(read, 4);	/*0: 5.5k, 1: 11k, 2: 2: 22k, 3: 44k*/	snd->sound_rate = swf_read_int(read, 2);	/*0: 8 bit, 1: 16 bit*/	snd->bits_per_sample = swf_read_int(read, 1) ? 16 : 8;	/*0: mono, 8 1: stereo*/	snd->stereo = swf_read_int(read, 1);	/*samplesperframe hint*/	samplesperframe = swf_read_int(read, 16);	switch (snd->format) {	/*raw PCM*/	case 0:		swf_report(read, GF_NOT_SUPPORTED, "Raw PCM Audio not supported");		free(snd);		break;	/*ADPCM*/	case 1:		swf_report(read, GF_NOT_SUPPORTED, "AD-PCM Audio not supported");		free(snd);		break;	/*MP3*/	case 2:		read->sound_stream = snd;		break;	case 3:		swf_report(read, GF_NOT_SUPPORTED, "Unrecognized sound format");		free(snd);		break;	}	return GF_OK;}GF_Err swf_soundstream_block(SWFReader *read){	unsigned char bytes[4];	u32 hdr, alloc_size, size, tot_size, samplesPerFrame, delay;	char *frame;	/*note we're doing only MP3*/	if (!read->sound_stream) return swf_func_skip(read);	samplesPerFrame = swf_get_16(read);	delay = swf_get_16(read);	if (!read->sound_stream->is_setup) {		if (!read->sound_stream->szFileName) {			char szName[1024];			sprintf(szName, "swf_soundstream_%d.mp3", (u32) read->sound_stream);			if (read->localPath) {				read->sound_stream->szFileName = (char*)malloc(sizeof(char)*GF_MAX_PATH);				strcpy(read->sound_stream->szFileName, read->localPath);				strcat(read->sound_stream->szFileName, szName);			} else {				read->sound_stream->szFileName = strdup(szName);			}			read->sound_stream->output = fopen(read->sound_stream->szFileName, "wb");		}		/*error at setup*/		if (!read->sound_stream->output) return swf_func_skip(read);		/*store TS of first AU*/		read->sound_stream->frame_delay_ms = read->current_frame*1000;		read->sound_stream->frame_delay_ms /= read->frame_rate;		read->sound_stream->frame_delay_ms = delay;		swf_setup_sound(read, read->sound_stream);	}	if (!samplesPerFrame) return GF_OK;	alloc_size = 1;	frame = (char*)malloc(sizeof(char));	tot_size = 4;	/*parse all frames*/	while (1) {		bytes[0] = swf_read_int(read, 8);		bytes[1] = swf_read_int(read, 8);		bytes[2] = swf_read_int(read, 8);		bytes[3] = swf_read_int(read, 8);		hdr = GF_4CC(bytes[0], bytes[1], bytes[2], bytes[3]);		size = gf_mp3_frame_size(hdr);		if (alloc_size<size-4) {			frame = (char*)realloc(frame, sizeof(char)*(size-4));			alloc_size = size-4;		}		/*watchout for truncated framesif */		if (tot_size + size >= read->size) size = read->size - tot_size;		swf_read_data(read, frame, size-4);		fwrite(bytes, sizeof(char)*4, 1, read->sound_stream->output);		fwrite(frame, sizeof(char)*(size-4), 1, read->sound_stream->output);		if (tot_size + size >= read->size) break;		tot_size += size;	}	free(frame);	return GF_OK;}GF_Err swf_process_tag(SWFReader *read){	switch (read->tag) {	case SWF_END: return GF_OK; /*void*/	case SWF_PROTECT: return GF_OK;	case SWF_SETBACKGROUNDCOLOR: return swf_set_backcol(read);	case SWF_DEFINESHAPE: return swf_def_shape(read, 0);	case SWF_DEFINESHAPE2: return swf_def_shape(read, 1);	case SWF_DEFINESHAPE3: return swf_def_shape(read, 2);	case SWF_PLACEOBJECT: return swf_place_obj(read, 0);	case SWF_PLACEOBJECT2: return swf_place_obj(read, 1);	case SWF_SHOWFRAME: return swf_show_frame(read);	case SWF_REMOVEOBJECT: return swf_remove_obj(read, 0);	case SWF_REMOVEOBJECT2: return swf_remove_obj(read, 1);	case SWF_DEFINEFONT: return swf_def_font(read, 0);	case SWF_DEFINEFONT2: return swf_def_font(read, 1);	case SWF_DEFINEFONTINFO: return swf_def_font_info(read);	case SWF_DEFINETEXT: return swf_def_text(read, 0);	case SWF_DEFINETEXT2: return swf_def_text(read, 1);	case SWF_DEFINESPRITE: return swf_def_sprite(read);	/*no revision needed*/	case SWF_SOUNDSTREAMHEAD: 	case SWF_SOUNDSTREAMHEAD2:		return swf_soundstream_hdr(read);	case SWF_DEFINESOUND: return swf_def_sound(read);	case SWF_STARTSOUND: return swf_start_sound(read);	case SWF_SOUNDSTREAMBLOCK: return swf_soundstream_block(read);	case SWF_DEFINEBUTTON: return swf_def_button(read, 0);	case SWF_DEFINEBUTTON2: return swf_def_button(read, 1);	case SWF_DEFINEBUTTONSOUND:	case SWF_DOACTION:		read->has_interact = 1;		swf_report(read, GF_OK, "skipping tag %s", swf_get_tag(read->tag) );		return swf_func_skip(read);/*	case SWF_DEFINEBITSJPEG: return swf_def_bits_jpeg(read);	case SWF_JPEGTABLES: return swf_def_hdr_jpeg(read);	case SWF_SOUNDSTREAMHEAD: return swf_sound_hdr(read);	case SWF_SOUNDSTREAMBLOCK: return swf_sound_block(read);	case SWF_DEFINEBITSLOSSLESS: return swf_def_bits_lossless(read);	case SWF_DEFINEBITSJPEG2: return swf_def_bits_jpegV2(read);	case SWF_DEFINEBITSJPEG3: return swf_def_bits_jpegV3(read);	case SWF_DEFINEBITSLOSSLESS2: return swf_def_bits_losslessV2(read);	case SWF_FRAMELABEL: return swf_def_frame_label(read);*/	default: return swf_unknown_tag(read);	}}GF_Err SWF_ParseTag(SWFReader *read){	GF_Err e;	s32 diff;	u16 hdr;	u32 pos;	hdr = swf_get_16(read);	read->tag = hdr>>6;	read->size = hdr & 0x3f;	if (read->size == 0x3f) {		swf_align(read);		read->size = swf_get_32(read);	}	pos = swf_get_file_pos(read);	diff = pos + read->size;	gf_set_progress("SWF Parsing", pos, read->length);	e = swf_process_tag(read);	swf_align(read);	diff -= swf_get_file_pos(read);	if (diff<0) {		swf_report(read, GF_IO_ERR, "tag over-read of %d bytes (size %d)", -1*diff, read->size);		return GF_IO_ERR;	} else {		swf_read_int(read, diff*8);	}	if (!e && !read->tag) return GF_EOS;	if (read->ioerr) {		swf_report(read, GF_IO_ERR, "bitstream IO err (tag size %d)", read->size);		return read->ioerr;	}	return e;}void swf_report(SWFReader *read, GF_Err e, char *format, ...){#ifndef GPAC_DISABLE_LOG	if (gf_log_get_level() && (gf_log_get_tools() & GF_LOG_PARSER)) {		char szMsg[2048];		va_list args;		va_start(args, format);		vsprintf(szMsg, format, args);		va_end(args);		GF_LOG((u32) (e ? GF_LOG_ERROR : GF_LOG_WARNING), GF_LOG_PARSER, ("[SWF Parsing] %s (frame %d)\n", szMsg, read->current_frame+1) );	}#endif}const char *swf_get_tag(u32 tag){	switch (tag) {	case SWF_END: return "End";	case SWF_SHOWFRAME: return "ShowFrame";	case SWF_DEFINESHAPE: return "DefineShape";	case SWF_FREECHARACTER: return "FreeCharacter";	case SWF_PLACEOBJECT: return "PlaceObject";	case SWF_REMOVEOBJECT: return "RemoveObject";	case SWF_DEFINEBITSJPEG: return "DefineBitsJPEG";	case SWF_DEFINEBUTTON: return "DefineButton";	case SWF_JPEGTABLES: return "JPEGTables";	case SWF_SETBACKGROUNDCOLOR: return "SetBackgroundColor";	case

⌨️ 快捷键说明

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