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

📄 media_export.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
	/*write header*/	/*'NHnt' format*/	gf_bs_write_data(bs, "NHnt", 4);	/*version 1*/	gf_bs_write_u8(bs, 0);	/*streamType*/	gf_bs_write_u8(bs, esd->decoderConfig->streamType);	/*OTI*/	gf_bs_write_u8(bs, esd->decoderConfig->objectTypeIndication);	/*reserved*/	gf_bs_write_u16(bs, 0);	/*bufferDB*/	gf_bs_write_u24(bs, esd->decoderConfig->bufferSizeDB);	/*avg BitRate*/	gf_bs_write_u32(bs, esd->decoderConfig->avgBitrate);	/*max bitrate*/	gf_bs_write_u32(bs, esd->decoderConfig->maxBitrate);	/*timescale*/	gf_bs_write_u32(bs, esd->slConfig->timestampResolution);	gf_odf_desc_del((GF_Descriptor *) esd);	has_b_frames = gf_isom_has_time_offset(dumper->file, track);	pos = 0;	count = gf_isom_get_sample_count(dumper->file, track);	for (i=0; i<count; i++) {		GF_ISOSample *samp = gf_isom_get_sample(dumper->file, track, i+1, &di);		if (!samp) break;		fwrite(samp->data, samp->dataLength, 1, out_med);				/*dump nhnt info*/		gf_bs_write_u24(bs, samp->dataLength);		gf_bs_write_int(bs, samp->IsRAP, 1);		/*AU start & end flag always true*/		gf_bs_write_int(bs, 1, 1);		gf_bs_write_int(bs, 1, 1);		/*reserved*/		gf_bs_write_int(bs, 0, 3);		/*type - try to guess it*/		if (has_b_frames) {			if (samp->IsRAP) gf_bs_write_int(bs, 0, 2);			/*if CTS offset, assime P*/			else if (samp->CTS_Offset) gf_bs_write_int(bs, 1, 2);			else gf_bs_write_int(bs, 2, 2);		} else {			gf_bs_write_int(bs, samp->IsRAP ? 0 : 1, 2);		}		gf_bs_write_u32(bs, pos);		/*TODO support for large files*/		gf_bs_write_u32(bs, (u32) (samp->DTS + samp->CTS_Offset) );		gf_bs_write_u32(bs, (u32) samp->DTS);		pos += samp->dataLength;		gf_isom_sample_del(&samp);		gf_set_progress("NHNT Export", i+1, count);		if (dumper->flags & GF_EXPORT_DO_ABORT) break;	}	fclose(out_med);	gf_bs_del(bs);	fclose(out_nhnt);	return GF_OK;}static GF_Err MP4T_CopyTrack(GF_MediaExporter *dumper, GF_ISOFile *infile, u32 inTrackNum, GF_ISOFile *outfile, Bool ResetDependancies, Bool AddToIOD){	GF_ESD *esd;	GF_InitialObjectDescriptor *iod;	u32 TrackID, newTk, descIndex, i, ts, rate, pos, di, count, msubtype;	u64 dur;	GF_ISOSample *samp;	if (!inTrackNum) {		if (gf_isom_get_track_count(infile) != 1) return gf_export_message(dumper, GF_BAD_PARAM, "Please specify trackID to export");		inTrackNum = 1;	}	//check the ID is available	TrackID = gf_isom_get_track_id(infile, inTrackNum);	newTk = gf_isom_get_track_by_id(outfile, TrackID);	if (newTk) TrackID = 0;	//get the ESD and remove dependancies	esd = NULL;	msubtype = gf_isom_get_media_subtype(infile, inTrackNum, 1);	if (msubtype == GF_ISOM_SUBTYPE_MPEG4) {		esd = gf_isom_get_esd(infile, inTrackNum, 1);		if (esd && ResetDependancies) {			esd->dependsOnESID = 0;			esd->OCRESID = 0;		}	}	newTk = gf_isom_new_track(outfile, TrackID, gf_isom_get_media_type(infile, inTrackNum), gf_isom_get_media_timescale(infile, inTrackNum));	gf_isom_set_track_enabled(outfile, newTk, 1);	if (esd) {		gf_isom_new_mpeg4_description(outfile, newTk, esd, NULL, NULL, &descIndex);		if ((esd->decoderConfig->streamType == GF_STREAM_VISUAL) || (esd->decoderConfig->streamType == GF_STREAM_SCENE)) {			u32 w, h;			gf_isom_get_visual_info(infile, inTrackNum, 1, &w, &h);			/*this is because so many files have reserved values of 320x240 from v1 ... */			if ((esd->decoderConfig->objectTypeIndication == 0x20) ) {				GF_M4VDecSpecInfo dsi;				gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi);				w = dsi.width;				h = dsi.height;			}			gf_isom_set_visual_info(outfile, newTk, 1, w, h);		}		else if ((esd->decoderConfig->streamType == GF_STREAM_ND_SUBPIC) && (esd->decoderConfig->objectTypeIndication == 0xe0)) {			u32 w, h;			s32 trans_x, trans_y;			s16 layer;			gf_isom_get_track_layout_info(infile, inTrackNum, &w, &h, &trans_x, &trans_y, &layer);			gf_isom_set_track_layout_info(outfile, newTk, w << 16, h << 16, trans_x, trans_y, layer);		}		esd->decoderConfig->avgBitrate = 0;		esd->decoderConfig->maxBitrate = 0;	} else {		gf_isom_clone_sample_description(outfile, newTk, infile, inTrackNum, 1, NULL, NULL, &descIndex);	}	pos = 0;	rate = 0;	ts = gf_isom_get_media_timescale(infile, inTrackNum);	count = gf_isom_get_sample_count(infile, inTrackNum); 	for (i=0; i<count; i++) {		samp = gf_isom_get_sample(infile, inTrackNum, i+1, &di);		gf_isom_add_sample(outfile, newTk, descIndex, samp);		if (esd) {			rate += samp->dataLength;			esd->decoderConfig->avgBitrate += samp->dataLength;			if (esd->decoderConfig->bufferSizeDB<samp->dataLength) esd->decoderConfig->bufferSizeDB = samp->dataLength;			if (samp->DTS - pos > ts) {				if (esd->decoderConfig->maxBitrate<rate) esd->decoderConfig->maxBitrate = rate;				rate = 0;				pos = 0;			}		}		gf_isom_sample_del(&samp);		gf_set_progress("ISO File Export", i, count);	}	gf_set_progress("ISO File Export", count, count);	if (msubtype == GF_ISOM_SUBTYPE_MPEG4_CRYP) {		esd = gf_isom_get_esd(infile, inTrackNum, 1);	} else if (msubtype == GF_ISOM_SUBTYPE_AVC_H264) {		return gf_isom_set_pl_indication(outfile, GF_ISOM_PL_VISUAL, 0x0F);	} 	/*likely 3gp or any non-MPEG-4 isomedia file*/	else if (!esd) return gf_isom_remove_root_od(outfile);	dur = gf_isom_get_media_duration(outfile, newTk);	if (!dur) dur = ts;	esd->decoderConfig->maxBitrate *= 8;	esd->decoderConfig->avgBitrate = (u32) (esd->decoderConfig->avgBitrate * 8 * ts / dur);	gf_isom_change_mpeg4_description(outfile, newTk, 1, esd);	iod = (GF_InitialObjectDescriptor *) gf_isom_get_root_od(infile);	switch (esd->decoderConfig->streamType) {	case GF_STREAM_SCENE:		if (iod && (iod->tag==GF_ODF_IOD_TAG)) {			gf_isom_set_pl_indication(outfile, GF_ISOM_PL_SCENE, iod->scene_profileAndLevel);			gf_isom_set_pl_indication(outfile, GF_ISOM_PL_GRAPHICS, iod->graphics_profileAndLevel);		} else if (esd->decoderConfig->objectTypeIndication==0x20) {			gf_export_message(dumper, GF_OK, "Warning: Scene PLs not found in original MP4 - defaulting to No Profile Specified");			gf_isom_set_pl_indication(outfile, GF_ISOM_PL_SCENE, 0xFE);			gf_isom_set_pl_indication(outfile, GF_ISOM_PL_GRAPHICS, 0xFE);		}		break;	case GF_STREAM_VISUAL:		if (iod && (iod->tag==GF_ODF_IOD_TAG)) {			gf_isom_set_pl_indication(outfile, GF_ISOM_PL_VISUAL, iod->visual_profileAndLevel);		} else if (esd->decoderConfig->objectTypeIndication==0x20) {			GF_M4VDecSpecInfo dsi;			gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi);			gf_isom_set_pl_indication(outfile, GF_ISOM_PL_VISUAL, dsi.VideoPL);		} else {			gf_export_message(dumper, GF_OK, "Warning: Visual PLs not found in original MP4 - defaulting to No Profile Specified");			gf_isom_set_pl_indication(outfile, GF_ISOM_PL_VISUAL, 0xFE);		}		break;	case GF_STREAM_AUDIO:		if (iod && (iod->tag==GF_ODF_IOD_TAG)) {			gf_isom_set_pl_indication(outfile, GF_ISOM_PL_AUDIO, iod->audio_profileAndLevel);		} else if (esd->decoderConfig->objectTypeIndication==0x40) {			GF_M4ADecSpecInfo cfg;			gf_m4a_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &cfg);			gf_isom_set_pl_indication(outfile, GF_ISOM_PL_AUDIO, cfg.audioPL);		} else {			gf_export_message(dumper, GF_OK, "Warning: Audio PLs not found in original MP4 - defaulting to No Profile Specified");			gf_isom_set_pl_indication(outfile, GF_ISOM_PL_AUDIO, 0xFE);		}	default:		break;	}	if (iod) gf_odf_desc_del((GF_Descriptor *) iod);		gf_odf_desc_del((GF_Descriptor *)esd);	if (AddToIOD) gf_isom_add_track_to_root_od(outfile, newTk);	return GF_OK;}GF_Err gf_media_export_isom(GF_MediaExporter *dumper){	GF_ISOFile *outfile;	GF_Err e;	Bool add_to_iod;	char szName[1000], *ext;	u32 track;	u8 mode;	track = gf_isom_get_track_by_id(dumper->file, dumper->trackID);	if (gf_isom_get_media_type(dumper->file, dumper->trackID)==GF_ISOM_MEDIA_OD) {		return gf_export_message(dumper, GF_BAD_PARAM, "Cannot extract OD track, result is  meaningless");	}	if (dumper->flags & GF_EXPORT_PROBE_ONLY) {		dumper->flags |= GF_EXPORT_MERGE;		return GF_OK;	}	ext = (char *) gf_isom_get_filename(dumper->file);	if (ext) ext = strrchr(ext, '.');	sprintf(szName, "%s%s", dumper->out_name, ext ? ext : ".mp4");	add_to_iod = 1;	mode = GF_ISOM_WRITE_EDIT;	if (dumper->flags & GF_EXPORT_MERGE) {		FILE *t = fopen(szName, "rb");		if (t) {			add_to_iod = 0;			mode = GF_ISOM_OPEN_EDIT;			fclose(t);		}	}	outfile = gf_isom_open(szName, mode, NULL);	if (mode == GF_ISOM_WRITE_EDIT) {		gf_isom_set_pl_indication(outfile, GF_ISOM_PL_AUDIO, 0xFF);		gf_isom_set_pl_indication(outfile, GF_ISOM_PL_VISUAL, 0xFF);		gf_isom_set_pl_indication(outfile, GF_ISOM_PL_GRAPHICS, 0xFF);		gf_isom_set_pl_indication(outfile, GF_ISOM_PL_SCENE, 0xFF);		gf_isom_set_pl_indication(outfile, GF_ISOM_PL_OD, 0xFF);		gf_isom_set_pl_indication(outfile, GF_ISOM_PL_MPEGJ, 0xFF);	}	e = MP4T_CopyTrack(dumper, dumper->file, track, outfile, 1, add_to_iod);	if (!add_to_iod) {		u32 i;		for (i=0; i<gf_isom_get_track_count(outfile); i++) {			gf_isom_remove_track_from_root_od(outfile, i+1);		}	}	if (e) gf_isom_delete(outfile);	else gf_isom_close(outfile);	return e;}GF_Err gf_media_export_avi(GF_MediaExporter *dumper){	GF_ESD *esd;	GF_ISOSample *samp;	char szName[1000], *v4CC;	avi_t *avi_out;	char dumdata[1];	u32 track, i, di, count, w, h, frame_d;	GF_M4VDecSpecInfo dsi;	Double FPS;	track = gf_isom_get_track_by_id(dumper->file, dumper->trackID);	esd = gf_isom_get_esd(dumper->file, track, 1);	if (!esd) return gf_export_message(dumper, GF_NON_COMPLIANT_BITSTREAM, "Invalid MPEG-4 stream in track ID %d", dumper->trackID);	if ((esd->decoderConfig->streamType!=GF_STREAM_VISUAL) || 	( (esd->decoderConfig->objectTypeIndication!=0x20) && (esd->decoderConfig->objectTypeIndication!=0x21)) ) {		gf_odf_desc_del((GF_Descriptor*)esd);		return gf_export_message(dumper, GF_NON_COMPLIANT_BITSTREAM, "Track ID %d is not MPEG-4 Visual - cannot extract to AVI", dumper->trackID);	}	if (!esd->decoderConfig->decoderSpecificInfo) {		gf_odf_desc_del((GF_Descriptor*)esd);		return gf_export_message(dumper, GF_NON_COMPLIANT_BITSTREAM, "Missing decoder config for track ID %d", dumper->trackID);	}	if (dumper->flags & GF_EXPORT_PROBE_ONLY) return GF_OK;	sprintf(szName, "%s.avi", dumper->out_name);	avi_out = AVI_open_output_file(szName);	if (!avi_out) {		gf_odf_desc_del((GF_Descriptor *)esd);		return gf_export_message(dumper, GF_IO_ERR, "Error opening %s for writing - check disk access & permissions", szName);	}	/*compute FPS - note we assume constant frame rate without droped frames...*/	count = gf_isom_get_sample_count(dumper->file, track);	FPS = gf_isom_get_media_timescale(dumper->file, track);	FPS *= (count-1);	samp = gf_isom_get_sample(dumper->file, track, count, &di);	FPS /= (s64) samp->DTS;	gf_isom_sample_del(&samp);	frame_d = 0;	/*AVC - FIXME dump format is probably wrong...*/	if (esd->decoderConfig->objectTypeIndication==0x21) {		gf_isom_get_visual_info(dumper->file, track, 1, &w, &h);		v4CC = "h264";	} 	/*MPEG4*/	else {		/*ignore visual size info, get it from dsi*/		gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi);		w = dsi.width;		h = dsi.height;		v4CC = "XVID";		/*compute VfW delay*/		if (gf_isom_has_time_offset(dumper->file, track)) {			u32 max_CTSO;			u64 DTS;			DTS = max_CTSO = 0;			for (i=0; i<count; i++) {				samp = gf_isom_get_sample_info(dumper->file, track, i+1, NULL, NULL);				if (!samp) break;				if (samp->CTS_Offset>max_CTSO) max_CTSO = samp->CTS_Offset;				DTS = samp->DTS;				gf_isom_sample_del(&samp);			}			DTS /= (count-1);			frame_d = max_CTSO / (u32) DTS;			frame_d -= 1;			/*dummy delay frame for xvid unpacked bitstreams*/			dumdata[0] = 127;		}	}	gf_export_message(dumper, GF_OK, "Creating AVI file %d x %d @ %.2f FPS - 4CC \"%s\"", w, h, FPS,v4CC);	if (frame_d) gf_export_message(dumper, GF_OK, "B-Frames detected - using unpacked bitstream with max B-VOP delta %d", frame_d);	AVI_set_video(avi_out, w, h, FPS, v4CC);	for (i=0; i<count; i++) {		samp = gf_isom_get_sample(dumper->file, track, i+1, &di);		if (!samp) break;		/*add DSI before each I-frame in MPEG-4 SP*/		if (samp->IsRAP && (esd->decoderConfig->objectTypeIndication==0x20)) {			char *data = (char*) malloc(sizeof(char) * (samp->dataLength + esd->decoderConfig->decoderSpecificInfo->dataLength));			memcpy(data, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength);			memcpy(data + esd->decoderConfig->decoderSpecificInfo->dataLength, samp->data, samp->dataLength);			AVI_write_frame(avi_out, data, samp->dataLength + esd->decoderConfig->decoderSpecificInfo->dataLength, 1);			free(data);		} else {			AVI_write_frame(avi_out, samp->data, samp->dataLength, samp->IsRAP);		}		gf_isom_sample_del(&samp);		while (frame_d) {			AVI_write_frame(avi_out, dumdata, 1, 0);			frame_d--;		}		gf_set_progress("AVI Export", i+1, count);		if (dumper->flags & GF_EXPORT_DO_ABORT) break;	}	gf_odf_desc_del((GF_Descriptor *) esd);	AVI_close(avi_out);	return GF_OK;}GF_Err gf_media_export_nhml(GF_MediaExporter *dumper){	GF_ESD *esd;	char szName[1000], szMedia[1000];

⌨️ 快捷键说明

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