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

📄 media_export.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
	FILE *med, *inf, *nhml;	Bool full_dump;	u32 track, i, di, count, pos;	track = gf_isom_get_track_by_id(dumper->file, dumper->trackID);	if (!track) return gf_export_message(dumper, GF_BAD_PARAM, "Invalid track ID %d", dumper->trackID);	if (dumper->flags & GF_EXPORT_PROBE_ONLY) {		dumper->flags |= GF_EXPORT_NHML_FULL;		return GF_OK;	}	esd = gf_isom_get_esd(dumper->file, track, 1);	full_dump = (dumper->flags & GF_EXPORT_NHML_FULL) ? 1 : 0;	sprintf(szMedia, "%s.media", dumper->out_name);	med = gf_f64_open(szMedia, "wb");	if (!med) {		if (esd) gf_odf_desc_del((GF_Descriptor *) esd);		return gf_export_message(dumper, GF_IO_ERR, "Error opening %s for writing - check disk access & permissions", szMedia);	}	sprintf(szName, "%s.nhml", dumper->out_name);	nhml = fopen(szName, "wt");	if (!nhml) {		fclose(med);		if (esd) 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);	}	/*write header*/	fprintf(nhml, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");	fprintf(nhml, "<NHNTStream version=\"1.0\" timeScale=\"%d\" ", gf_isom_get_media_timescale(dumper->file, track) );	if (esd) {		fprintf(nhml, "streamType=\"%d\" objectTypeIndication=\"%d\" ", esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication);		if (esd->decoderConfig->decoderSpecificInfo  && esd->decoderConfig->decoderSpecificInfo->data) {			sprintf(szName, "%s.info", dumper->out_name);			inf = fopen(szName, "wb");			if (inf) fwrite(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, 1, inf);			fclose(inf);			fprintf(nhml, "specificInfoFile=\"%s\" ", szName);		}		gf_odf_desc_del((GF_Descriptor *) esd);		if (gf_isom_get_media_type(dumper->file, track)==GF_ISOM_MEDIA_VISUAL) {			u32 w, h;			gf_isom_get_visual_info(dumper->file, track, 1, &w, &h);			fprintf(nhml, "width=\"%d\" height=\"%d\" ", w, h);		}		else if (gf_isom_get_media_type(dumper->file, track)==GF_ISOM_MEDIA_AUDIO) {			u32 sr, nb_ch;			u8 bps;			gf_isom_get_audio_info(dumper->file, track, 1, &sr, &nb_ch, &bps);			fprintf(nhml, "sampleRate=\"%d\" numChannels=\"%d\" ", sr, nb_ch);		}	} else {		GF_GenericSampleDescription *sdesc = gf_isom_get_generic_sample_description(dumper->file, track, 1);		u32 mtype = gf_isom_get_media_type(dumper->file, track);		fprintf(nhml, "mediaType=\"%s\" mediaSubType=\"%s\" ", gf_4cc_to_str(mtype), gf_4cc_to_str(sdesc->codec_tag));		if (mtype==GF_ISOM_MEDIA_VISUAL) {			fprintf(nhml, "codecVendor=\"%s\" codecVersion=\"%d\" codecRevision=\"%d\" ", gf_4cc_to_str(sdesc->vendor_code), sdesc->version, sdesc->revision);			fprintf(nhml, "width=\"%d\" height=\"%d\" compressorName=\"%s\" temporalQuality=\"%d\" spatialQuality=\"%d\" horizontalResolution=\"%d\" verticalResolution=\"%d\" bitDepth=\"%d\" ",				sdesc->width, sdesc->height, sdesc->compressor_name, sdesc->temporal_quality, sdesc->spacial_quality, sdesc->h_res, sdesc->v_res, sdesc->depth);		} else if (mtype==GF_ISOM_MEDIA_AUDIO) {			fprintf(nhml, "codecVendor=\"%s\" codecVersion=\"%d\" codecRevision=\"%d\" ", gf_4cc_to_str(sdesc->vendor_code), sdesc->version, sdesc->revision);			fprintf(nhml, "sampleRate=\"%d\" numChannels=\"%d\" bitsPerSample=\"%d\" ", sdesc->samplerate, sdesc->nb_channels, sdesc->bits_per_sample);		}		if (sdesc->extension_buf) {			sprintf(szName, "%s.info", dumper->out_name);			inf = fopen(szName, "wb");			if (inf) fwrite(sdesc->extension_buf, sdesc->extension_buf_size, 1, inf);			fclose(inf);			fprintf(nhml, "specificInfoFile=\"%s\" ", szName);			free(sdesc->extension_buf);		}		free(sdesc);	}	fprintf(nhml, "baseMediaFile=\"%s\" ", szMedia);	if (gf_isom_is_track_in_root_od(dumper->file, track)) fprintf(nhml, "inRootOD=\"yes\" ");	fprintf(nhml, "trackID=\"%d\" ", dumper->trackID);	fprintf(nhml, ">\n");	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, med);		fprintf(nhml, "<NHNTSample DTS=\""LLD"\" dataLength=\"%d\" ", LLD_CAST samp->DTS, samp->dataLength);		if (full_dump || samp->CTS_Offset) fprintf(nhml, "CTSOffset=\"%d\" ", samp->CTS_Offset);		if (samp->IsRAP==1) fprintf(nhml, "isRAP=\"yes\" ");		else if (samp->IsRAP==2) fprintf(nhml, "isSyncShadow=\"yes\" ");		else if (full_dump) fprintf(nhml, "isRAP=\"no\" ");		if (full_dump) fprintf(nhml, "mediaOffset=\"%d\" ", pos);		fprintf(nhml, "/>\n");		pos += samp->dataLength;		gf_isom_sample_del(&samp);		gf_set_progress("NHML Export", i+1, count);		if (dumper->flags & GF_EXPORT_DO_ABORT) break;	}	fprintf(nhml, "</NHNTStream>\n");	fclose(med);	fclose(nhml);	return GF_OK;}typedef struct {	u32 track_num, stream_id, last_sample, nb_samp;} SAFInfo;GF_Err gf_media_export_saf(GF_MediaExporter *dumper){	u32 count, i, s_count, di, tot_samp, samp_done;	char out_file[GF_MAX_PATH];	GF_SAFMuxer *mux;	char *data;	u32 size;	FILE *saf_f;	SAFInfo safs[1024];	if (dumper->flags & GF_EXPORT_PROBE_ONLY) return GF_OK;	s_count = tot_samp = 0;	mux = gf_saf_mux_new();	count = gf_isom_get_track_count(dumper->file);	for (i=0; i<count; i++) {		u32 time_scale, mtype, stream_id;		GF_ESD *esd;		mtype = gf_isom_get_media_type(dumper->file, i+1);		if (mtype==GF_ISOM_MEDIA_OD) continue;		if (mtype==GF_ISOM_MEDIA_HINT) continue;		stream_id = 0;		time_scale = gf_isom_get_media_timescale(dumper->file, i+1);		esd = gf_isom_get_esd(dumper->file, i+1, 1);		if (esd) {			stream_id = gf_isom_find_od_for_track(dumper->file, i+1);			if (!stream_id) stream_id = esd->ESID;			/*translate OD IDs to ESIDs !!*/			if (esd->decoderConfig->decoderSpecificInfo) {				gf_saf_mux_stream_add(mux, stream_id, time_scale, esd->decoderConfig->bufferSizeDB, esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication, NULL, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, esd->URLString);			} else {				gf_saf_mux_stream_add(mux, stream_id, time_scale, esd->decoderConfig->bufferSizeDB, esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication, NULL, NULL, 0, esd->URLString);			}			gf_odf_desc_del((GF_Descriptor *)esd);		} else {			char *mime = NULL;			switch (gf_isom_get_media_subtype(dumper->file, i+1, 1)) {			case GF_ISOM_SUBTYPE_3GP_H263: mime = "video/h263"; break;			case GF_ISOM_SUBTYPE_3GP_AMR: mime = "audio/amr"; break;			case GF_ISOM_SUBTYPE_3GP_AMR_WB: mime = "audio/amr-wb"; break;			case GF_ISOM_SUBTYPE_3GP_EVRC: mime = "audio/evrc"; break;			case GF_ISOM_SUBTYPE_3GP_QCELP: mime = "audio/qcelp"; break;			case GF_ISOM_SUBTYPE_3GP_SMV: mime = "audio/smv"; break;			}			if (!mime) continue;			stream_id = gf_isom_get_track_id(dumper->file, i+1);			gf_saf_mux_stream_add(mux, stream_id, time_scale, 0, 0xFF, 0xFF, mime, NULL, 0, NULL);		}		safs[s_count].track_num = i+1;		safs[s_count].stream_id = stream_id;		safs[s_count].nb_samp = gf_isom_get_sample_count(dumper->file, i+1);		safs[s_count].last_sample = 0;		tot_samp += safs[s_count].nb_samp;		s_count++;	}	if (!s_count) {		gf_export_message(dumper, GF_OK, "No tracks available for SAF muxing");		gf_saf_mux_del(mux);		return GF_OK;	}	gf_export_message(dumper, GF_OK, "SAF: Multiplexing %d tracks", s_count);	strcpy(out_file, dumper->out_name);	strcat(out_file, ".saf");	saf_f = fopen(out_file, "wb");	samp_done = 0;	while (samp_done<tot_samp) {		for (i=0; i<s_count; i++) {			GF_ISOSample *samp;			if (safs[i].last_sample==safs[i].nb_samp) continue;			samp = gf_isom_get_sample(dumper->file, safs[i].track_num, safs[i].last_sample + 1, &di);			gf_saf_mux_add_au(mux, safs[i].stream_id, (u32) (samp->DTS+samp->CTS_Offset), samp->data, samp->dataLength, samp->IsRAP);			/*data is kept by muxer!!*/			free(samp);			safs[i].last_sample++;			samp_done ++;		}		while (1) {			gf_saf_mux_for_time(mux, (u32) -1, 0, &data, &size);			if (!data) break;			fwrite(data, size, 1, saf_f);			free(data);		}		gf_set_progress("SAF Export", samp_done, tot_samp);		if (dumper->flags & GF_EXPORT_DO_ABORT) break;	}		gf_saf_mux_for_time(mux, (u32) -1, 1, &data, &size);	if (data) {		fwrite(data, size, 1, saf_f);		free(data);	}	fclose(saf_f);	gf_saf_mux_del(mux);	return GF_OK;}void m2ts_export_check(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) {	if (evt_type == GF_M2TS_EVT_PAT_REPEAT) ts->user = NULL;}void m2ts_export_dump(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) {	if (evt_type == GF_M2TS_EVT_PES_PCK) {		FILE *dst = (FILE*)ts->user;		GF_M2TS_PES_PCK *pck = (GF_M2TS_PES_PCK *)par;		fwrite(pck->data, pck->data_len, 1, dst);	}}GF_Err gf_media_export_ts_native(GF_MediaExporter *dumper){	char data[188], szFile[GF_MAX_PATH];	GF_M2TS_PES *stream;	u32 i, size, fsize, fdone;	GF_M2TS_Demuxer *ts;	FILE *src, *dst;	if (dumper->flags & GF_EXPORT_PROBE_ONLY) return GF_OK;		src = fopen(dumper->in_name, "rb");	if (!src) return gf_export_message(dumper, GF_CODEC_NOT_FOUND, "Error opening %s", dumper->in_name);	fseek(src, 0, SEEK_END);	fsize = ftell(src);	fseek(src, 0, SEEK_SET);	ts = gf_m2ts_demux_new();	ts->on_event = m2ts_export_check;	ts->user = dumper;	/*get PAT*/	while (!feof(src)) {		size = fread(data, 1, 188, src);		if (size<188) break;		gf_m2ts_process_data(ts, data, size);		if (!ts->user) break;	}	if (ts->user) {		fclose(src);		gf_m2ts_demux_del(ts);		return gf_export_message(dumper, GF_URL_ERROR, "Cannot locate program association table");	}	stream = NULL;	for (i=0; i<GF_M2TS_MAX_STREAMS; i++) {		GF_M2TS_PES *pes = (GF_M2TS_PES *)ts->ess[i];		if (!pes || (pes->pid==pes->program->pmt_pid)) continue;		if (pes->pid == dumper->trackID) {			stream = pes;			gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_RAW);		} else {			gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_SKIP);		}		break;	}	if (!stream) {		fclose(src);		gf_m2ts_demux_del(ts);		return gf_export_message(dumper, GF_URL_ERROR, "Cannot find PID %d in transport stream", dumper->trackID);	}	gf_m2ts_reset_parsers(ts);	sprintf(szFile, "%s_pid%d", dumper->out_name ? dumper->out_name : "", stream->pid);	switch (stream->stream_type) {	case GF_M2TS_VIDEO_MPEG1:		strcat(szFile, ".m1v");		gf_export_message(dumper, GF_OK, "Extracting MPEG-1 Visual stream to m1v");		break;	case GF_M2TS_VIDEO_MPEG2:		strcat(szFile, ".m2v");		gf_export_message(dumper, GF_OK, "Extracting MPEG-2 Visual stream to m1v");		break;	case GF_M2TS_AUDIO_MPEG1:		strcat(szFile, ".mp3");		gf_export_message(dumper, GF_OK, "Extracting MPEG-1 Audio stream to mp3");		break;	case GF_M2TS_AUDIO_MPEG2:		strcat(szFile, ".mp3");		gf_export_message(dumper, GF_OK, "Extracting MPEG-2 Audio stream to mp3");		break;	case GF_M2TS_AUDIO_AAC:		strcat(szFile, ".aac");		gf_export_message(dumper, GF_OK, "Extracting MPEG-4 Audio stream to aac");		break;	case GF_M2TS_VIDEO_MPEG4:		strcat(szFile, ".cmp");		gf_export_message(dumper, GF_OK, "Extracting MPEG-4 Visual stream to cmp");		break;	case GF_M2TS_VIDEO_H264:		strcat(szFile, ".264");		gf_export_message(dumper, GF_OK, "Extracting MPEG-4 AVC/H264 Visual stream to h264");		break;	default:		strcat(szFile, ".raw");		gf_export_message(dumper, GF_OK, "Extracting Unknown stream to raw");		break;	}	dst = fopen(szFile, "wb");	if (!dst) {		fclose(src);		gf_m2ts_demux_del(ts);		return gf_export_message(dumper, GF_IO_ERR, "Cannot open file %s for writing", szFile);	}	gf_m2ts_reset_parsers(ts);	gf_f64_seek(src, 0, SEEK_SET);	fdone = 0;	ts->user = dst;	ts->on_event = m2ts_export_dump;	while (!feof(src)) {		size = fread(data, 1, 188, src);		if (size<188) break;		gf_m2ts_process_data(ts, data, size);		fdone += size;		gf_set_progress("MPEG-2 TS Extract", fdone, fsize);		if (dumper->flags & GF_EXPORT_DO_ABORT) break;	}	gf_set_progress("MPEG-2 TS Extract", fsize, fsize);	fclose(dst);	fclose(src);	gf_m2ts_demux_del(ts);	return GF_OK;}GF_EXPORTGF_Err gf_media_export(GF_MediaExporter *dumper){	if (!dumper) return GF_BAD_PARAM;	if (!dumper->out_name && !dumper->flags & GF_EXPORT_PROBE_ONLY) return GF_BAD_PARAM;		if (dumper->flags & GF_EXPORT_NATIVE) {		if (dumper->in_name) {			char *ext = strrchr(dumper->in_name, '.');			if (ext && (!strnicmp(ext, ".ts", 3) || !strnicmp(ext, ".m2t", 4)) ) {				return gf_media_export_ts_native(dumper);			}		}		return gf_media_export_native(dumper);	}	else if (dumper->flags & GF_EXPORT_RAW_SAMPLES) return gf_media_export_samples(dumper);	else if (dumper->flags & GF_EXPORT_NHNT) return gf_media_export_nhnt(dumper);	else if (dumper->flags & GF_EXPORT_AVI) return gf_media_export_avi(dumper);	else if (dumper->flags & GF_EXPORT_MP4) return gf_media_export_isom(dumper);	else if (dumper->flags & GF_EXPORT_AVI_NATIVE) return gf_media_export_avi_track(dumper);	else if (dumper->flags & GF_EXPORT_NHML) return gf_media_export_nhml(dumper);	else if (dumper->flags & GF_EXPORT_SAF) return gf_media_export_saf(dumper);	else return GF_BAD_PARAM;}#endif

⌨️ 快捷键说明

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