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

📄 quicktime.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
}int quicktime_write_video_hint(quicktime_t *file, 				unsigned char *hintBuffer, 				long hintBufferSize, 				int videoTrack,				int hintTrack,				long hintSampleDuration,				u_char isKeyFrame){	quicktime_trak_t* hintTrak = 		file->vtracks[videoTrack].hintTracks[hintTrack];	return quicktime_write_media_hint(file, hintBuffer, hintBufferSize,		hintTrak, &(file->vtracks[videoTrack].hintPositions[hintTrack]), 		hintSampleDuration, isKeyFrame);}FILE* quicktime_get_fd(quicktime_t *file){	if(ftell(file->stream) != file->file_position) fseek(file->stream, file->file_position, SEEK_SET);	return file->stream;}int quicktime_write_frame_init(quicktime_t *file, int track){	if(ftell(file->stream) != file->file_position) fseek(file->stream, file->file_position, SEEK_SET);	file->offset = quicktime_position(file);	return 0;}int quicktime_write_frame_end(quicktime_t *file, int track){	long bytes;	file->file_position = ftell(file->stream);	bytes = quicktime_position(file) - file->offset;	quicktime_update_tables(file,						file->vtracks[track].track,						file->offset,						file->vtracks[track].current_chunk,						file->vtracks[track].current_position,						1,						bytes,						0,						0,						0);	file->vtracks[track].current_position += 1;	file->vtracks[track].current_chunk++;	return 0;}int quicktime_write_audio_init(quicktime_t *file, int track){	return quicktime_write_frame_init(file, track);}int quicktime_write_audio_end(quicktime_t *file, int track, long samples){	long bytes;	file->file_position = ftell(file->stream);	bytes = quicktime_position(file) - file->offset;	quicktime_update_tables(file, 						file->atracks[track].track,						file->offset,						file->atracks[track].current_chunk,						file->atracks[track].current_position,						samples,						bytes, 						0,						0,						0);	file->atracks[track].current_position += samples;	file->atracks[track].current_chunk++;	return 0;}long quicktime_read_audio(quicktime_t *file, char *audio_buffer, long samples, int track){	long chunk_sample, chunk;	int result = 1, track_num;	quicktime_trak_t *trak = file->atracks[track].track;	long fragment_len, chunk_end;	long position = file->atracks[track].current_position;	long start = position, end = position + samples;	long bytes, total_bytes = 0;	long buffer_offset;	quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, position);	buffer_offset = 0;	while(position < end && result)	{		quicktime_set_audio_position(file, position, track);		fragment_len = quicktime_chunk_samples(trak, chunk);		chunk_end = chunk_sample + fragment_len;		fragment_len -= position - chunk_sample;		if(position + fragment_len > chunk_end) fragment_len = chunk_end - position;		if(position + fragment_len > end) fragment_len = end - position;		bytes = quicktime_samples_to_bytes(trak, fragment_len);		result = quicktime_read_data(file, &audio_buffer[buffer_offset], bytes);		total_bytes += bytes;		position += fragment_len;		chunk_sample = position;		buffer_offset += bytes;		chunk++;	}	file->atracks[track].current_position = position;	if(!result) return 0;	return total_bytes;}int quicktime_read_chunk(quicktime_t *file, char *output, int track, long chunk, long byte_start, long byte_len){	quicktime_set_position(file, quicktime_chunk_to_offset(file->atracks[track].track, chunk) + byte_start);	if(quicktime_read_data(file, output, byte_len)) return 0;	else	return 1;}long quicktime_frame_size(quicktime_t *file, long frame, int track){	int bytes;	quicktime_trak_t *trak = file->vtracks[track].track;	if(trak->mdia.minf.stbl.stsz.sample_size)	{		bytes = trak->mdia.minf.stbl.stsz.sample_size;	}	else	{		bytes = trak->mdia.minf.stbl.stsz.table[frame].size;	}	return bytes;}long quicktime_audio_frame_size(quicktime_t *file, long frame, int track){	int bytes;	quicktime_trak_t *trak = file->atracks[track].track;	if(trak->mdia.minf.stbl.stsz.sample_size)	{		bytes = trak->mdia.minf.stbl.stsz.sample_size;	}	else	{		bytes = trak->mdia.minf.stbl.stsz.table[frame].size;	}	return bytes;}long quicktime_read_audio_frame(quicktime_t *file, unsigned char *audio_buffer,  int maxBytes, int track){	long bytes;	int result = 0;	quicktime_trak_t *trak = file->atracks[track].track;	bytes = quicktime_audio_frame_size(file, 		file->atracks[track].current_position, track);	if (bytes > maxBytes) {		return -bytes;	}	quicktime_set_audio_position(file, 		file->atracks[track].current_position, track);	result = quicktime_read_data(file, audio_buffer, bytes);	file->atracks[track].current_position++;	if (!result)		return 0;	return bytes;}long quicktime_read_frame(quicktime_t *file, unsigned char *video_buffer, int track){	long bytes;	int result = 0;	quicktime_trak_t *trak = file->vtracks[track].track;	bytes = quicktime_frame_size(file, file->vtracks[track].current_position, track);	if(!file->vtracks[track].frames_cached)	{		quicktime_set_video_position(file, file->vtracks[track].current_position, track);		result = quicktime_read_data(file, video_buffer, bytes);	}	else	{		int i;		unsigned char *cached_frame;		if(file->vtracks[track].current_position >= file->vtracks[track].frames_cached) result = 1;		if(!result)		{			cached_frame = file->vtracks[track].frame_cache[file->vtracks[track].current_position];			for(i = 0; i < bytes; i++)				video_buffer[i] = cached_frame[i];		}	}	file->vtracks[track].current_position++;	if(!result) return 0;	return bytes;}int quicktime_read_frame_init(quicktime_t *file, int track){	quicktime_trak_t *trak = file->vtracks[track].track;	quicktime_set_video_position(file, file->vtracks[track].current_position, track);	if(ftell(file->stream) != file->file_position) fseek(file->stream, file->file_position, SEEK_SET);	return 0;}int quicktime_read_frame_end(quicktime_t *file, int track){	file->file_position = ftell(file->stream);	file->vtracks[track].current_position++;	return 0;}int quicktime_init_video_map(quicktime_video_map_t *vtrack, quicktime_trak_t *trak){	vtrack->track = trak;	vtrack->current_position = 0;	vtrack->current_chunk = 1;	vtrack->frame_cache = 0;	vtrack->frames_cached = 0;	return 0;}int quicktime_delete_video_map(quicktime_video_map_t *vtrack){	int i;	if(vtrack->frames_cached)	{		for(i = 0; i < vtrack->frames_cached; i++)		{			free(vtrack->frame_cache[i]);		}		free(vtrack->frame_cache);		vtrack->frames_cached = 0;	}	return 0;}int quicktime_init_audio_map(quicktime_audio_map_t *atrack, quicktime_trak_t *trak){	atrack->track = trak;	atrack->channels = trak->mdia.minf.stbl.stsd.table[0].channels;	atrack->current_position = 0;	atrack->current_chunk = 1;	return 0;}int quicktime_delete_audio_map(quicktime_audio_map_t *atrack){	int i;	return 0;}int quicktime_read_info(quicktime_t *file){	int result = 0, found_moov = 0;	int i, j, k, m, channel, trak_channel, track;	long start_position = quicktime_position(file);	quicktime_atom_t leaf_atom;	quicktime_trak_t *trak;	char avi_test[4];/* Check for Microsoft AVI */	quicktime_read_char32(file, avi_test);	if(quicktime_match_32(avi_test, "RIFF"))	{		quicktime_read_char32(file, avi_test);		quicktime_read_char32(file, avi_test);		if(quicktime_match_32(avi_test, "AVI "))			file->use_avi = 1;	}	quicktime_set_position(file, 0);	do	{		result = quicktime_atom_read_header(file, &leaf_atom);		if(!result)		{			if(quicktime_atom_is(&leaf_atom, "mdat")) {				quicktime_read_mdat(file, &(file->mdat), &leaf_atom);			} else if(quicktime_atom_is(&leaf_atom, "moov")) {				quicktime_read_moov(file, &(file->moov), &leaf_atom);				found_moov = 1;			} else {				quicktime_atom_skip(file, &leaf_atom);			}		}	}while(!result && quicktime_position(file) < file->total_length);/* go back to the original position */	quicktime_set_position(file, start_position);	if(found_moov) {		/* get tables for all the different tracks */		file->total_atracks = quicktime_audio_tracks(file);		file->atracks = (quicktime_audio_map_t*)calloc(1, 			sizeof(quicktime_audio_map_t) * file->total_atracks);		for(i = 0, track = 0; i < file->total_atracks; i++) {			while(!file->moov.trak[track]->mdia.minf.is_audio)				track++;			quicktime_init_audio_map(&(file->atracks[i]), file->moov.trak[track]);		}		file->total_vtracks = quicktime_video_tracks(file);		file->vtracks = (quicktime_video_map_t*)calloc(1, sizeof(quicktime_video_map_t) * file->total_vtracks);		for(track = 0, i = 0; i < file->total_vtracks; i++)		{			while(!file->moov.trak[track]->mdia.minf.is_video)				track++;			quicktime_init_video_map(&(file->vtracks[i]), file->moov.trak[track]);		}		/* for all tracks */		for (track = 0; track < file->moov.total_tracks; track++) {			/* check if it's a hint track */			if (!file->moov.trak[track]->mdia.minf.is_hint) {				continue;			}			/* it is, so for each reference */			for (j = 0; j < file->moov.trak[track]->tref.hint.numTracks; j++) {				/* get the reference track id */				long refTrackId = file->moov.trak[track]->tref.hint.trackIds[j]; 				/* check each audio track */				for(k = 0; k < file->total_atracks; k++) {					if (file->atracks[k].track->tkhd.track_id == refTrackId) {						int m = file->atracks[k].totalHintTracks++;						file->atracks[k].hintTracks[m] = file->moov.trak[track];						file->atracks[k].hintPositions[m] = 0;						file->moov.trak[track]->tref.hint.traks[j] = 							file->atracks[k].track;						file->total_hint_tracks++;						break;					}				}				/* check each video track */				for(k = 0; k < file->total_vtracks; k++) {					if (file->vtracks[k].track->tkhd.track_id == refTrackId) {						int m = file->vtracks[k].totalHintTracks++;						file->vtracks[k].hintTracks[m] = file->moov.trak[track];						file->vtracks[k].hintPositions[m] = 0;						file->moov.trak[track]->tref.hint.traks[j] = 							file->vtracks[k].track;						file->total_hint_tracks++;						break;					}				}			}		}	}	if(found_moov) 		return 0; 	else 		return 1;}int quicktime_dump(quicktime_t *file){	printf("quicktime_dump\n");	printf("movie data\n");	printf(" size %ld\n", file->mdat.size);	printf(" start %ld\n", file->mdat.start);	quicktime_moov_dump(&(file->moov));	return 0;}/* ================================== Entry points ========================== */int quicktime_check_sig(const char *path){	quicktime_t file;	quicktime_atom_t leaf_atom;	int result1 = 0, result2 = 0;	quicktime_init(&file);	if(!(file.stream = fopen(path, "rb"))) 	{		perror("quicktime_check_sig");		return 0;	}	fseek(file.stream, 0, SEEK_END);	file.total_length = ftell(file.stream);	fseek(file.stream, 0, SEEK_SET);	do	{		result1 = quicktime_atom_read_header(&file, &leaf_atom);		if(!result1)		{/* just want the "moov" atom */			if(quicktime_atom_is(&leaf_atom, "moov"))			{				result2 = 1;			}			else				quicktime_atom_skip(&file, &leaf_atom);		}	}while(!result1 && !result2 && quicktime_position(&file) < file.total_length);	fclose(file.stream);	quicktime_delete(&file);	return result2;}quicktime_t* quicktime_open(char *filename, int rd, int wr, int append){	quicktime_t *new_file = malloc(sizeof(quicktime_t));	char flags[10];	int exists = 0;	quicktime_init(new_file);	new_file->wr = wr;	new_file->rd = rd;	new_file->mdat.start = 0;	if (!strcmp(&filename[strlen(filename)-4], ".mp4")) {		new_file->use_mp4 = TRUE;	} else {		new_file->use_mp4 = FALSE;	}	if(rd && (new_file->stream = fopen(filename, "rb")))	{		exists = 1; 		fclose(new_file->stream); 		new_file->stream = NULL;	}	if(rd && !wr) 		sprintf(flags, "rb");	else if(!rd && wr) 		sprintf(flags, "wb");	else if(rd && wr)	{		if(exists) 			sprintf(flags, "rb+");		else			sprintf(flags, "wb+");	}	if(!(new_file->stream = fopen(filename, flags)))	{		perror("quicktime_open");		free(new_file);		return 0;	}	if(rd && exists)	{		fseek(new_file->stream, 0, SEEK_END);		new_file->total_length = ftell(new_file->stream);		fseek(new_file->stream, 0, SEEK_SET);		if(quicktime_read_info(new_file))		{			quicktime_close(new_file);			new_file = 0;		}	}	if(wr) {		if(!exists || !append) {			/* start the data atom */			quicktime_write_int32(new_file, 0);			quicktime_write_char32(new_file, "mdat");		} else {			quicktime_set_position(new_file,				 new_file->mdat.start + new_file->mdat.size);			fseek(new_file->stream, 				 new_file->mdat.start + new_file->mdat.size, SEEK_SET);		}	}	return new_file;}int quicktime_write(quicktime_t *file){	int result = -1;	if(!file->wr) {		return result;	}	quicktime_write_mdat(file, &(file->mdat));	quicktime_write_moov(file, &(file->moov));	result = fclose(file->stream);	file->stream = NULL;	return result;}int quicktime_destroy(quicktime_t *file){	quicktime_delete(file);	free(file);	return 0;}int quicktime_close(quicktime_t *file){	int result;	if(file->wr)	{		quicktime_write_mdat(file, &(file->mdat));		quicktime_write_moov(file, &(file->moov));	}	result = fclose(file->stream);	quicktime_delete(file);	free(file);	return result;}

⌨️ 快捷键说明

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