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

📄 fileimport.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
		mtype = gf_isom_get_media_type(mp4, i+1);		switch (mtype) {		/*we duplicate text samples at boundaries*/		case GF_ISOM_MEDIA_TEXT:			tks[nb_tk].can_duplicate = 1;		case GF_ISOM_MEDIA_AUDIO:			break;		case GF_ISOM_MEDIA_VISUAL:			if (gf_isom_get_sample_count(mp4, i+1)>1) {				break;			}			continue;		case GF_ISOM_MEDIA_HINT:		case GF_ISOM_MEDIA_SCENE:		case GF_ISOM_MEDIA_OCR:		case GF_ISOM_MEDIA_OD:		case GF_ISOM_MEDIA_OCI:		case GF_ISOM_MEDIA_IPMP:		case GF_ISOM_MEDIA_MPEGJ:		case GF_ISOM_MEDIA_MPEG7:		case GF_ISOM_MEDIA_FLASH:			fprintf(stdout, "WARNING: Track ID %d (type %s) not handled by spliter - skipping\n", gf_isom_get_track_id(mp4, i+1), gf_4cc_to_str(mtype));			continue;		default:			/*for all other track types, only split if more than one sample*/			if (gf_isom_get_sample_count(mp4, i+1)==1) {				fprintf(stdout, "WARNING: Track ID %d (type %s) not handled by spliter - skipping\n", gf_isom_get_track_id(mp4, i+1), gf_4cc_to_str(mtype));				continue;			}			tks[nb_tk].can_duplicate = 1;		}		tks[nb_tk].sample_count = gf_isom_get_sample_count(mp4, i+1);		nb_samp += tks[nb_tk].sample_count;		tks[nb_tk].last_sample = 0;		tks[nb_tk].firstDTS = 0;		tks[nb_tk].time_scale = gf_isom_get_media_timescale(mp4, i+1);		tks[nb_tk].has_non_raps = gf_isom_has_sync_points(mp4, i+1);		/*seen that on some 3gp files from nokia ...*/		if (mtype==GF_ISOM_MEDIA_AUDIO) tks[nb_tk].has_non_raps = 0;				dur = (Double) (s64) gf_isom_get_media_duration(mp4, i+1);		dur /= tks[nb_tk].time_scale;		if (max_dur<dur) max_dur=dur;		if (tks[nb_tk].has_non_raps) {			/*we don't support that*/			if (needs_rap_sync) {				fprintf(stdout, "More than one track has non-sync points - cannot split file\n");				free(tks);				return GF_NOT_SUPPORTED;			}			needs_rap_sync = nb_tk+1;		}		if (!tks[nb_tk].can_duplicate) all_duplicatable = 0;		nb_tk++;	}	if (!nb_tk) {		fprintf(stdout, "No suitable tracks found for spliting file\n");		free(tks);		return GF_NOT_SUPPORTED;	}	if (chunk_start>=max_dur) {		fprintf(stdout, "Input file (%f) shorter than requested split start offset (%f)\n", max_dur, chunk_start);		free(tks);		return GF_NOT_SUPPORTED;	}	if (max_dur<=split_dur) {		fprintf(stdout, "Input file (%f) shorter than requested split duration (%f)\n", max_dur, split_dur);		free(tks);		return GF_NOT_SUPPORTED;	}	if (needs_rap_sync) {		tki = &tks[needs_rap_sync-1];		if ((gf_isom_get_sync_point_count(mp4, tki->tk)==1) && (chunk_start != 0.0f)) {			fprintf(stdout, "Not enough Random Access points in input file - cannot split\n");			free(tks);			return GF_NOT_SUPPORTED;		}	}	split_size_kb *= 1024;	cur_file_time = 0;	if (chunk_start>0) {		if (needs_rap_sync) {			u32 sample_num;			Double start;			tki = &tks[needs_rap_sync-1];			start = (Double) (s64) gf_isom_get_sample_dts(mp4, tki->tk, tki->sample_count);			start /= tki->time_scale;			if (start<chunk_start) {				tki->stop_state = 2;				needs_rap_sync = 0;			} else  {				e = gf_isom_get_sample_for_media_time(mp4, tki->tk, (u64) (chunk_start*tki->time_scale), &di, GF_ISOM_SEARCH_SYNC_BACKWARD, &samp, &sample_num);				if (e!=GF_OK) {					fprintf(stdout, "Cannot locate RAP in track ID %d for chunk extraction from %02.2f sec\n", gf_isom_get_track_id(mp4, tki->tk), chunk_start);					free(tks);					return GF_NOT_SUPPORTED;				}				start = (Double) (s64) samp->DTS;				start /= tki->time_scale;				gf_isom_sample_del(&samp);				fprintf(stdout, "Adjusting chunk start time to previous random access at %02.2f sec\n", start);				split_dur += (chunk_start - start);				chunk_start = start;			}		}		/*sync all tracks*/		for (i=0; i<nb_tk; i++) {			tki = &tks[i];			while (tki->last_sample<tki->sample_count) {				Double time;				u64 dts;				dts = gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1);				time = (Double) (s64) dts;				time /= tki->time_scale;				if (time>=chunk_start) {					/*rewind one sample (text tracks & co)*/					if (tki->can_duplicate && tki->last_sample) {						tki->last_sample--;						tki->firstDTS = (u64) (chunk_start*tki->time_scale);					} else {						tki->firstDTS = dts;					}					break;				}				tki->last_sample++;			}		}		cur_file_time = chunk_start;	} else {		chunk_start = 0;	}	dest = NULL;	nb_done = 0;	nb_tk_done = 0;	cur_file = 0;	while (nb_tk_done<nb_tk) {		Double last_rap_sample_time, max_dts, file_split_dur;		Bool is_last;		if (chunk_extraction) {			if (outfile) {				strcpy(szFile, outfile);			} else {				sprintf(szFile, "%s_%d_%d%s", szName, (u32) chunk_start, (u32) (chunk_start+split_dur), ext);			}		} else {			sprintf(szFile, "%s_%03d%s", szName, cur_file+1, ext);		}		dest = gf_isom_open(szFile, GF_ISOM_WRITE_EDIT, tmpdir);		/*clone all tracks*/		for (i=0; i<nb_tk; i++) {			tki = &tks[i];			/*track done - we remove the track from destination, an empty video track could cause pbs to some players*/			if (tki->stop_state==2) continue;			e = gf_isom_clone_track(mp4, tki->tk, dest, 0, &tki->dst_tk);			if (e) {				fprintf(stdout, "Error cloning track %d\n", tki->tk);				goto err_exit;			}			/*use non-packet CTS offsets (faster add/remove)*/			if (gf_isom_has_time_offset(mp4, tki->tk)) {				gf_isom_set_cts_packing(dest, tki->dst_tk, 1);			}		}		do_add = 1;		is_last = 0;		last_rap_sample_time = 0;		file_split_dur = split_dur;		size_exceeded = 0;		max_dts = 0;		while (do_add) {			Double time;			u32 nb_over;			/*perfom basic de-interleaving to make sure we're not importing too much of a given track*/			u32 nb_add = 0;			/*add one sample of each track*/			for (i=0; i<nb_tk; i++) {				Double t;				u64 dts;				tki = &tks[i];								if (tki->stop_state) 					continue;				if (tki->last_sample==tki->sample_count) 					continue;							/*get sample info, see if we need to check it (basic de-interleaver)*/				dts = gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1);				/*reinsertion (timed text)*/				if (dts < tki->firstDTS) {					samp = gf_isom_get_sample(mp4, tki->tk, tki->last_sample+1, &di);					samp->DTS = 0;					e = gf_isom_add_sample(dest, tki->dst_tk, di, samp);					gf_isom_sample_del(&samp);					tki->last_sample += 1;					dts = gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1);				}				dts -= tki->firstDTS;				t = (Double) (s64) dts;				t /= tki->time_scale;				if (tki->first_sample_done) {					if (t>max_dts) continue;				} else {					/*here's the trick: only take care of a/v media for deinterleaving, and ad other media					only if thir dts is less than the max AV dts found. Otherwise with some text streams we will end up importing					too much video and corrupting the last sync point indication*/					if (!tki->can_duplicate && (t>max_dts)) max_dts = t;					tki->first_sample_done = 1;				}				samp = gf_isom_get_sample(mp4, tki->tk, tki->last_sample+1, &di);				samp->DTS -= tki->firstDTS;				nb_add += 1;				if (tki->has_non_raps && samp->IsRAP) {					GF_ISOSample *next_rap;					u32 next_rap_num, sdi;					last_rap_sample_time = (Double) (s64) samp->DTS;					last_rap_sample_time /= tki->time_scale;					e = gf_isom_get_sample_for_media_time(mp4, tki->tk, samp->DTS+tki->firstDTS+2, &sdi, GF_ISOM_SEARCH_SYNC_FORWARD, &next_rap, &next_rap_num);					if (e==GF_EOS) is_last = 1;					if (next_rap) {						if (!next_rap->IsRAP) 							is_last = 1;						gf_isom_sample_del(&next_rap);					}				}				tki->lastDTS = samp->DTS;				e = gf_isom_add_sample(dest, tki->dst_tk, di, samp);				gf_isom_sample_del(&samp);				tki->last_sample += 1;				gf_set_progress("Splitting", nb_done, nb_samp);				nb_done++;				if (e) {					fprintf(stdout, "Error cloning track %d sample %d\n", tki->tk, tki->last_sample);					goto err_exit;				}			}			/*test by size/duration*/			nb_over = 0;			/*test by file size: same as duration test, only dynamically increment import duration*/			if (split_size_kb) {				u64 est_size = gf_isom_estimate_size(dest);				/*while below desired size keep importing*/				if (est_size<split_size_kb) 					file_split_dur = (Double) GF_MAX_FLOAT;				else {					size_exceeded = 1;				}			}			for (i=0; i<nb_tk; i++) {				tki = &tks[i];				if (tki->stop_state) {					nb_over++;					continue;				}				time = (Double) (s64) tki->lastDTS;				time /= tki->time_scale;				if (size_exceeded || (tki->last_sample==tki->sample_count) || (!tki->can_duplicate && (time>file_split_dur)) ) {					nb_over++;					tki->stop_state = 1;					if (tki->last_sample<tki->sample_count) is_last = 0;					if ((!tki->can_duplicate || all_duplicatable) && (tki->last_sample==tki->sample_count)) is_last = 1;				}				/*special tracks (not audio, not video)*/				else if (tki->can_duplicate) {					u64 dts = gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1);					time = (Double) (s64) (dts - tki->firstDTS);					time /= tki->time_scale;					if (time>file_split_dur) {						nb_over++;						tki->stop_state = 1;					}				}				if (!nb_add && (!max_dts || (tki->lastDTS <= 1 + (u64) (tki->time_scale*max_dts) ))) 					tki->first_sample_done = 0;			}			if (nb_over==nb_tk) do_add = 0;		}		/*remove samples - first figure out smallest duration*/		file_split_dur = (Double) GF_MAX_FLOAT;		for (i=0; i<nb_tk; i++) {			Double time;			tki = &tks[i];			/*track done*/			if ((tki->stop_state==2) || (!is_last && (tki->sample_count == tki->last_sample)) ) {				if (tki->has_non_raps) last_rap_sample_time = 0;				continue;			}			if (tki->lastDTS) {				time = (Double) (s64) tki->lastDTS;				time /= tki->time_scale;				if ((!tki->can_duplicate || all_duplicatable) && time<file_split_dur) file_split_dur = time;			}		}		if (chunk_extraction) file_split_dur = split_dur;		/*don't split if eq to copy...*/		if (is_last && !cur_file && !chunk_start) {			fprintf(stdout, "Cannot split file (Not enough sync samples, duration too large or size too big)\n");			goto err_exit;		}		/*if not last chunk and longer duration adjust to previous RAP point*/		if ( (size_exceeded || !split_size_kb) && (file_split_dur>split_dur) && !chunk_start) {			/*if larger than last RAP, rewind till it*/			if (last_rap_sample_time && (last_rap_sample_time<file_split_dur) ) {				file_split_dur = last_rap_sample_time;				is_last = 0;			}		}		nb_tk_done = 0;		if (!is_last || chunk_extraction) {			for (i=0; i<nb_tk; i++) {				Double time = 0;				u32 last_samp;				tki = &tks[i];				while (1) {					u64 dts;					last_samp = gf_isom_get_sample_count(dest, tki->dst_tk);					if (!last_samp) break;					dts = gf_isom_get_sample_dts(dest, tki->dst_tk, last_samp);					time = (Double) (s64) dts;					time /= tki->time_scale;					/*done*/					if (tki->last_sample==tki->sample_count) {						if (!chunk_extraction && !tki->can_duplicate) {							tki->stop_state=2;							break;						}					}					if (time /*+ (Double) GF_EPSILON_FLOAT*/ < file_split_dur) break;					gf_isom_remove_sample(dest, tki->dst_tk, last_samp);					tki->last_sample--;					assert(tki->last_sample);					nb_done--;					gf_set_progress("Splitting", nb_done, nb_samp);				}				if (tki->last_sample<tki->sample_count) {					u64 dts;					tki->stop_state = 0;					dts = gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1);					time = (Double) (s64) (dts - tki->firstDTS);					time /= tki->time_scale;					/*re-insert prev sample*/					if (tki->can_duplicate && (time>file_split_dur) ) {						tki->last_sample--;						dts = gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1);						tki->firstDTS += (u64) (file_split_dur*tki->time_scale);						gf_isom_set_last_sample_duration(dest, tki->dst_tk, (u32) (tki->firstDTS - dts) );					} else {						tki->firstDTS = dts;					}					tki->first_sample_done = 0;				} else {					nb_tk_done++;				}			}		}		if (chunk_extraction) {			fprintf(stdout, "Extracting chunk %s - duration %02.2f seconds\n", szFile, file_split_dur);		} else {			fprintf(stdout, "Storing split-file %s - duration %02.2f seconds\n", szFile, file_split_dur);		}		/*repack CTSs*/		for (i=0; i<nb_tk; i++) {			tki = &tks[i];			if (tki->stop_state == 2) continue;			if (!gf_isom_get_sample_count(dest, tki->dst_tk)) {				gf_isom_remove_track(dest, tki->dst_tk);				continue;			}			if (gf_isom_has_time_offset(mp4, tki->tk)) {				gf_isom_set_cts_packing(dest, tki->dst_tk, 0);			}			if (is_last && tki->can_duplicate) {				gf_isom_set_last_sample_duration(dest, tki->dst_tk, gf_isom_get_sample_duration(mp4, tki->tk, tki->sample_count));			}		}		/*check chapters*/		do_add = 1;		for (i=0; i<gf_isom_get_chapter_count(mp4, 0); i++) {

⌨️ 快捷键说明

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