📄 lqt_quicktime.c
字号:
/******************************************************************************* lqt_quicktime.c libquicktime - A library for reading and writing quicktime/avi/mp4 files. http://libquicktime.sourceforge.net Copyright (C) 2002 Heroine Virtual Ltd. Copyright (C) 2002-2007 Members of the libquicktime project. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*******************************************************************************/ #include "lqt_private.h"#include "lqt_fseek.h"#include <quicktime/colormodels.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <strings.h>#include <errno.h>#define LQT_LIBQUICKTIME#include <quicktime/lqt_codecapi.h>#define LOG_DOMAIN "core"static int64_t get_file_length(quicktime_t *file){ int64_t current_pos, total_bytes; current_pos = ftello(file->stream); fseeko(file->stream, 0, SEEK_END); total_bytes = ftello(file->stream); fseeko(file->stream, current_pos, SEEK_CUR); return total_bytes;}int lqt_fileno(quicktime_t *file) { FILE *fp; fp = file->stream; return(fileno(fp)); }int quicktime_make_streamable(char *in_path, char *out_path){ quicktime_t file, *old_file, new_file; int moov_exists = 0, mdat_exists = 0, ftyp_exists = 0, result, atoms = 1; int64_t mdat_start = 0, mdat_size = 0; quicktime_atom_t leaf_atom; int64_t moov_length = 0, moov_start; memset(&new_file,0,sizeof(new_file)); quicktime_init(&file);/* find the moov atom in the old file */ if(!(file.stream = fopen(in_path, "rb"))) { perror("quicktime_make_streamable"); return 1; } file.total_length = get_file_length(&file);/* get the locations of moov and mdat atoms */ do { result = quicktime_atom_read_header(&file, &leaf_atom); if(!result) { if(quicktime_atom_is(&leaf_atom, "moov")) { moov_exists = atoms; moov_length = leaf_atom.size; } else if(quicktime_atom_is(&leaf_atom, "ftyp")) { ftyp_exists = atoms; } else if(quicktime_atom_is(&leaf_atom, "mdat")) { mdat_start = quicktime_position(&file) - HEADER_LENGTH; mdat_size = leaf_atom.size; mdat_exists = atoms; } quicktime_atom_skip(&file, &leaf_atom); atoms++; } }while(!result && quicktime_position(&file) < file.total_length); fclose(file.stream); if(!moov_exists) { lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN, "quicktime_make_streamable: no moov atom"); return 1; } if(!mdat_exists) { lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN, "quicktime_make_streamable: no mdat atom"); return 1; }/* copy the old file to the new file */ if(moov_exists && mdat_exists) {/* moov comes after mdat */ if(moov_exists > mdat_exists) { uint8_t *buffer; int64_t buf_size = 1000000; result = 0;/* read the header proper */ if(!(old_file = quicktime_open(in_path, 1, 0))) { return 1; } quicktime_shift_offsets(&(old_file->moov), moov_length+8);/* open the output file */ if(!(new_file.stream = fopen(out_path, "wb"))) { lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN, "quicktime_make_streamable: cannot open output file: %s", strerror(errno)); result = 1; } else {/* set up some flags */ new_file.wr = 1; new_file.rd = 0; new_file.presave_buffer = calloc(1, QUICKTIME_PRESAVE); new_file.file_type = old_file->file_type; if(old_file->has_ftyp) quicktime_write_ftyp(&new_file, &(old_file->ftyp)); moov_start = quicktime_position(&new_file); quicktime_write_moov(&new_file, &(old_file->moov)); if(moov_length != quicktime_position(&new_file) - moov_start) { lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN, "quicktime_make_streamable: moov size changed from %"PRId64" to %"PRId64" (Pos: %"PRId64", start: %"PRId64")", moov_length, quicktime_position(&new_file) - moov_start, quicktime_position(&new_file), moov_start); quicktime_set_position(&new_file, moov_start + moov_length); } quicktime_atom_write_header64(&new_file, &(new_file.mdat.atom), "mdat"); quicktime_set_position(old_file, mdat_start); if(!(buffer = calloc(1, buf_size))) { result = 1; printf("quicktime_make_streamable: out of memory\n"); } else { while(quicktime_position(old_file) < mdat_start +mdat_size && !result) { if(quicktime_position(old_file) + buf_size >mdat_start + mdat_size) buf_size = mdat_start + mdat_size -quicktime_position(old_file); if(!quicktime_read_data(old_file, buffer, buf_size))result = 1; if(!result) { if(!quicktime_write_data(&new_file, buffer,buf_size)) result = 1; } } free(buffer); } quicktime_atom_write_footer(&new_file, &(new_file.mdat.atom)); if(new_file.presave_size) { quicktime_fseek(&new_file,new_file.presave_position - new_file.presave_size); fwrite(new_file.presave_buffer, 1,new_file.presave_size, new_file.stream); new_file.presave_size = 0; } free(new_file.presave_buffer); fclose(new_file.stream); } quicktime_close(old_file); } else { printf("quicktime_make_streamable: header already at 0 offset\n"); return 0; } } return 0;}void lqt_set_audio_parameter(quicktime_t *file,int stream, const char *key, const void *value) { quicktime_codec_t *codec = (quicktime_codec_t*)file->atracks[stream].codec; if(codec->set_parameter) codec->set_parameter(file, stream, key, value); }void lqt_set_video_parameter(quicktime_t *file,int stream, const char *key, const void *value) { quicktime_codec_t *codec = (quicktime_codec_t*)file->vtracks[stream].codec; if(codec->set_parameter) codec->set_parameter(file, stream, key, value); }void quicktime_set_parameter(quicktime_t *file, char *key, void *value){ int i; for(i = 0; i < file->total_vtracks; i++) { lqt_set_video_parameter(file,i, key,value); } for(i = 0; i < file->total_atracks; i++) { lqt_set_audio_parameter(file,i, key,value); }}void quicktime_set_jpeg(quicktime_t *file, int quality, int use_float){ quicktime_set_parameter( file, "jpeg_quality", &quality ); quicktime_set_parameter( file, "jpeg_usefloat", &use_float );}void quicktime_set_copyright(quicktime_t *file, char *string){ quicktime_set_udta_string(&(file->moov.udta.copyright), &(file->moov.udta.copyright_len), string);}void quicktime_set_name(quicktime_t *file, char *string){ quicktime_set_udta_string(&(file->moov.udta.name), &(file->moov.udta.name_len), string);}void quicktime_set_info(quicktime_t *file, char *string){ quicktime_set_udta_string(&(file->moov.udta.info), &(file->moov.udta.info_len), string);}char* quicktime_get_copyright(quicktime_t *file){ return file->moov.udta.copyright;}char* quicktime_get_name(quicktime_t *file){ return file->moov.udta.name;}char* quicktime_get_info(quicktime_t *file){ return file->moov.udta.info;}/* Extended metadata support */void lqt_set_album(quicktime_t *file, char *string){ quicktime_set_udta_string(&(file->moov.udta.album), &(file->moov.udta.album_len), string);}void lqt_set_artist(quicktime_t *file, char *string){ quicktime_set_udta_string(&(file->moov.udta.artist), &(file->moov.udta.artist_len), string);}void lqt_set_genre(quicktime_t *file, char *string){ quicktime_set_udta_string(&(file->moov.udta.genre), &(file->moov.udta.genre_len), string);}void lqt_set_track(quicktime_t *file, char *string){ quicktime_set_udta_string(&(file->moov.udta.track), &(file->moov.udta.track_len), string);}void lqt_set_comment(quicktime_t *file, char *string){ quicktime_set_udta_string(&(file->moov.udta.comment), &(file->moov.udta.comment_len), string);}void lqt_set_author(quicktime_t *file, char *string){ quicktime_set_udta_string(&(file->moov.udta.author), &(file->moov.udta.author_len), string);}void lqt_set_creation_time(quicktime_t *file, unsigned long time) { file->moov.mvhd.creation_time = time; }char * lqt_get_album(quicktime_t * file){ return file->moov.udta.album;}char * lqt_get_artist(quicktime_t * file){ return file->moov.udta.artist;}char * lqt_get_genre(quicktime_t * file){ return file->moov.udta.genre;}char * lqt_get_track(quicktime_t * file){ return file->moov.udta.track;}char * lqt_get_comment(quicktime_t *file){ return file->moov.udta.comment;}char * lqt_get_author(quicktime_t *file){ return file->moov.udta.author;}unsigned long lqt_get_creation_time(quicktime_t * file) { return file->moov.mvhd.creation_time; }int quicktime_video_tracks(quicktime_t *file){ int i, result = 0; for(i = 0; i < file->moov.total_tracks; i++) { if(file->moov.trak[i]->mdia.minf.is_video) result++; } return result;}int quicktime_audio_tracks(quicktime_t *file){ int i, result = 0; quicktime_minf_t *minf; for(i = 0; i < file->moov.total_tracks; i++) { minf = &(file->moov.trak[i]->mdia.minf); if(minf->is_audio) result++; } return result;}int lqt_add_audio_track(quicktime_t *file, int channels, long sample_rate, int bits, lqt_codec_info_t * codec_info) { quicktime_trak_t *trak; char * compressor = codec_info->fourccs[0]; /* Fake the bits parameter for some formats. */ if(quicktime_match_32(compressor, QUICKTIME_ULAW) || quicktime_match_32(compressor, QUICKTIME_IMA4)) bits = 16; else if(quicktime_match_32(compressor, QUICKTIME_RAW)) bits = 8; file->atracks = realloc(file->atracks, (file->total_atracks+1)*sizeof(quicktime_audio_map_t)); memset(&(file->atracks[file->total_atracks]), 0, sizeof(quicktime_audio_map_t)); trak = quicktime_add_track(file); quicktime_trak_init_audio(file, trak, channels, sample_rate, bits, compressor); quicktime_init_audio_map(file, &(file->atracks[file->total_atracks]), trak, file->wr, codec_info); file->atracks[file->total_atracks].track = trak; file->atracks[file->total_atracks].channels = channels; file->atracks[file->total_atracks].current_position = 0; file->atracks[file->total_atracks].current_chunk = 1; lqt_set_default_audio_parameters(file, file->total_atracks); file->total_atracks++; return 0; }int lqt_set_audio(quicktime_t *file, int channels, long sample_rate, int bits,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -