📄 lqt_quicktime.c
字号:
lqt_codec_info_t * codec_info) { lqt_add_audio_track(file, channels, sample_rate, bits, codec_info); return 0; }int quicktime_set_audio(quicktime_t *file, int channels, long sample_rate, int bits, char *compressor){ lqt_codec_info_t ** info; info = lqt_find_audio_codec(compressor, 1); lqt_set_audio(file, channels, sample_rate, bits, *info); lqt_destroy_codec_info(info); return 1; /* Return the number of tracks created */}int lqt_set_video(quicktime_t *file, int tracks, int frame_w, int frame_h, int frame_duration, int timescale, lqt_codec_info_t * info) { int i; for(i = 0; i < tracks; i++) lqt_add_video_track(file, frame_w, frame_h, frame_duration, timescale, info); return 0;}int quicktime_set_video(quicktime_t *file, int tracks, int frame_w, int frame_h, double frame_rate, char *compressor) { lqt_codec_info_t ** info; int timescale, frame_duration; timescale = quicktime_get_timescale(frame_rate); frame_duration = (int)((double)(timescale)/frame_rate+0.5); info = lqt_find_video_codec(compressor, 1); lqt_set_video(file, tracks, frame_w, frame_h, frame_duration, timescale, *info); lqt_destroy_codec_info(info); return 0;}int lqt_add_video_track(quicktime_t *file, int frame_w, int frame_h, int frame_duration, int timescale, lqt_codec_info_t * info) { char * compressor = info->fourccs[0]; quicktime_trak_t *trak; if(!file->total_vtracks) quicktime_mhvd_init_video(file, &(file->moov.mvhd), timescale); file->vtracks = realloc(file->vtracks, (file->total_vtracks+1) * sizeof(quicktime_video_map_t)); memset(&(file->vtracks[file->total_vtracks]), 0, sizeof(quicktime_video_map_t)); trak = quicktime_add_track(file); file->total_vtracks++; quicktime_trak_init_video(file, trak, frame_w, frame_h, frame_duration, timescale, compressor); quicktime_init_video_map(&(file->vtracks[file->total_vtracks-1]), trak, file->wr, info); lqt_set_default_video_parameters(file, file->total_vtracks-1); /* Get encoding colormodel */ ((quicktime_codec_t*)(file->vtracks[file->total_vtracks-1].codec))->encode_video(file, (uint8_t**)0, file->total_vtracks-1); file->vtracks[file->total_vtracks-1].io_cmodel = file->vtracks[file->total_vtracks-1].stream_cmodel; return 0; }void quicktime_set_framerate(quicktime_t *file, double framerate){ int i; int new_time_scale, new_sample_duration; if(!file->wr) { lqt_log(file, LQT_LOG_WARNING, LOG_DOMAIN, "quicktime_set_framerate shouldn't be called in read mode."); return; } new_time_scale = quicktime_get_timescale(framerate); new_sample_duration = (int)((float)new_time_scale / framerate + 0.5); for(i = 0; i < file->total_vtracks; i++) { file->vtracks[i].track->mdia.mdhd.time_scale = new_time_scale; file->vtracks[i].track->mdia.minf.stbl.stts.table[0].sample_duration = new_sample_duration; }}/* Used for writing only */quicktime_trak_t* quicktime_add_track(quicktime_t *file) { quicktime_moov_t *moov = &(file->moov); quicktime_trak_t *trak; // for(i = moov->total_tracks; i > 0; i--) // moov->trak[i] = moov->trak[i - 1]; trak = moov->trak[moov->total_tracks] = calloc(1, sizeof(quicktime_trak_t)); quicktime_trak_init(trak, file->file_type); moov->trak[moov->total_tracks]->tkhd.track_id = moov->mvhd.next_track_id; moov->total_tracks++; moov->mvhd.next_track_id++; return trak; }/* ============================= Initialization functions */int quicktime_init(quicktime_t *file){ bzero(file, sizeof(quicktime_t));// quicktime_atom_write_header64(new_file, &file->mdat.atom, "mdat"); quicktime_moov_init(&(file->moov)); file->max_riff_size = 0x40000000; // file->color_model = BC_RGB888; return 0;}static int quicktime_delete(quicktime_t *file){ int i; if(file->total_atracks) { for(i = 0; i < file->total_atracks; i++) quicktime_delete_audio_map(&(file->atracks[i])); free(file->atracks); } if(file->total_vtracks) { for(i = 0; i < file->total_vtracks; i++) quicktime_delete_video_map(&(file->vtracks[i])); free(file->vtracks); } if(file->total_ttracks) { for(i = 0; i < file->total_ttracks; i++) lqt_delete_text_map(file, &(file->ttracks[i])); free(file->ttracks); } file->total_atracks = 0; file->total_vtracks = 0; if(file->moov_data) free(file->moov_data); if(file->preload_size) { free(file->preload_buffer); file->preload_size = 0; } if(file->presave_buffer) { free(file->presave_buffer); } for(i = 0; i < file->total_riffs; i++) { quicktime_delete_riff(file, file->riff[i]); } quicktime_moov_delete(&(file->moov)); quicktime_mdat_delete(&(file->mdat)); quicktime_ftyp_delete(&(file->ftyp)); return 0;}/* =============================== Optimization functions */int quicktime_set_cpus(quicktime_t *file, int cpus){ return 0;}void quicktime_set_preload(quicktime_t *file, int64_t preload){ file->preload_size = preload; if(file->preload_buffer) free(file->preload_buffer); file->preload_buffer = 0; if(preload) file->preload_buffer = calloc(1, preload); file->preload_start = 0; file->preload_end = 0; file->preload_ptr = 0;}int quicktime_get_timescale(double frame_rate){ int timescale = 600;/* Encode the 29.97, 23.976, 59.94 framerates */ if(frame_rate - (int)frame_rate != 0) timescale = (int)(frame_rate * 1001 + 0.5); else if((600 / frame_rate) - (int)(600 / frame_rate) != 0) timescale = (int)(frame_rate * 100 + 0.5); return timescale;}int quicktime_seek_start(quicktime_t *file){ int i; for(i = 0; i < file->total_atracks; i++) quicktime_set_audio_position(file, 0, i); for(i = 0; i < file->total_vtracks; i++) quicktime_set_video_position(file, 0, i); return 0;}long quicktime_audio_length(quicktime_t *file, int track){ if(file->total_atracks > 0) return file->atracks[track].total_samples; return 0;}long quicktime_video_length(quicktime_t *file, int track){/*printf("quicktime_video_length %d %d\n", quicktime_track_samples(file, file->vtracks[track].track), track); */ if(file->total_vtracks > 0) return quicktime_track_samples(file, file->vtracks[track].track); return 0;}long quicktime_audio_position(quicktime_t *file, int track){ return file->atracks[track].current_position;}long quicktime_video_position(quicktime_t *file, int track){ return file->vtracks[track].current_position;}int quicktime_set_audio_position(quicktime_t *file, int64_t sample, int track) { if((track >= 0) && (track < file->total_atracks)) { /* We just set the current position, Codec will do the rest */ file->atracks[track].current_position = sample; file->atracks[track].eof = 0; } else lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN, "quicktime_set_audio_position: track >= file->total_atracks\n"); return 0; }int quicktime_set_video_position(quicktime_t *file, int64_t frame, int track) { int64_t chunk_sample, chunk; quicktime_trak_t *trak; quicktime_codec_t * codec; if((track < 0) || (track >= file->total_vtracks)) return 0; trak = file->vtracks[track].track; if((frame < 0) || (frame >= quicktime_track_samples(file, trak))) return 0; file->vtracks[track].current_position = frame; quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, frame); file->vtracks[track].current_chunk = chunk; file->vtracks[track].timestamp = quicktime_sample_to_time(&(trak->mdia.minf.stbl.stts), frame, &(file->vtracks[track].stts_index), &(file->vtracks[track].stts_count)); /* Resync codec */ codec = (quicktime_codec_t*)(file->vtracks[track].codec); if(codec && codec->resync) codec->resync(file, track); return 0; }void lqt_seek_video(quicktime_t * file, int track, int64_t time) { int64_t frame; quicktime_trak_t *trak; if((track < 0) || (track >= file->total_vtracks)) return; trak = file->vtracks[track].track; file->vtracks[track].timestamp = time; frame = quicktime_time_to_sample(&(trak->mdia.minf.stbl.stts), &(file->vtracks[track].timestamp), &(file->vtracks[track].stts_index), &(file->vtracks[track].stts_count)); quicktime_set_video_position(file, frame, track); }#define FRAME_PADDING 128int lqt_read_video_frame(quicktime_t * file, uint8_t ** buffer, int * buffer_alloc, int64_t frame, int64_t * time, int track) { int64_t offset, chunk_sample, chunk; int result; quicktime_trak_t *trak; int len; if((track >= file->total_vtracks) || (track < 0)) return 0; trak = file->vtracks[track].track; if((frame < 0) || (frame >= quicktime_track_samples(file, trak))) return 0; // file->vtracks[track].current_position = frame; quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, frame); file->vtracks[track].current_chunk = chunk; offset = quicktime_sample_to_offset(file, trak, frame); quicktime_set_position(file, offset); if(time) *time = quicktime_sample_to_time(&(trak->mdia.minf.stbl.stts), frame, &(file->vtracks[track].stts_index), &(file->vtracks[track].stts_count)); len = quicktime_frame_size(file, frame, track); if(len + FRAME_PADDING > *buffer_alloc) { *buffer_alloc = len + FRAME_PADDING + 1024; *buffer = realloc(*buffer, *buffer_alloc); } result = quicktime_read_data(file, *buffer, len); if(result < len) { return 0; } memset(*buffer + len, 0, FRAME_PADDING); return len; }#undef FRAME_PADDINGint quicktime_has_audio(quicktime_t *file) { if(quicktime_audio_tracks(file)) return 1; return 0; }long quicktime_sample_rate(quicktime_t *file, int track) { if(file->total_atracks) return file->atracks[track].samplerate; return 0; }int quicktime_audio_bits(quicktime_t *file, int track){ if(file->total_atracks) return file->atracks[track].track->mdia.minf.stbl.stsd.table[0].sample_size; return 0;}char* quicktime_audio_compressor(quicktime_t *file, int track){ return file->atracks[track].track->mdia.minf.stbl.stsd.table[0].format;}int quicktime_track_channels(quicktime_t *file, int track){ if(track < file->total_atracks) return file->atracks[track].channels; return 0;}int quicktime_channel_location(quicktime_t *file, int *quicktime_track, int *quicktime_channel, int channel){ int current_channel = 0, current_track = 0; *quicktime_channel = 0; *quicktime_track = 0; for(current_channel = 0, current_track = 0; current_track < file->total_atracks; ) { if(channel >= current_channel) { *quicktime_channel = channel - current_channel; *quicktime_track = current_track; } current_channel += file->atracks[current_track].channels; current_track++; } return 0;}int quicktime_has_video(quicktime_t *file){ if(quicktime_video_tracks(file)) return 1; return 0;}int quicktime_video_width(quicktime_t *file, int track){// if(file->total_vtracks)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -