📄 lqt_quicktime.c
字号:
atrack->channels = trak->mdia.minf.stbl.stsd.table[0].channels; atrack->samplerate = (int)(trak->mdia.minf.stbl.stsd.table[0].samplerate + 0.5); atrack->current_position = 0; atrack->current_chunk = 1; if(!encode) { /* Set channel setup */ if(trak->mdia.minf.stbl.stsd.table[0].has_chan) quicktime_get_chan(atrack); } quicktime_init_acodec(atrack, encode, info); return 0; }int quicktime_delete_audio_map(quicktime_audio_map_t *atrack){ quicktime_delete_acodec(atrack); if(atrack->sample_buffer) free(atrack->sample_buffer); if(atrack->channel_setup) free(atrack->channel_setup); return 0;}// Initialize maps, for reading onlyvoid quicktime_init_maps(quicktime_t * file) { int i, j, k, dom, track; /* get tables for all the different tracks */ file->total_atracks = quicktime_audio_tracks(file); if(file->total_atracks) { file->atracks = calloc(1, sizeof(*file->atracks) * file->total_atracks); for(i = 0, track = 0; i < file->total_atracks; i++, track++) { while(!file->moov.trak[track]->mdia.minf.is_audio) track++; quicktime_init_audio_map(file, &(file->atracks[i]), file->moov.trak[track], file->wr, (lqt_codec_info_t*)0); /* Some codecs set the channel setup */ ((quicktime_codec_t*)file->atracks[i].codec)->decode_audio(file, (void*)0, 0, i); } } file->total_vtracks = quicktime_video_tracks(file); if(file->total_vtracks) { file->vtracks = calloc(1, sizeof(*file->vtracks) * file->total_vtracks); for(track = 0, i = 0; i < file->total_vtracks; i++, track++) { while(!file->moov.trak[track]->mdia.minf.is_video) track++; quicktime_init_video_map(&(file->vtracks[i]), file->moov.trak[track], file->wr, (lqt_codec_info_t*)0); /* Get decoder colormodel */ ((quicktime_codec_t*)file->vtracks[i].codec)->decode_video(file, (uint8_t**)0, i); file->vtracks[i].io_cmodel = file->vtracks[i].stream_cmodel; lqt_get_default_rowspan(file->vtracks[i].stream_cmodel, quicktime_video_width(file, i), &(file->vtracks[i].stream_row_span), &(file->vtracks[i].stream_row_span_uv)); /* Get interlace mode */ if((file->vtracks[i].interlace_mode == LQT_INTERLACE_NONE) && (file->vtracks[i].track->mdia.minf.stbl.stsd.table[0].has_fiel)) { dom = file->vtracks[i].track->mdia.minf.stbl.stsd.table[0].fiel.dominance; if (file->vtracks[i].track->mdia.minf.stbl.stsd.table[0].fiel.fields == 2) { if (dom == 14 || dom == 6) file->vtracks[i].interlace_mode = LQT_INTERLACE_BOTTOM_FIRST; else if (dom == 9 || dom == 1) file->vtracks[i].interlace_mode = LQT_INTERLACE_TOP_FIRST; } } /* Timecode track */ if(file->moov.trak[track]->has_tref) { for(j = 0; j < file->moov.trak[track]->tref.num_references; j++) { /* Track reference has type tmcd */ if(quicktime_match_32(file->moov.trak[track]->tref.references[j].type, "tmcd")) { for(k = 0; k < file->moov.total_tracks; k++) { if(file->moov.trak[track]->tref.references[j].tracks[0] == file->moov.trak[k]->tkhd.track_id) { file->vtracks[i].timecode_track = file->moov.trak[k]; break; } } break; } } } } } /* Text tracks */ file->total_ttracks = lqt_text_tracks(file); if(file->total_ttracks) { file->ttracks = calloc(file->total_ttracks, sizeof(*file->ttracks)); for(track = 0, i = 0; i < file->total_ttracks; i++, track++) { while(!file->moov.trak[track]->mdia.minf.is_text) track++; lqt_init_text_map(file, &file->ttracks[i], file->moov.trak[track], 0); } } }int quicktime_read_info(quicktime_t *file){ int result = 0, got_header = 0; int64_t start_position = quicktime_position(file); quicktime_atom_t leaf_atom; uint8_t avi_avi[4]; int got_avi = 0; quicktime_set_position(file, 0LL); /* Test file format */ do { file->file_type = LQT_FILE_AVI; result = quicktime_atom_read_header(file, &leaf_atom); if(!result && quicktime_atom_is(&leaf_atom, "RIFF")) { quicktime_read_data(file, avi_avi, 4); if(quicktime_match_32(avi_avi, "AVI ")) { got_avi = 1; } else { result = 0; break; } } else { result = 0; break; } }while(1); if(!got_avi) file->file_type = LQT_FILE_NONE; quicktime_set_position(file, 0LL); /* McRoweSoft AVI section */ if(file->file_type == LQT_FILE_AVI) {/* Import first RIFF */ do { result = quicktime_atom_read_header(file, &leaf_atom); if(!result) { if(quicktime_atom_is(&leaf_atom, "RIFF")) { quicktime_read_riff(file, &leaf_atom);/* Return success */ got_header = 1; } } }while(!result && !got_header && quicktime_position(file) < file->total_length); /* Construct indexes. */ if(quicktime_import_avi(file)) return 1; }/* Quicktime section */ else if(!(file->file_type & (LQT_FILE_AVI|LQT_FILE_AVI_ODML))) { 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, "ftyp")) { quicktime_read_ftyp(file, &file->ftyp, &leaf_atom); file->file_type = quicktime_ftyp_get_file_type(&file->ftyp); file->has_ftyp = 1; } else if(quicktime_atom_is(&leaf_atom, "moov")) {/* Set preload and preload the moov atom here */ int64_t start_position = quicktime_position(file); long temp_size = leaf_atom.end - start_position; unsigned char *temp = malloc(temp_size); quicktime_set_preload(file, (temp_size < 0x100000) ? 0x100000 : temp_size); quicktime_read_data(file, temp, temp_size); quicktime_set_position(file, start_position); free(temp); quicktime_read_moov(file, &(file->moov), &leaf_atom); got_header = 1; } else quicktime_atom_skip(file, &leaf_atom); } }while(!result && quicktime_position(file) < file->total_length); /* read QTVR sample atoms -- object */ if (lqt_qtvr_get_object_track(file) >= 0) { quicktime_qtatom_t leaf_atom, root_atom; int64_t start_position = quicktime_position(file); quicktime_set_position(file, file->moov.trak[lqt_qtvr_get_object_track(file)]->mdia.minf.stbl.stco.table[0].offset); quicktime_qtatom_read_container_header(file); /* root qtatom "sean" */ quicktime_qtatom_read_header(file, &root_atom); do { quicktime_qtatom_read_header(file, &leaf_atom); if(quicktime_qtatom_is(&leaf_atom, "obji")) { quicktime_read_obji(file, &file->qtvr_node[0].obji); } else if(quicktime_qtatom_is(&leaf_atom, "ndhd")) { quicktime_read_ndhd(file, &file->qtvr_node[0].ndhd); } else quicktime_qtatom_skip(file, &leaf_atom); } while(quicktime_position(file) < root_atom.end); quicktime_set_position(file, start_position); } /* read QTVR sample atoms -- panorama */ if (lqt_qtvr_get_panorama_track(file) >= 0 && lqt_qtvr_get_qtvr_track(file) >= 0) { quicktime_qtatom_t leaf_atom, root_atom; int64_t start_position = quicktime_position(file); quicktime_set_position(file, file->moov.trak[lqt_qtvr_get_panorama_track(file)]->mdia.minf.stbl.stco.table[0].offset); quicktime_qtatom_read_container_header(file); /* root qtatom "sean" */ quicktime_qtatom_read_header(file, &root_atom); do { quicktime_qtatom_read_header(file, &leaf_atom); if(quicktime_qtatom_is(&leaf_atom, "pdat")) { quicktime_read_pdat(file, &file->qtvr_node[0].pdat); } else if(quicktime_qtatom_is(&leaf_atom, "ndhd")) { quicktime_read_ndhd(file, &file->qtvr_node[0].ndhd); } else quicktime_qtatom_skip(file, &leaf_atom); } while(quicktime_position(file) < root_atom.end); quicktime_set_position(file, start_position); } if (lqt_qtvr_get_qtvr_track(file) >= 0) { quicktime_qtatom_t leaf_atom, root_atom; int64_t start_position = quicktime_position(file); quicktime_set_position(file, file->moov.trak[lqt_qtvr_get_qtvr_track(file)]->mdia.minf.stbl.stco.table[0].offset); quicktime_qtatom_read_container_header(file); /* root qtatom "sean" */ quicktime_qtatom_read_header(file, &root_atom); do { quicktime_qtatom_read_header(file, &leaf_atom); if(quicktime_qtatom_is(&leaf_atom, "ndhd")) { quicktime_read_ndhd(file, &file->qtvr_node[0].ndhd); } else quicktime_qtatom_skip(file, &leaf_atom); } while(quicktime_position(file) < root_atom.end); quicktime_set_position(file, start_position); }/* go back to the original position */ quicktime_set_position(file, start_position); } /* Initialize track map objects */ if(got_header) { quicktime_init_maps(file); } /* Set file type if no ftyp is there */ if(file->file_type == LQT_FILE_NONE) file->file_type = LQT_FILE_QT_OLD; /* Shut down preload in case of an obsurdly high temp_size */ quicktime_set_preload(file, 0); return !got_header;}int quicktime_dump(quicktime_t *file){ lqt_dump("quicktime_dump\n"); if(file->has_ftyp) quicktime_ftyp_dump(&(file->ftyp)); lqt_dump("movie data (mdat)\n"); lqt_dump(" size %"PRId64"\n", file->mdat.atom.size); lqt_dump(" start %"PRId64"\n", file->mdat.atom.start); quicktime_moov_dump(&(file->moov)); if (lqt_qtvr_get_object_track(file) >= 0) { quicktime_obji_dump(&(file->qtvr_node[0].obji)); } if (lqt_qtvr_get_panorama_track(file) >= 0) { quicktime_pdat_dump(&(file->qtvr_node[0].pdat)); } if (lqt_qtvr_get_qtvr_track(file) >= 0) { quicktime_ndhd_dump(&(file->qtvr_node[0].ndhd)); } if(file->file_type & (LQT_FILE_AVI | LQT_FILE_AVI_ODML)) { quicktime_riff_dump(file->riff[0]); } return 0;}// ================================== Entry points =============================int quicktime_check_sig(char *path){ quicktime_t file; quicktime_atom_t leaf_atom; int result = 0, result1 = 0, result2 = 0; uint8_t avi_test[12]; quicktime_init(&file); result = quicktime_file_open(&file, path, 1, 0); if(!result) {// Check for Microsoft AVI quicktime_read_data(&file, avi_test, 12); quicktime_set_position(&file, 0); if(quicktime_match_32(avi_test, "RIFF") && quicktime_match_32(avi_test + 8, "AVI ")) { result2 = 1; } else { 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); } } quicktime_file_close(&file); quicktime_delete(&file); return result2;}void quicktime_set_avi(quicktime_t *file, int value) { if(value) file->file_type = LQT_FILE_AVI_ODML; }#if 0 static int quicktime_is_avi(quicktime_t *file){return !!(file->file_type & (LQT_FILE_AVI|LQT_FILE_AVI_ODML));}#endifstatic quicktime_t* do_open(const char *filename, int rd, int wr, lqt_file_type_t type, lqt_log_callback_t log_cb, void * log_data){ int i; quicktime_t *new_file; int result = 0; new_file = calloc(1, sizeof(*new_file)); new_file->log_callback = log_cb; new_file->log_data = log_data; if(rd && wr) { lqt_log(new_file, LQT_LOG_ERROR, LOG_DOMAIN, "read/write mode is not supported");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -