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

📄 media_import.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / Media Tools sub-project * *  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/internal/media_dev.h>#include <gpac/internal/avilib.h>#include <gpac/internal/ogg.h>#include <gpac/internal/vobsub.h>#include <gpac/xml.h>#include <gpac/mpegts.h>#include <gpac/constants.h>/*since 0.2.2, we use zlib for xmt/x3d reading to handle gz files*/#include <zlib.h>#ifndef GPAC_READ_ONLY#define GF_IMPORT_DEFAULT_FPS	25.0GF_Err gf_import_message(GF_MediaImporter *import, GF_Err e, char *format, ...){#ifndef GPAC_DISABLE_LOG	if (gf_log_get_level() && (gf_log_get_tools() & GF_LOG_AUTHOR)) {		va_list args;		char szMsg[1024];		va_start(args, format);		vsprintf(szMsg, format, args);		va_end(args);		GF_LOG((u32) (e ? GF_LOG_ERROR : GF_LOG_INFO), GF_LOG_AUTHOR, ("%s\n", szMsg) );	}#endif	return e;}static GF_Err gf_media_update_par(GF_ISOFile *file, u32 track){	u32 tk_w, tk_h, stype;	GF_Err e;	e = gf_isom_get_visual_info(file, track, 1, &tk_w, &tk_h);	if (e) return e;	stype = gf_isom_get_media_subtype(file, track, 1);	if (stype==GF_ISOM_SUBTYPE_AVC_H264) {		s32 par_n, par_d;		GF_AVCConfig *avcc = gf_isom_avc_config_get(file, track, 1);		GF_AVCConfigSlot *slc = (GF_AVCConfigSlot *)gf_list_get(avcc->sequenceParameterSets, 0);		par_n = par_d = 1;		if (slc) gf_avc_get_sps_info(slc->data, slc->size, NULL, NULL, &par_n, &par_d);		gf_odf_avc_cfg_del(avcc);		if ((par_n>1) && (par_d>1)) 			tk_w = tk_w * par_n / par_d;	} 	else if ((stype==GF_ISOM_SUBTYPE_MPEG4) || (stype==GF_ISOM_SUBTYPE_MPEG4_CRYP) ) {		GF_M4VDecSpecInfo dsi;		GF_ESD *esd = gf_isom_get_esd(file, track, 1);		if (!esd || !esd->decoderConfig || (esd->decoderConfig->streamType!=4) || (esd->decoderConfig->objectTypeIndication!=0x20)) {			if (esd) gf_odf_desc_del((GF_Descriptor *) esd);			return GF_NOT_SUPPORTED;		}		gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi);		if (esd) gf_odf_desc_del((GF_Descriptor *) esd);		if ((dsi.par_num>1) && (dsi.par_num>1)) 			tk_w = dsi.width * dsi.par_num / dsi.par_den;	} else {		return GF_OK;	}	return gf_isom_set_track_layout_info(file, track, tk_w<<16, tk_h<<16, 0, 0, 0);}static void MP4T_RecomputeBitRate(GF_ISOFile *file, u32 track){	u32 i, count, timescale;	u64 time_wnd, rate, max_rate, avg_rate;	Double br;	GF_ESD *esd;	esd = gf_isom_get_esd(file, track, 1);	if (!esd) return;	esd->decoderConfig->avgBitrate = 0;	esd->decoderConfig->maxBitrate = 0;	rate = max_rate = avg_rate = time_wnd = 0;	timescale = gf_isom_get_media_timescale(file, track);	count = gf_isom_get_sample_count(file, track);	for (i=0; i<count; i++) {		GF_ISOSample *samp = gf_isom_get_sample_info(file, track, i+1, NULL, NULL);				if (samp->dataLength>esd->decoderConfig->bufferSizeDB) esd->decoderConfig->bufferSizeDB = samp->dataLength;		if (esd->decoderConfig->bufferSizeDB < samp->dataLength) esd->decoderConfig->bufferSizeDB = samp->dataLength;		avg_rate += samp->dataLength;		rate += samp->dataLength;		if (samp->DTS > time_wnd + timescale) {			if (rate > max_rate) max_rate = rate;			time_wnd = samp->DTS;			rate = 0;		}		gf_isom_sample_del(&samp);	}		br = (Double) (s64) gf_isom_get_media_duration(file, track);	br /= timescale;	esd->decoderConfig->avgBitrate = (u32) ((Double) (s64)avg_rate / br);	/*move to bps*/	esd->decoderConfig->avgBitrate *= 8;	esd->decoderConfig->maxBitrate = (u32) (max_rate*8);	gf_isom_change_mpeg4_description(file, track, 1, esd);	gf_odf_desc_del((GF_Descriptor *)esd);}static void get_video_timing(Double fps, u32 *timescale, u32 *dts_inc){	u32 fps_1000 = (u32) (fps*1000 + 0.5);	/*handle all drop-frame formats*/	if (fps_1000==29970) {		*timescale = 30000;		*dts_inc = 1001;	}	else if (fps_1000==23976) {		*timescale = 24000;		*dts_inc = 1001;	}	else if (fps_1000==59940) {		*timescale = 60000;		*dts_inc = 1001;	} else {		*timescale = fps_1000;		*dts_inc = 1000;	}}static GF_Err gf_import_still_image(GF_MediaImporter *import){	GF_BitStream *bs;	GF_Err e;	Bool destroy_esd;	u32 size, track, di, w, h, dsi_len, mtype;	GF_ISOSample *samp;	u8 OTI;	char *dsi, *data;	FILE *src;	src = fopen(import->in_name, "rb");	if (!src) return gf_import_message(import, GF_URL_ERROR, "Opening file %s failed", import->in_name);	fseek(src, 0, SEEK_END);	size = ftell(src);	fseek(src, 0, SEEK_SET);	data = (char*)malloc(sizeof(char)*size);	fread(data, sizeof(char)*size, 1, src);	fclose(src);	/*get image size*/	bs = gf_bs_new(data, size, GF_BITSTREAM_READ);	gf_img_parse(bs, &OTI, &mtype, &w, &h, &dsi, &dsi_len);	gf_bs_del(bs);	if (!OTI) {		free(data);		return gf_import_message(import, GF_NOT_SUPPORTED, "Unrecognized file %s", import->in_name);	}	if (!w || !h) {		free(data);		if (dsi) free(dsi);		return gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Invalid %s file", (OTI==0x6C) ? "JPEG" : (OTI==0x6D) ? "PNG" : "JPEG2000");	}	if (import->flags & GF_IMPORT_PROBE_ONLY) {		import->tk_info[0].track_num = 1;		import->tk_info[0].type = GF_ISOM_MEDIA_VISUAL;		import->tk_info[0].media_type = mtype;		import->tk_info[0].flags = GF_IMPORT_USE_DATAREF | GF_IMPORT_NO_DURATION;		import->tk_info[0].video_info.width = w;		import->tk_info[0].video_info.height = h;		import->nb_tracks = 1;		if (dsi) free(dsi);		return GF_OK;	}	e = GF_OK;	destroy_esd = 0;	if (!import->esd) {		import->esd = gf_odf_desc_esd_new(2);		destroy_esd = 1;	}	/*update stream type/oti*/	if (!import->esd->decoderConfig) import->esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG);	if (!import->esd->slConfig) import->esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);	import->esd->decoderConfig->streamType = GF_STREAM_VISUAL;	import->esd->decoderConfig->objectTypeIndication = OTI;	import->esd->decoderConfig->bufferSizeDB = size;	import->esd->decoderConfig->avgBitrate = 8*size;	import->esd->decoderConfig->maxBitrate = 8*size;	import->esd->slConfig->timestampResolution = 1000;	if (dsi) {		if (!import->esd->decoderConfig->decoderSpecificInfo) import->esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG);		if (import->esd->decoderConfig->decoderSpecificInfo->data) free(import->esd->decoderConfig->decoderSpecificInfo->data);		import->esd->decoderConfig->decoderSpecificInfo->data = dsi;		import->esd->decoderConfig->decoderSpecificInfo->dataLength = dsi_len;	}		track = gf_isom_new_track(import->dest, import->esd->ESID, GF_ISOM_MEDIA_VISUAL, 1000);	if (!track) {		e = gf_isom_last_error(import->dest);		goto exit;	}	gf_isom_set_track_enabled(import->dest, track, 1);	if (!import->esd->ESID) import->esd->ESID = gf_isom_get_track_id(import->dest, track);	import->final_trackID = import->esd->ESID;	e = gf_isom_new_mpeg4_description(import->dest, track, import->esd, (import->flags & GF_IMPORT_USE_DATAREF) ? import->in_name : NULL, NULL, &di);	if (e) goto exit;	gf_isom_set_visual_info(import->dest, track, di, w, h);	samp = gf_isom_sample_new();	samp->IsRAP = 1;	samp->dataLength = size;	gf_import_message(import, GF_OK, "%s import - size %d x %d", (OTI==0x6C) ? "JPEG" : (OTI==0x6C) ? "PNG" : "JPEG2000", w, h);	gf_set_progress("Importing Image", 0, 1);	if (import->flags & GF_IMPORT_USE_DATAREF) {		e = gf_isom_add_sample_reference(import->dest, track, di, samp, (u64) 0);	} else {		samp->data = data;		e = gf_isom_add_sample(import->dest, track, di, samp);		samp->data = NULL;	}	gf_set_progress("Importing Image", 1, 1);	gf_isom_sample_del(&samp);exit:	free(data);	if (import->esd && destroy_esd) {		gf_odf_desc_del((GF_Descriptor *) import->esd);		import->esd = NULL;	}	return e;}GF_Err gf_import_mp3(GF_MediaImporter *import){	u8 oti;	Bool destroy_esd;	GF_Err e;	u16 sr;	u32 nb_chan;	FILE *in;	u32 hdr, size, max_size, track, di, tot_size, done, offset, duration;	GF_ISOSample *samp;	in = gf_f64_open(import->in_name, "rb");	if (!in) return gf_import_message(import, GF_URL_ERROR, "Opening file %s failed", import->in_name);	hdr = gf_mp3_get_next_header(in);	if (!hdr) {		fclose(in);		return gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Audio isn't MPEG-1/2 audio");	}	sr = gf_mp3_sampling_rate(hdr);	oti = gf_mp3_object_type_indication(hdr);	if (!oti) {		fclose(in);		return gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Audio isn't MPEG-1/2 audio");	}	if (import->flags & GF_IMPORT_PROBE_ONLY) {		fclose(in);		import->tk_info[0].track_num = 1;		import->tk_info[0].type = GF_ISOM_MEDIA_AUDIO;		import->tk_info[0].flags = GF_IMPORT_USE_DATAREF;		import->tk_info[0].audio_info.sample_rate = sr;		import->tk_info[0].audio_info.nb_channels = gf_mp3_num_channels(hdr);		import->nb_tracks = 1;		return GF_OK;	}	e = GF_OK;	destroy_esd = 0;	if (!import->esd) {		import->esd = gf_odf_desc_esd_new(2);		destroy_esd = 1;	}	if (!import->esd->decoderConfig) import->esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG);	if (!import->esd->slConfig) import->esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);	/*update stream type/oti*/	import->esd->decoderConfig->streamType = GF_STREAM_AUDIO;	import->esd->decoderConfig->objectTypeIndication = oti;	import->esd->decoderConfig->bufferSizeDB = 20;	import->esd->slConfig->timestampResolution = sr;	samp = NULL;	nb_chan = gf_mp3_num_channels(hdr);	gf_import_message(import, GF_OK, "MP3 import - sample rate %d - %s audio - %d channel%s", sr, (oti==0x6B) ? "MPEG-1" : "MPEG-2", nb_chan, (nb_chan>1) ? "s" : "");	track = gf_isom_new_track(import->dest, import->esd->ESID, GF_ISOM_MEDIA_AUDIO, sr);	if (!track) {		e = gf_isom_last_error(import->dest);		goto exit;	}	gf_isom_set_track_enabled(import->dest, track, 1);	if (!import->esd->ESID) import->esd->ESID = gf_isom_get_track_id(import->dest, track);	import->final_trackID = import->esd->ESID;	if (import->esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) import->esd->decoderConfig->decoderSpecificInfo);	import->esd->decoderConfig->decoderSpecificInfo = NULL;	gf_isom_new_mpeg4_description(import->dest, track, import->esd, (import->flags & GF_IMPORT_USE_DATAREF) ? import->in_name : NULL, NULL, &di);	gf_isom_set_audio_info(import->dest, track, di, sr, nb_chan, 16);	fseek(in, 0, SEEK_END);	tot_size = ftell(in);	fseek(in, 0, SEEK_SET);	e = GF_OK;	samp = gf_isom_sample_new();	samp->IsRAP = 1;	duration = import->duration*sr;	duration /= 1000;	max_size = 0;	done = 0;	while (tot_size > done) {		/* get the next MP3 frame header */		hdr = gf_mp3_get_next_header(in);		/*MP3 stream truncated*/		if (!hdr) break;		offset = ftell(in) - 4;		size = gf_mp3_frame_size(hdr);		assert(size);		if (size>max_size) {			samp->data = (char*)realloc(samp->data, sizeof(char) * size);			max_size = size;		}		samp->data[0] = (hdr >> 24) & 0xFF;		samp->data[1] = (hdr >> 16) & 0xFF;		samp->data[2] = (hdr >> 8) & 0xFF;		samp->data[3] = hdr & 0xFF;		samp->dataLength = size;		/* read the frame data into the buffer */		if (fread(&samp->data[4], 1, size - 4, in) != size - 4) break;		if (import->flags & GF_IMPORT_USE_DATAREF) {			gf_isom_add_sample_reference(import->dest, track, di, samp, offset);		} else {			gf_isom_add_sample(import->dest, track, di, samp);		}

⌨️ 快捷键说明

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