📄 quicktime.c
字号:
quicktime_mdat_delete(&(file->mdat)); return 0;}/* =============================== Optimization functions */int quicktime_set_cpus(quicktime_t *file, int cpus){ if(cpus > 0) file->cpus = cpus; return 0;}int quicktime_set_preload(quicktime_t *file, long preload){ if(!file->preload_size) { file->preload_size = preload; file->preload_buffer = calloc(1, preload); file->preload_start = 0; file->preload_end = 0; file->preload_ptr = 0; }}int quicktime_get_timescale(float frame_rate){ int timescale = 600;/* Encode the 29.97, 23.976, 59.94 framerates as per DV freaks */ 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_end(quicktime_t *file){ quicktime_set_position(file, file->mdat.size + file->mdat.start);/*printf("quicktime_seek_end %ld\n", file->mdat.size + file->mdat.start); */ quicktime_update_positions(file); return 0;}int quicktime_seek_start(quicktime_t *file){ quicktime_set_position(file, file->mdat.start + HEADER_LENGTH); quicktime_update_positions(file); return 0;}long quicktime_audio_length(quicktime_t *file, int track){ if(file->total_atracks > 0) return quicktime_track_samples(file, file->atracks[track].track); 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_update_positions(quicktime_t *file){/* Used for routines that change the positions of all tracks, like *//* seek_end and seek_start but not for routines that reposition one track, like *//* set_audio_position. */ long mdat_offset = quicktime_position(file) - file->mdat.start; long sample, chunk, chunk_offset; int i; if(file->total_atracks) { sample = quicktime_offset_to_sample(file->atracks[0].track, mdat_offset); chunk = quicktime_offset_to_chunk(&chunk_offset, file->atracks[0].track, mdat_offset); for(i = 0; i < file->total_atracks; i++) { file->atracks[i].current_position = sample; file->atracks[i].current_chunk = chunk; } } if(file->total_vtracks) { sample = quicktime_offset_to_sample(file->vtracks[0].track, mdat_offset); chunk = quicktime_offset_to_chunk(&chunk_offset, file->vtracks[0].track, mdat_offset); for(i = 0; i < file->total_vtracks; i++) { file->vtracks[i].current_position = sample; file->vtracks[i].current_chunk = chunk; } } return 0;}int quicktime_set_audio_position(quicktime_t *file, long sample, int track){ long offset, chunk_sample, chunk; quicktime_trak_t *trak; if(file->total_atracks) { trak = file->atracks[track].track; file->atracks[track].current_position = sample; quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, sample); file->atracks[track].current_chunk = chunk; offset = quicktime_sample_to_offset(trak, sample); quicktime_set_position(file, offset); /*quicktime_update_positions(file); */ } return 0;}int quicktime_set_video_position(quicktime_t *file, long frame, int track){ long offset, chunk_sample, chunk; quicktime_trak_t *trak; if(file->total_vtracks) { trak = file->vtracks[track].track; 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(trak, frame); quicktime_set_position(file, offset); /*quicktime_update_positions(file); */ } return 0;}int quicktime_has_audio(quicktime_t *file){ if(quicktime_audio_tracks(file)) return 1; return 0;}long quicktime_audio_sample_rate(quicktime_t *file, int track){ if(file->total_atracks) return file->atracks[track].track->mdia.minf.stbl.stsd.table[0].sample_rate; 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;}int quicktime_audio_time_scale(quicktime_t *file, int track){ if(file->total_atracks) { return file->atracks[track].track->mdia.mdhd.time_scale; } return 0;}int quicktime_audio_sample_duration(quicktime_t *file, int track){ if(file->total_atracks) { return file->atracks[track].track->mdia.minf.stbl.stts.table[0].sample_duration; } return 0;}char* quicktime_audio_compressor(quicktime_t *file, int track){ if (file->atracks[track].track == NULL) return (NULL); 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) { int width = file->vtracks[track].track->mdia.minf.stbl.stsd.table[0].width; if (width) { return width; } return file->vtracks[track].track->tkhd.track_width; } return 0;}int quicktime_video_height(quicktime_t *file, int track){ if(file->total_vtracks) { int height = file->vtracks[track].track->mdia.minf.stbl.stsd.table[0].height; if (height) { return height; } return file->vtracks[track].track->tkhd.track_height; } return 0;}int quicktime_video_depth(quicktime_t *file, int track){ if(file->total_vtracks) return file->vtracks[track].track->mdia.minf.stbl.stsd.table[0].depth; return 0;}int quicktime_set_depth(quicktime_t *file, int depth, int track){ int i; for(i = 0; i < file->total_vtracks; i++) { file->vtracks[i].track->mdia.minf.stbl.stsd.table[0].depth = depth; }}float quicktime_video_frame_rate(quicktime_t *file, int track){ float ret = 0; int num = 0; if(file->total_vtracks) { ret = file->vtracks[track].track->mdia.mdhd.time_scale; if (file->vtracks[track].track->mdia.minf.stbl.stts.table[0].sample_duration == 0) num = 1; ret /= file->vtracks[track].track->mdia.minf.stbl.stts.table[num].sample_duration; } return ret;}char* quicktime_video_compressor(quicktime_t *file, int track){ if (file->vtracks[track].track == NULL) return (NULL); return file->vtracks[track].track->mdia.minf.stbl.stsd.table[0].format;}int quicktime_video_time_scale(quicktime_t *file, int track){ if(file->total_vtracks) { return file->vtracks[track].track->mdia.mdhd.time_scale; } return 0;}int quicktime_video_frame_time(quicktime_t *file, int track, long frame, long *start, int *duration){ quicktime_stts_t *stts; int i; long f; if (file->total_vtracks == 0) { return 0; } stts = &(file->vtracks[track].track->mdia.minf.stbl.stts); if (frame < file->last_frame) { /* we need to reset our cached values */ file->last_frame = 0; file->last_start = 0; file->last_stts_index = 0; } i = file->last_stts_index; f = file->last_frame; *start = file->last_start; while (i < stts->total_entries) { if (f + stts->table[i].sample_count <= frame) { *start += stts->table[i].sample_duration * stts->table[i].sample_count; f += stts->table[i].sample_count; i++; } else { /* cache the results for future use */ file->last_stts_index = i; file->last_frame = f; file->last_start = *start; *start += stts->table[i].sample_duration * (frame - f); *duration = stts->table[i].sample_duration; return 1; } } /* error */ return 0;}int quicktime_get_mp4_video_decoder_config(quicktime_t *file, int track, u_char** ppBuf, int* pBufSize){ quicktime_esds_t* esds; if (!file->total_vtracks) { return 0; } esds = &file->vtracks[track].track->mdia.minf.stbl.stsd.table[0].esds; return quicktime_esds_get_decoder_config(esds, ppBuf, pBufSize);}int quicktime_set_mp4_video_decoder_config(quicktime_t *file, int track, u_char* pBuf, int bufSize){ quicktime_esds_t* esds; if (!file->total_vtracks) { return 0; } esds = &file->vtracks[track].track->mdia.minf.stbl.stsd.table[0].esds; return quicktime_esds_set_decoder_config(esds, pBuf, bufSize);}int quicktime_get_mp4_audio_decoder_config(quicktime_t *file, int track, u_char** ppBuf, int* pBufSize){ quicktime_esds_t* esds; if (!file->total_atracks) { return 0; } esds = &file->atracks[track].track->mdia.minf.stbl.stsd.table[0].esds; return quicktime_esds_get_decoder_config(esds, ppBuf, pBufSize);}int quicktime_set_mp4_audio_decoder_config(quicktime_t *file, int track, u_char* pBuf, int bufSize){ quicktime_esds_t* esds; if (!file->total_atracks) { return 0; } esds = &file->atracks[track].track->mdia.minf.stbl.stsd.table[0].esds; return quicktime_esds_set_decoder_config(esds, pBuf, bufSize);}long quicktime_samples_to_bytes(quicktime_trak_t *track, long samples){ return samples * track->mdia.minf.stbl.stsd.table[0].channels * track->mdia.minf.stbl.stsd.table[0].sample_size / 8;}int quicktime_write_audio(quicktime_t *file, char *audio_buffer, long samples, int track){ long offset; int result; long bytes;/* Defeat 32 bit file size limit. */ if(quicktime_test_position(file)) return 1;/* write chunk for 1 track */ bytes = samples * quicktime_audio_bits(file, track) / 8 * file->atracks[track].channels; offset = quicktime_position(file); result = quicktime_write_data(file, audio_buffer, bytes); if(result) result = 0; else result = 1; /* defeat fwrite's return */ quicktime_update_tables(file, file->atracks[track].track, offset, file->atracks[track].current_chunk, file->atracks[track].current_position, samples, 0, 0, 0, 0); file->atracks[track].current_position += samples; file->atracks[track].current_chunk++; return result;}int quicktime_write_audio_frame(quicktime_t *file, unsigned char *audio_buffer, long bytes, int track){ long offset = quicktime_position(file); int result = 0; /* Defeat 32 bit file size limit. */ if(quicktime_test_position(file)) return 1; result = quicktime_write_data(file, audio_buffer, bytes); if(result) result = 0; else result = 1; quicktime_update_tables(file, file->atracks[track].track, offset, file->atracks[track].current_chunk, file->atracks[track].current_position, 1, bytes, 0, 0, 0); file->atracks[track].current_position += 1; file->atracks[track].current_chunk++; return result;}int quicktime_write_video_frame(quicktime_t *file, unsigned char *video_buffer, long bytes, int track, u_char isKeyFrame, long duration, long renderingOffset){ long offset = quicktime_position(file); int result = 0; /* Defeat 32 bit file size limit. */ if(quicktime_test_position(file)) return 1; result = quicktime_write_data(file, video_buffer, bytes); if(result) result = 0; else result = 1; quicktime_update_tables(file, file->vtracks[track].track, offset, file->vtracks[track].current_chunk, file->vtracks[track].current_position, 1, bytes, duration, isKeyFrame, renderingOffset); file->vtracks[track].current_position += 1; file->vtracks[track].current_chunk++; return result;}static int quicktime_write_media_hint(quicktime_t* file, u_char* hintBuffer, long hintBufferSize, quicktime_trak_t* hintTrak, long* pSampleNumber, long hintSampleDuration, u_char isSyncSample){ long offset = quicktime_position(file); quicktime_hint_info_t hintInfo; int result = 0; /* handle 32 bit file size limit */ if (quicktime_test_position(file)) { return 1; } /* get info about this hint */ quicktime_get_hint_info(hintBuffer, hintBufferSize, &hintInfo); /* update overall info */ hintTrak->hint_udta.hinf.trpy.numBytes += hintInfo.trpy; hintTrak->hint_udta.hinf.nump.numPackets += hintInfo.nump; hintTrak->hint_udta.hinf.tpyl.numBytes += hintInfo.tpyl; hintTrak->hint_udta.hinf.dmed.numBytes += hintInfo.dmed; hintTrak->hint_udta.hinf.drep.numBytes += hintInfo.drep; hintTrak->hint_udta.hinf.dimm.numBytes += hintInfo.dimm; hintTrak->hint_udta.hinf.tmin.milliSecs = MAX(hintInfo.tmin, hintTrak->hint_udta.hinf.tmin.milliSecs); hintTrak->hint_udta.hinf.tmax.milliSecs = MAX(hintInfo.tmax, hintTrak->hint_udta.hinf.tmax.milliSecs); hintTrak->hint_udta.hinf.pmax.numBytes = MAX(hintInfo.pmax, hintTrak->hint_udta.hinf.pmax.numBytes); hintTrak->mdia.minf.hmhd.maxPDUsize = hintTrak->hint_udta.hinf.pmax.numBytes; hintTrak->mdia.minf.hmhd.avgPDUsize = hintTrak->hint_udta.hinf.trpy.numBytes / hintTrak->hint_udta.hinf.nump.numPackets; /* write the hint data */ result = quicktime_write_data(file, hintBuffer, hintBufferSize); result = (result ? 0 : 1); quicktime_update_tables(file, hintTrak, offset, *pSampleNumber + 1, *pSampleNumber, 1, hintBufferSize, hintSampleDuration, isSyncSample, 0); (*pSampleNumber)++; return result;}int quicktime_write_audio_hint(quicktime_t *file, unsigned char *hintBuffer, long hintBufferSize, int audioTrack, int hintTrack, long hintSampleDuration){ quicktime_trak_t* hintTrak = file->atracks[audioTrack].hintTracks[hintTrack]; return quicktime_write_media_hint(file, hintBuffer, hintBufferSize, hintTrak, &(file->atracks[audioTrack].hintPositions[hintTrack]), hintSampleDuration, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -