📄 lqt_codecinfo.c
字号:
/* Set the end pointers so we can quickly add codecs after */ audio_codecs_end = lqt_audio_codecs; if(audio_codecs_end) while(audio_codecs_end->next) audio_codecs_end = audio_codecs_end->next; video_codecs_end = lqt_video_codecs; if(video_codecs_end) while(video_codecs_end->next) video_codecs_end = video_codecs_end->next; directory = opendir(plugin_dir); if(!directory) { lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN, "Cannot open plugin directory %s (forgot make install?)", plugin_dir); return 0; } ret = 0; while(1) { directory_entry = readdir(directory); if(!directory_entry) /* We're done */ break; /* Check the beginning of the filename */ if(strncmp(directory_entry->d_name, "lqt_", 4)) continue; /* Check the end of the filename -> filter out .la files */ pos = strchr(directory_entry->d_name, '.'); if(!pos) continue; if(strcmp(pos, MODULE_EXT)) continue; /* Now, the file should be a valid plugin, construct the filename */ strcpy(filename, plugin_dir); strcat(filename, "/"); strcat(filename, directory_entry->d_name); stat(filename, &status); if(!S_ISREG(status.st_mode)) continue; codecs = find_codec_by_filename(database, filename, status.st_ctime); if(codecs) /* Codec information found in database */ { register_codecs(codecs, &audio_codecs_end, &video_codecs_end); } else /* Load the informations from the module */ { codecs = load_codec_info_from_plugin(filename, status.st_ctime); register_codecs(codecs, &audio_codecs_end, &video_codecs_end); ret = 1; } } free(filename); closedir(directory); return ret; }void lqt_registry_destroy() { lqt_codec_info_t * tmp; while(lqt_audio_codecs) { tmp = lqt_audio_codecs->next; destroy_codec_info(lqt_audio_codecs); lqt_audio_codecs = tmp; } while(lqt_video_codecs) { tmp = lqt_video_codecs->next; destroy_codec_info(lqt_video_codecs); lqt_video_codecs = tmp; } lqt_num_video_codecs = 0; lqt_num_audio_codecs = 0; }void lqt_registry_init() { int do_write = 0; char * audio_order = (char*)0; char * video_order = (char*)0; lqt_codec_info_t * file_codecs; lqt_codec_info_t * tmp_file_codecs; const char* plugin_dir = PLUGIN_DIR; lqt_registry_lock(); if(registry_init_done) { lqt_registry_unlock(); return; } registry_init_done = 1; /* Check for environment variable for plugin dir */ if(getenv("LIBQUICKTIME_PLUGIN_DIR")) { plugin_dir = getenv("LIBQUICKTIME_PLUGIN_DIR"); } if(lqt_audio_codecs || lqt_video_codecs) { lqt_registry_unlock(); return; } file_codecs = lqt_registry_read(&audio_order, &video_order); /* Scan for the plugins, use cached values if possible */ if(scan_for_plugins(plugin_dir, &file_codecs)) do_write = 1; /* * If there were codecs in the database, which have * disappeared, they must be deleted now */ while(file_codecs) { tmp_file_codecs = file_codecs; file_codecs = file_codecs->next; destroy_codec_info(tmp_file_codecs); do_write = 1; } /* * Write the file again, so we can use it the next time */ /* Sort the codecs */ if(audio_order) { lqt_audio_codecs = sort_codecs_internal(lqt_audio_codecs, audio_order); free(audio_order); } if(video_order) { lqt_video_codecs = sort_codecs_internal(lqt_video_codecs, video_order); free(video_order); } lqt_registry_unlock(); if(do_write) lqt_registry_write(); }/* * Get the numbers of codecs */int lqt_get_num_audio_codecs() { return lqt_num_audio_codecs; }int lqt_get_num_video_codecs() { return lqt_num_video_codecs; }/* * Get corresponding info structures * These point to the original database entries, * so they are returned as const here */const lqt_codec_info_t * lqt_get_audio_codec_info(int index) { const lqt_codec_info_t * ret; int i; if((index < 0) || (index >= lqt_num_audio_codecs)) return (lqt_codec_info_t *)0; ret = lqt_audio_codecs; for(i = 0; i < index; i++) ret = ret->next; return ret; }const lqt_codec_info_t * lqt_get_video_codec_info(int index) { const lqt_codec_info_t * ret; int i; if((index < 0) || (index >= lqt_num_video_codecs)) return (lqt_codec_info_t *)0; ret = lqt_video_codecs; for(i = 0; i < index; i++) ret = ret->next; return ret; }/* Thread save methods of getting codec infos */static void create_parameter_info(lqt_parameter_info_t * ret, const lqt_parameter_info_static_t * info) { int i; ret->name = __lqt_strdup(info->name); /* Parameter name */ ret->real_name = __lqt_strdup(info->real_name); /* Parameter name */ if(info->help_string) ret->help_string = __lqt_strdup(info->help_string); ret->type = info->type; switch(ret->type) { case LQT_PARAMETER_INT: ret->val_default.val_int = info->val_default.val_int; ret->val_min.val_int = info->val_min.val_int; ret->val_max.val_int = info->val_max.val_int; break; case LQT_PARAMETER_FLOAT: ret->val_default.val_float = info->val_default.val_float; ret->val_min.val_float = info->val_min.val_float; ret->val_max.val_float = info->val_max.val_float; ret->num_digits = info->num_digits; break; case LQT_PARAMETER_STRING: ret->val_default.val_string = __lqt_strdup(info->val_default.val_string); break; case LQT_PARAMETER_STRINGLIST: ret->val_default.val_string = __lqt_strdup(info->val_default.val_string); if(!info->stringlist_options) { lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN, "Stringlist parameter %s has NULL options", info->name); return; } /* Count the options */ ret->num_stringlist_options = 0; while(1) { if(info->stringlist_options[ret->num_stringlist_options]) ret->num_stringlist_options++; else break; } /* Now, copy them */ ret->stringlist_options = malloc(ret->num_stringlist_options * sizeof(char *)); for(i = 0; i < ret->num_stringlist_options; i++) { ret->stringlist_options[i] = __lqt_strdup(info->stringlist_options[i]); } /* Labels */ ret->stringlist_labels = malloc(ret->num_stringlist_options * sizeof(char *)); if(info->stringlist_labels) { for(i = 0; i < ret->num_stringlist_options; i++) { ret->stringlist_labels[i] = __lqt_strdup(info->stringlist_labels[i]); } } else { for(i = 0; i < ret->num_stringlist_options; i++) { ret->stringlist_labels[i] = __lqt_strdup(info->stringlist_options[i]); } } break; default: break; } }lqt_codec_info_t *lqt_create_codec_info(const lqt_codec_info_static_t * template) { int i; lqt_codec_info_t * ret; if(!template->fourccs) { lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN, "Codec %s has no fourccs defined", template->name); return (lqt_codec_info_t*)0; } ret = calloc(1, sizeof(lqt_codec_info_t)); ret->compatibility_flags = template->compatibility_flags; ret->name = __lqt_strdup(template->name); ret->long_name = __lqt_strdup(template->long_name); ret->description = __lqt_strdup(template->description); if(template->gettext_domain) ret->gettext_domain = __lqt_strdup(template->gettext_domain); if(template->gettext_directory) ret->gettext_directory = __lqt_strdup(template->gettext_directory); ret->type = template->type; ret->direction = template->direction; /* Copy fourccs */ ret->num_fourccs = 0; while(1) { if(template->fourccs[ret->num_fourccs]) ret->num_fourccs++; else break; } ret->fourccs = malloc(ret->num_fourccs * sizeof(char*)); for(i = 0; i < ret->num_fourccs; i++) ret->fourccs[i] = __lqt_fourccdup(template->fourccs[i]); /* Copy wav_ids */ ret->num_wav_ids = 0; if(template->wav_ids) { while(1) { if(template->wav_ids[ret->num_wav_ids] != LQT_WAV_ID_NONE) ret->num_wav_ids++; else break; } ret->wav_ids = malloc(ret->num_wav_ids * sizeof(int)); for(i = 0; i < ret->num_wav_ids; i++) ret->wav_ids[i] = template->wav_ids[i]; } /* Copy encoding colormodels */ if(template->encoding_parameters) { ret->num_encoding_parameters = 0; while(1) { if(template->encoding_parameters[ret->num_encoding_parameters].name) ret->num_encoding_parameters++; else break; } } if(ret->num_encoding_parameters) { ret->encoding_parameters = calloc(ret->num_encoding_parameters, sizeof(lqt_parameter_info_t)); for(i = 0; i < ret->num_encoding_parameters; i++) { /* Copy parameter info */ create_parameter_info(&(ret->encoding_parameters[i]), &(template->encoding_parameters[i])); } } else { ret->encoding_parameters = (lqt_parameter_info_t*)0; } if(template->decoding_parameters) { ret->num_decoding_parameters = 0; while(1) { if(template->decoding_parameters[ret->num_decoding_parameters].name) ret->num_decoding_parameters++; else break; } } if(ret->num_decoding_parameters) { ret->decoding_parameters = calloc(ret->num_decoding_parameters, sizeof(lqt_parameter_info_t)); for(i = 0; i < ret->num_decoding_parameters; i++) { /* Copy parameter info */ create_parameter_info(&(ret->decoding_parameters[i]), &(template->decoding_parameters[i])); } } else { ret->decoding_parameters = (lqt_parameter_info_t*)0; } return ret; }static void dump_codec_parameter(lqt_parameter_info_t * p) { int i; lqt_dump("Parameter: %s (%s) ", p->name, p->real_name); lqt_dump("Type: "); switch(p->type) { case LQT_PARAMETER_INT: lqt_dump("Integer, Default Value: %d ", p->val_default.val_int); if(p->val_min.val_int < p->val_max.val_int) lqt_dump("(%d..%d)\n", p->val_min.val_int, p->val_max.val_int); else lqt_dump("(unlimited)\n"); break; case LQT_PARAMETER_FLOAT: lqt_dump("Float, Default Value: %f ", p->val_default.val_float); if(p->val_min.val_float < p->val_max.val_float) lqt_dump("(%f..%f)\n", p->val_min.val_float, p->val_max.val_float); else lqt_dump("(unlimited)\n"); break; case LQT_PARAMETER_STRING: lqt_dump("String, Default Value : %s\n", (p->val_default.val_string ? p->val_default.val_string : "NULL")); break; case LQT_PARAMETER_STRINGLIST: lqt_dump("Stringlist, Default Value : %s\n", (p->val_default.val_string ? p->val_default.val_string : "NULL")); lqt_dump("Options: "); for(i = 0; i < p->num_stringlist_options; i++) lqt_dump("%s ", p->stringlist_options[i]); lqt_dump("\n"); break; case LQT_PARAMETER_SECTION: lqt_dump("Section"); } if(p->help_string) lqt_dump("Help string: %s\n", p->help_string); }void lqt_dump_codec_info(const lqt_codec_info_t * info) { int i; lqt_dump("Codec: %s (%s)\n", info->long_name, info->name); lqt_dump("Type: %s Direction: ", (info->type == LQT_CODEC_AUDIO ? "Audio, " : "Video, ") ); switch(info->direction) { case LQT_DIRECTION_ENCODE: lqt_dump("Encode\n"); break; case LQT_DIRECTION_DECODE: lqt_dump("Decode\n"); break; case LQT_DIRECTION_BOTH: lqt_dump("Encode/Decode\n"); break; } lqt_dump("Description:\n%s\n", info->description); lqt_dump("Four character codes: (fourccs)\n"); for(i = 0; i < info->num_fourccs; i++) lqt_dump("%s (0x%08x)\n", info->fourccs[i], LQT_STRING_2_FOURCC(info->fourccs[i])); if(!info->num_encoding_parameters) { lqt_dump("No settable parameters for encoding\n"); } else { for(i = 0; i < info->num_encoding_parameters; i++) dump_codec_parameter(&(info->encoding_parameters[i])); } if(!info->num_encoding_parameters) { lqt_dump("No settable parameters for decoding\n"); } else { for(i = 0; i < info->num_decoding_parameters; i++) dump_codec_parameter(&(info->decoding_parameters[i])); } lqt_dump("Module filename: %s\nIndex inside module: %d\n", info->module_filename, info->module_index); }#define MATCH_FOURCC(a, b) \( ( a[0]==b[0] ) && \ ( a[1]==b[1] ) &&\ ( a[2]==b[2] ) &&\ ( a[3]==b[3] ) )/* * Find codecs: These replace get_acodec_index() and get_vcodec_index() * This returns a pointer to the codec info or NULL if there is none. */lqt_codec_info_t ** lqt_find_audio_codec(char * fourcc, int encode) { int j; lqt_codec_info_t * tmp_ptr = (lqt_codec_info_t*)0; lqt_codec_info_t * ptr; lqt_codec_info_t ** ret = (lqt_codec_info_t **)0; /* also init registry */ lqt_registry_init(); lqt_registry_lock(); ptr = lqt_audio_codecs; while(ptr) { for(j = 0; j < ptr->num_fourccs; j++) { if(MATCH_FOURCC(ptr->fourccs[j], fourcc)) { if((encode && (ptr->direction != LQT_DIRECTION_DECODE)) || (!encode && (ptr->direction != LQT_DIRECTION_ENCODE))) { tmp_ptr = ptr; break; } } } if(tmp_ptr) break; ptr = ptr->next; } if(tmp_ptr) { ret = calloc(2, sizeof(lqt_codec_info_t*)); *ret = copy_codec_info(tmp_ptr); } lqt_registry_unlock(); return ret; }lqt_codec_info_t ** lqt_find_audio_codec_by_wav_id(int wav_id, int encode) { int j; lqt_codec_info_t * tmp_ptr = (lqt_codec_info_t*)0; lqt_codec_info_t * ptr; lqt_codec_info_t ** ret = (lqt_codec_info_t **)0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -