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

📄 isom_tools.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *			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/media_tools.h>#include <gpac/constants.h>#ifndef GPAC_READ_ONLYstatic const u32 ISMA_VIDEO_OD_ID = 20;static const u32 ISMA_AUDIO_OD_ID = 10;static const u32 ISMA_VIDEO_ES_ID = 201;static const u32 ISMA_AUDIO_ES_ID = 101;static const char ISMA_BIFS_CONFIG[] = {0x00, 0x00, 0x60 };/*ISMA audio*/static const u8 ISMA_BIFS_AUDIO[] = {	0xC0, 0x10, 0x12, 0x81, 0x30, 0x2A, 0x05, 0x7C};/*ISMA video*/static const u8 ISMA_GF_BIFS_VIDEO[] = {	0xC0, 0x10, 0x12, 0x60, 0x42, 0x82, 0x28, 0x29,	0xD0, 0x4F, 0x00};/*ISMA audio-video*/static const u8 ISMA_BIFS_AV[] = {	0xC0, 0x10, 0x12, 0x81, 0x30, 0x2A, 0x05, 0x72, 	0x60, 0x42, 0x82, 0x28, 0x29, 0xD0, 0x4F, 0x00};/*image only - uses same visual OD ID as video*/static const u8 ISMA_BIFS_IMAGE[] = {	0xC0, 0x11, 0xA4, 0xCD, 0x53, 0x6A, 0x0A, 0x44, 	0x13, 0x00};/*ISMA audio-image*/static const u8 ISMA_BIFS_AI[] = {	0xC0, 0x11, 0xA5, 0x02, 0x60, 0x54, 0x0A, 0xE4,	0xCD, 0x53, 0x6A, 0x0A, 0x44, 0x13, 0x00};GF_EXPORTGF_Err gf_media_make_isma(GF_ISOFile *mp4file, Bool keepESIDs, Bool keepImage, Bool no_ocr){	u32 AudioTrack, VideoTrack, Tracks, i, mType, bifsT, odT, descIndex, VideoType, VID, AID, bifsID, odID;	u32 bifs, w, h;	Bool is_image, image_track;	GF_ESD *a_esd, *v_esd, *_esd;	Bool update_vid_esd;	GF_ObjectDescriptor *od;	GF_ODUpdate *odU;	GF_ODCodec *codec;	GF_ISOSample *samp;	GF_BitStream *bs;	u8 audioPL, visualPL;		switch (gf_isom_get_mode(mp4file)) {	case GF_ISOM_OPEN_EDIT:	case GF_ISOM_OPEN_WRITE:	case GF_ISOM_WRITE_EDIT:		break;	default:		return GF_BAD_PARAM;	}	Tracks = gf_isom_get_track_count(mp4file);	AID = VID = 0;	is_image = 0;	//search for tracks	for (i=0; i<Tracks; i++) {		GF_ESD *esd = gf_isom_get_esd(mp4file, i+1, 1);		//remove from IOD		gf_isom_remove_track_from_root_od(mp4file, i+1);		mType = gf_isom_get_media_type(mp4file, i+1);		switch (mType) {		case GF_ISOM_MEDIA_VISUAL:			image_track = 0;			if (esd && ((esd->decoderConfig->objectTypeIndication==0x6C) || (esd->decoderConfig->objectTypeIndication==0x6D)) )				image_track = 1;			/*remove image tracks if wanted*/			if (keepImage || !image_track) {				/*only ONE video stream possible with ISMA*/				if (VID) {					if (esd) gf_odf_desc_del((GF_Descriptor*)esd);					GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMA convert] More than one video track found, cannot convert file - remove extra track(s)\n"));					return GF_NOT_SUPPORTED;				}				VID = gf_isom_get_track_id(mp4file, i+1);				is_image = image_track;			} else {				GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[ISMA convert] Visual track ID %d: only one sample found, assuming image and removing track\n", gf_isom_get_track_id(mp4file, i+1) ) );				gf_isom_remove_track(mp4file, i+1);				i -= 1;				Tracks = gf_isom_get_track_count(mp4file);			}			break;		case GF_ISOM_MEDIA_AUDIO:			if (AID) {				if (esd) gf_odf_desc_del((GF_Descriptor*)esd);				GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMA convert] More than one audio track found, cannot convert file - remove extra track(s)\n") );				return GF_NOT_SUPPORTED;			}			AID = gf_isom_get_track_id(mp4file, i+1);			break;		/*clean file*/		default:			if (mType==GF_ISOM_MEDIA_HINT) {				GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[ISMA convert] Removing Hint track ID %d\n", gf_isom_get_track_id(mp4file, i+1) ));			} else {				GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[ISMA convert] Removing track ID %d\n", gf_isom_get_track_id(mp4file, i+1) ));			}			gf_isom_remove_track(mp4file, i+1);			i -= 1;			Tracks = gf_isom_get_track_count(mp4file);			break;		}		if (esd) gf_odf_desc_del((GF_Descriptor*)esd);	}	//no audio no video	if (!AID && !VID) return GF_OK;	/*reset all PLs*/	visualPL = 0xFE;	audioPL = 0xFE;	od = (GF_ObjectDescriptor *) gf_isom_get_root_od(mp4file);	if (od && (od->tag==GF_ODF_IOD_TAG)) {		audioPL = ((GF_InitialObjectDescriptor*)od)->audio_profileAndLevel;		visualPL = ((GF_InitialObjectDescriptor*)od)->visual_profileAndLevel;	}	if (od) gf_odf_desc_del((GF_Descriptor *)od);	//create the OD AU	bifs = 0;	odU = (GF_ODUpdate *) gf_odf_com_new(GF_ODF_OD_UPDATE_TAG);		a_esd = v_esd = NULL;	update_vid_esd = 0;	gf_isom_set_root_od_id(mp4file, 1);	bifsID = 1;	odID = 2;	if (keepESIDs) {		bifsID = 1;		while ((bifsID==AID) || (bifsID==VID)) bifsID++;		odID = 2;		while ((odID==AID) || (odID==VID) || (odID==bifsID)) odID++;	}	VideoTrack = gf_isom_get_track_by_id(mp4file, VID);	AudioTrack = gf_isom_get_track_by_id(mp4file, AID);		w = h = 0;	if (VideoTrack) {		bifs = 1;		VideoType = 0;		od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);		od->objectDescriptorID = ISMA_VIDEO_OD_ID;		if (!keepESIDs && (VID != ISMA_VIDEO_ES_ID)) {			gf_isom_set_track_id(mp4file, VideoTrack, ISMA_VIDEO_ES_ID);		}		v_esd = gf_isom_get_esd(mp4file, VideoTrack, 1);		if (v_esd) {			v_esd->OCRESID = no_ocr ? 0 : bifsID;			gf_odf_desc_add_desc((GF_Descriptor *)od, (GF_Descriptor *)v_esd);			gf_list_add(odU->objectDescriptors, od);			gf_isom_get_track_layout_info(mp4file, VideoTrack, &w, &h, NULL, NULL, NULL);			if (!w || !h) {				gf_isom_get_visual_info(mp4file, VideoTrack, 1, &w, &h);				if ((v_esd->decoderConfig->objectTypeIndication==0x20) && (v_esd->decoderConfig->streamType==GF_STREAM_VISUAL)) {					GF_M4VDecSpecInfo dsi;					gf_m4v_get_config(v_esd->decoderConfig->decoderSpecificInfo->data, v_esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi);					if (!is_image && (!w || !h)) {						w = dsi.width;						h = dsi.height;						gf_isom_set_visual_info(mp4file, VideoTrack, 1, w, h);						GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[ISMA convert] Adjusting visual track size to %d x %d\n", w, h));					}					if (dsi.par_num && (dsi.par_den!=dsi.par_num)) {						w *= dsi.par_num;						w /= dsi.par_den;					}					if (dsi.VideoPL) visualPL = dsi.VideoPL;				}			}		}	}	if (AudioTrack) {		od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);		od->objectDescriptorID = ISMA_AUDIO_OD_ID;		if (!keepESIDs && (AID != ISMA_AUDIO_ES_ID)) {			gf_isom_set_track_id(mp4file, AudioTrack, ISMA_AUDIO_ES_ID);		}		a_esd = gf_isom_get_esd(mp4file, AudioTrack, 1);		if (a_esd) {			a_esd->OCRESID = no_ocr ? 0 : bifsID;			if (!keepESIDs) a_esd->ESID = ISMA_AUDIO_ES_ID;			gf_odf_desc_add_desc((GF_Descriptor *)od, (GF_Descriptor *)a_esd);			gf_list_add(odU->objectDescriptors, od);			if (!bifs) {				bifs = 3;			} else {				bifs = 2;			}			if (a_esd->decoderConfig->objectTypeIndication == 0x40) {				GF_M4ADecSpecInfo cfg;				gf_m4a_get_config(a_esd->decoderConfig->decoderSpecificInfo->data, a_esd->decoderConfig->decoderSpecificInfo->dataLength, &cfg);				audioPL = cfg.audioPL;			}		}	}	/*update video cfg if needed*/	if (v_esd) gf_isom_change_mpeg4_description(mp4file, VideoTrack, 1, v_esd);	if (a_esd) gf_isom_change_mpeg4_description(mp4file, AudioTrack, 1, a_esd);	/*likely 3GP or other files...*/	if ((!a_esd && AudioTrack) || (!v_esd && VideoTrack)) return GF_OK;	//get the OD sample	codec = gf_odf_codec_new();	samp = gf_isom_sample_new();	gf_odf_codec_add_com(codec, (GF_ODCom *)odU);	gf_odf_codec_encode(codec, 1);	gf_odf_codec_get_au(codec, &samp->data, &samp->dataLength);	gf_odf_codec_del(codec);	samp->CTS_Offset = 0;	samp->DTS = 0;	samp->IsRAP = 1;		/*create the OD track*/	odT = gf_isom_new_track(mp4file, odID, GF_ISOM_MEDIA_OD, gf_isom_get_timescale(mp4file));	if (!odT) return gf_isom_last_error(mp4file);	_esd = gf_odf_desc_esd_new(SLPredef_MP4);	_esd->decoderConfig->bufferSizeDB = samp->dataLength;	_esd->decoderConfig->objectTypeIndication = 0x01;	_esd->decoderConfig->streamType = GF_STREAM_OD;	_esd->ESID = odID;	_esd->OCRESID = no_ocr ? 0 : bifsID;	gf_isom_new_mpeg4_description(mp4file, odT, _esd, NULL, NULL, &descIndex);	gf_odf_desc_del((GF_Descriptor *)_esd);	gf_isom_add_sample(mp4file, odT, 1, samp);	gf_isom_sample_del(&samp);	gf_isom_set_track_group(mp4file, odT, 1);	/*create the BIFS track*/	bifsT = gf_isom_new_track(mp4file, bifsID, GF_ISOM_MEDIA_SCENE, gf_isom_get_timescale(mp4file));	if (!bifsT) return gf_isom_last_error(mp4file);	_esd = gf_odf_desc_esd_new(SLPredef_MP4);	_esd->decoderConfig->bufferSizeDB = sizeof(ISMA_BIFS_CONFIG);	_esd->decoderConfig->objectTypeIndication = 0x02;	_esd->decoderConfig->streamType = GF_STREAM_SCENE;	_esd->ESID = bifsID;	_esd->OCRESID = 0;	/*rewrite ISMA BIFS cfg*/	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);	/*empty bifs stuff*/	gf_bs_write_int(bs, 0, 17);	/*command stream*/	gf_bs_write_int(bs, 1, 1);	/*in pixel metrics*/	gf_bs_write_int(bs, 1, 1);	/*with size*/	gf_bs_write_int(bs, 1, 1);	gf_bs_write_int(bs, w, 16);	gf_bs_write_int(bs, h, 16);	gf_bs_align(bs);	gf_bs_get_content(bs, &_esd->decoderConfig->decoderSpecificInfo->data, &_esd->decoderConfig->decoderSpecificInfo->dataLength);	gf_isom_new_mpeg4_description(mp4file, bifsT, _esd, NULL, NULL, &descIndex);	gf_odf_desc_del((GF_Descriptor *)_esd);	gf_bs_del(bs);	gf_isom_set_visual_info(mp4file, bifsT, descIndex, w, h);		samp = gf_isom_sample_new();	samp->CTS_Offset = 0;	samp->DTS = 0;	switch (bifs) {	case 1:		if (is_image) {			samp->data = (char *) ISMA_BIFS_IMAGE;			samp->dataLength = 10;		} else {			samp->data = (char *) ISMA_GF_BIFS_VIDEO;			samp->dataLength = 11;		}		break;	case 2:		if (is_image) {			samp->data = (char *) ISMA_BIFS_AI;			samp->dataLength = 15;		} else {			samp->data = (char *) ISMA_BIFS_AV;			samp->dataLength = 16;		}		break;	case 3:		samp->data = (char *) ISMA_BIFS_AUDIO;		samp->dataLength = 8;		break;	}	samp->IsRAP = 1;	gf_isom_add_sample(mp4file, bifsT, 1, samp);

⌨️ 快捷键说明

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