📄 lqt_quicktime.c
字号:
free(new_file); return (quicktime_t*)0; } quicktime_init(new_file); new_file->wr = wr; new_file->rd = rd; new_file->mdat.atom.start = 0; if(wr) { new_file->file_type = type; quicktime_ftyp_init(&new_file->ftyp, type); if(new_file->ftyp.major_brand) new_file->has_ftyp = 1; /* Switch the iods atom on for MP4 */ if(new_file->file_type & LQT_FILE_MP4) new_file->moov.has_iods = 1; } result = quicktime_file_open(new_file, filename, rd, wr); if(!result) { if(rd) { if(quicktime_read_info(new_file)) { lqt_log(new_file, LQT_LOG_ERROR, LOG_DOMAIN, "Opening failed (unsupported filetype)"); quicktime_close(new_file); new_file = 0; } } /* start the data atom */ /* also don't want to do this if making a streamable file */ if(wr) { if(new_file->has_ftyp) quicktime_write_ftyp(new_file, &(new_file->ftyp)); quicktime_atom_write_header64(new_file, &new_file->mdat.atom, "mdat"); } } else { /* If the open failed due to permission or path errors then there * may not be a file pointer allocated and attempting to close will * coredump due to a NULL pointer dereference. */ if (new_file->stream) quicktime_close(new_file); else free(new_file); new_file = 0; } if(rd && new_file) { /* Set default decoding parameters */ for(i = 0; i < new_file->total_atracks; i++) lqt_set_default_audio_parameters(new_file, i); for(i = 0; i < new_file->total_vtracks; i++) lqt_set_default_video_parameters(new_file, i); } return new_file;}quicktime_t* quicktime_open(const char *filename, int rd, int wr) { return do_open(filename, rd, wr, LQT_FILE_QT_OLD, NULL, NULL); }quicktime_t * lqt_open_read(const char * filename) { return do_open(filename, 1, 0, LQT_FILE_NONE, NULL, NULL); }quicktime_t * lqt_open_write(const char * filename, lqt_file_type_t type) { return do_open(filename, 0, 1, type, NULL, NULL); }quicktime_t * lqt_open_read_with_log(const char * filename, lqt_log_callback_t cb, void * log_data) { return do_open(filename, 1, 0, LQT_FILE_NONE, cb, log_data); }quicktime_t * lqt_open_write_with_log(const char * filename, lqt_file_type_t type, lqt_log_callback_t cb, void * log_data) { return do_open(filename, 0, 1, type, cb, log_data); }int quicktime_close(quicktime_t *file) { int i; int result = 0; if(file->wr) { quicktime_codecs_flush(file); if(file->file_type & (LQT_FILE_AVI|LQT_FILE_AVI_ODML)) {#if 0 quicktime_atom_t junk_atom; int64_t position = quicktime_position(file);#endif // total_riffs is 0 if no A/V frames have been written if(file->total_riffs) { // Finalize last header quicktime_finalize_riff(file, file->riff[file->total_riffs - 1]); // Finalize the odml header quicktime_finalize_odml(file, &file->riff[0]->hdrl); if(file->file_type == LQT_FILE_AVI_ODML) { for(i = 0; i < file->moov.total_tracks; i++) { quicktime_finalize_indx(file, &file->moov.trak[i]->strl->indx); } } } } else { if (lqt_qtvr_get_object_track(file) >= 0) { lqt_qtvr_add_object_node(file); } else if (lqt_qtvr_get_panorama_track(file) >= 0) { lqt_qtvr_add_panorama_node(file); } // Atoms are only written here quicktime_atom_write_footer(file, &file->mdat.atom); quicktime_finalize_moov(file, &(file->moov)); quicktime_write_moov(file, &(file->moov)); } } quicktime_file_close(file); quicktime_delete(file); free(file); return result; }/* * Apply default parameters for a codec */static void apply_default_parameters(quicktime_t * file, int track, quicktime_codec_t * codec, lqt_codec_info_t * codec_info, int encode) { int num_parameters; lqt_parameter_info_t * parameter_info; int j; if(encode) { num_parameters = codec_info->num_encoding_parameters; parameter_info = codec_info->encoding_parameters; } else { num_parameters = codec_info->num_decoding_parameters; parameter_info = codec_info->decoding_parameters; } for(j = 0; j < num_parameters; j++) { switch(parameter_info[j].type) { case LQT_PARAMETER_INT: lqt_log(file, LQT_LOG_DEBUG, LOG_DOMAIN, "Setting parameter %s to %d", parameter_info[j].name, parameter_info[j].val_default.val_int); codec->set_parameter(file, track, parameter_info[j].name, &(parameter_info[j].val_default.val_int)); break; case LQT_PARAMETER_FLOAT: lqt_log(file, LQT_LOG_DEBUG, LOG_DOMAIN, "Setting parameter %s to %f", parameter_info[j].name, parameter_info[j].val_default.val_float); codec->set_parameter(file, track, parameter_info[j].name, &(parameter_info[j].val_default.val_float)); break; case LQT_PARAMETER_STRING: case LQT_PARAMETER_STRINGLIST: lqt_log(file, LQT_LOG_DEBUG, LOG_DOMAIN, "Setting parameter %s to %s", parameter_info[j].name, parameter_info[j].val_default.val_string); codec->set_parameter(file, track, parameter_info[j].name, parameter_info[j].val_default.val_string); break; case LQT_PARAMETER_SECTION: break; /* NOP */ } } }void lqt_set_default_video_parameters(quicktime_t * file, int track) { lqt_codec_info_t ** codec_info; quicktime_codec_t * codec; codec = (quicktime_codec_t*)(file->vtracks[track].codec); codec_info = lqt_find_video_codec_by_name(codec->codec_name); if(codec_info) { apply_default_parameters(file, track, codec, *codec_info, file->wr); lqt_destroy_codec_info(codec_info); } } void lqt_set_default_audio_parameters(quicktime_t * file, int track) { int i; lqt_codec_info_t ** codec_info; quicktime_codec_t * codec; for(i = 0; i < file->total_atracks; i++) { codec = (quicktime_codec_t*)(file->atracks[i].codec); codec_info = lqt_find_audio_codec_by_name(codec->codec_name); if(codec_info) { apply_default_parameters(file, i, codec, *codec_info, file->wr); lqt_destroy_codec_info(codec_info); } } }int quicktime_major(){ return QUICKTIME_MAJOR;}int quicktime_minor(){ return QUICKTIME_MINOR;}int quicktime_release(){ return QUICKTIME_RELEASE;}int quicktime_div3_is_key(unsigned char *data, long size) { int result = 0;// First 2 bits are pict type. result = (data[0] & 0xc0) == 0; return result; }/* * AVI Specific stuff */int lqt_is_avi(quicktime_t *file) { return (file->file_type & (LQT_FILE_AVI|LQT_FILE_AVI_ODML)); }int lqt_get_wav_id(quicktime_t *file, int track) { quicktime_trak_t * trak; trak = file->atracks[track].track; return trak->mdia.minf.stbl.stsd.table[0].compression_id; }int64_t * lqt_get_chunk_sizes(quicktime_t * file, quicktime_trak_t *trak) { int i, j; int64_t * ret; int64_t next_offset; long num_chunks; int num_tracks; int * chunk_indices; num_chunks = trak->mdia.minf.stbl.stco.total_entries; ret = calloc(num_chunks, sizeof(int64_t)); num_tracks = file->moov.total_tracks; chunk_indices = malloc(num_tracks * sizeof(int)); for(i = 0; i < num_tracks; i++) { chunk_indices[i] = 0; } for(i = 0; i < num_chunks; i++) { next_offset = -1; for(j = 0; j < num_tracks; j++) { if(chunk_indices[j] < 0) continue; while(file->moov.trak[j]->mdia.minf.stbl.stco.table[chunk_indices[j]].offset <= trak->mdia.minf.stbl.stco.table[i].offset) { if(chunk_indices[j] >= file->moov.trak[j]->mdia.minf.stbl.stco.total_entries - 1) { chunk_indices[j] = -1; break; } else chunk_indices[j]++; } if(chunk_indices[j] < 0) continue; if((next_offset == -1) || (file->moov.trak[j]->mdia.minf.stbl.stco.table[chunk_indices[j]].offset < next_offset)) next_offset = file->moov.trak[j]->mdia.minf.stbl.stco.table[chunk_indices[j]].offset; } if(next_offset > 0) { ret[i] = next_offset - trak->mdia.minf.stbl.stco.table[i].offset; } else /* Last chunk: Take the end of the mdat atom */ { ret[i] = file->mdat.atom.start + file->mdat.atom.size - trak->mdia.minf.stbl.stco.table[i].offset; if(ret[i] < 0) ret[i] = 0; } } free(chunk_indices); return ret; }int lqt_read_audio_chunk(quicktime_t * file, int track, long chunk, uint8_t ** buffer, int * buffer_alloc, int * samples) { int64_t offset; quicktime_trak_t * trak; int result; trak = file->atracks[track].track; if(chunk > trak->mdia.minf.stbl.stco.total_entries) { /* Read beyond EOF */ file->atracks[track].eof = 1; return 0; } if(!trak->chunk_sizes) { trak->chunk_sizes = lqt_get_chunk_sizes(file, trak); } if(samples) *samples = quicktime_chunk_samples(trak, chunk); /* Reallocate buffer */ if(*buffer_alloc < trak->chunk_sizes[chunk-1] + 16) { *buffer_alloc = trak->chunk_sizes[chunk-1] + 32; *buffer = realloc(*buffer, *buffer_alloc); } /* Get offset */ offset = quicktime_chunk_to_offset(file, trak, chunk); quicktime_set_position(file, offset); result = quicktime_read_data(file, *buffer, trak->chunk_sizes[chunk-1]); memset((*buffer) + trak->chunk_sizes[chunk-1], 0, 16); return result ? trak->chunk_sizes[chunk-1] : 0; }int lqt_append_audio_chunk(quicktime_t * file, int track, long chunk, uint8_t ** buffer, int * buffer_alloc, int initial_bytes) { int64_t offset; quicktime_trak_t * trak; int result; trak = file->atracks[track].track; if(chunk > trak->mdia.minf.stbl.stco.total_entries) { /* Read beyond EOF */ file->atracks[track].eof = 1; return 0; } if(!trak->chunk_sizes) { trak->chunk_sizes = lqt_get_chunk_sizes(file, trak); } /* Reallocate buffer */ if(*buffer_alloc < trak->chunk_sizes[chunk-1] + 16 + initial_bytes) { *buffer_alloc = trak->chunk_sizes[chunk-1] + 32 + initial_bytes; *buffer = realloc(*buffer, *buffer_alloc); } /* Get offset */ offset = quicktime_chunk_to_offset(file, trak, chunk); quicktime_set_position(file, offset); result = quicktime_read_data(file, (*buffer) + initial_bytes, trak->chunk_sizes[chunk-1]); memset((*buffer) + initial_bytes + trak->chunk_sizes[chunk-1], 0, 16); return result ? trak->chunk_sizes[chunk-1] : 0; }int64_t lqt_last_audio_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -