⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lqt_codecinfo.c

📁 这个库实现了录象功能
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************* lqt_codecinfo.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_codecinfo_private.h"#define LQT_LIBQUICKTIME#include <quicktime/lqt_codecapi.h>#include <sys/stat.h>#include <pthread.h>#include <dlfcn.h>#include <dirent.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <limits.h>#include <libintl.h>#define LOG_DOMAIN "codecinfo"/* Public function (lqt.h) */int lqt_get_codec_api_version() { return LQT_CODEC_API_VERSION; }/* Forward declaration */static lqt_codec_info_t *sort_codecs_internal(lqt_codec_info_t * original, char * names);/* *  Quick and dirty strdup function for the case it's not there */static char * __lqt_strdup(const char * string)  {  char * ret = malloc(strlen(string)+1);  strcpy(ret, string);  return ret;  }static char * __lqt_fourccdup(const char * fourcc)  {  char * ret = malloc(5);  memcpy(ret, fourcc, 5);  return ret;  };/* *  Codec Registry */int lqt_num_audio_codecs = 0;int lqt_num_video_codecs = 0;lqt_codec_info_t * lqt_audio_codecs = (lqt_codec_info_t*)0;lqt_codec_info_t * lqt_video_codecs = (lqt_codec_info_t*)0;static int registry_init_done = 0;pthread_mutex_t codecs_mutex = PTHREAD_MUTEX_INITIALIZER;/* *  Lock and unlock the codec registry */void lqt_registry_lock()  {  pthread_mutex_lock(&codecs_mutex);  }void lqt_registry_unlock()  {  pthread_mutex_unlock(&codecs_mutex);  }/* Free memory of parameter info */static void destroy_parameter_info(lqt_parameter_info_t * p)  {  int i;  if(p->name)    free(p->name);  if(p->real_name)    free(p->real_name);  if(p->help_string)    free(p->help_string);  switch(p->type)    {    case LQT_PARAMETER_STRING:      if(p->val_default.val_string)        free(p->val_default.val_string);      break;    case LQT_PARAMETER_STRINGLIST:      if(p->val_default.val_string)        free(p->val_default.val_string);      if(p->stringlist_options)        {        for(i = 0; i < p->num_stringlist_options; i++)          free(p->stringlist_options[i]);        free(p->stringlist_options);        }      if(p->stringlist_labels)        {        for(i = 0; i < p->num_stringlist_options; i++)          free(p->stringlist_labels[i]);        free(p->stringlist_labels);        }      break;    default: /* Keep gcc quiet */      break;    }  }/* Free memory of codec info (public) */static void destroy_codec_info(lqt_codec_info_t * ptr)  {  int i;  if(ptr->fourccs)    {    for(i = 0; i < ptr->num_fourccs; i++)      free(ptr->fourccs[i]);    free(ptr->fourccs);    }  if(ptr->wav_ids)    free(ptr->wav_ids);    if(ptr->name)    free(ptr->name);          /* Name of the codec              */  if(ptr->long_name)          /* Long name of the codec         */    free(ptr->long_name);  if(ptr->description)        /* Long name of the codec         */    free(ptr->description);  if(ptr->module_filename)        /* Module filename       */    free(ptr->module_filename);  if(ptr->gettext_domain)    free(ptr->gettext_domain);  if(ptr->gettext_directory)    free(ptr->gettext_directory);    if(ptr->encoding_parameters)    {    for(i = 0; i < ptr->num_encoding_parameters; i++)      destroy_parameter_info(&(ptr->encoding_parameters[i]));    free(ptr->encoding_parameters);    }  if(ptr->decoding_parameters)    {    for(i = 0; i < ptr->num_decoding_parameters; i++)      destroy_parameter_info(&(ptr->decoding_parameters[i]));    free(ptr->decoding_parameters);    }  free(ptr);  }static void copy_parameter_value(lqt_parameter_value_t * dst,                                 const lqt_parameter_value_t * src,                                 lqt_parameter_type_t type)  {  switch(type)    {    case LQT_PARAMETER_INT:      dst->val_int = src->val_int;      break;    case LQT_PARAMETER_FLOAT:      dst->val_float = src->val_float;      break;    case LQT_PARAMETER_STRING:    case LQT_PARAMETER_STRINGLIST: /* String with options */      if(dst->val_string)        free(dst->val_string);      if(src->val_string)        dst->val_string = __lqt_strdup(src->val_string);      else        dst->val_string = (char*)0;      break;    case LQT_PARAMETER_SECTION:      break;    }  }static voidcopy_parameter_info(lqt_parameter_info_t * ret,                    const lqt_parameter_info_t * info, const char * gettext_domain)  {  int i;    if(info->name)    ret->name = __lqt_strdup(info->name);  if(info->real_name)    ret->real_name = __lqt_strdup(dgettext(gettext_domain, info->real_name));  if(info->help_string)    ret->help_string = __lqt_strdup(dgettext(gettext_domain, info->help_string));    ret->type = info->type;  switch(ret->type)    {    case LQT_PARAMETER_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_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:      break;    case LQT_PARAMETER_STRINGLIST: /* String with options */      ret->num_stringlist_options = info->num_stringlist_options;      ret->stringlist_options = calloc(ret->num_stringlist_options,                                       sizeof(char*));      ret->stringlist_labels = calloc(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]);        ret->stringlist_labels[i] =          __lqt_strdup(dgettext(gettext_domain, info->stringlist_labels[i]));        }      break;    case LQT_PARAMETER_SECTION: /* String with options */      break;    }  copy_parameter_value(&(ret->val_default),                       &(info->val_default),                       info->type);  }/* *  Copy codec Info */static lqt_codec_info_t *copy_codec_info(const lqt_codec_info_t * info)  {  int i;  const char * gettext_domain;  lqt_codec_info_t * ret = calloc(1, sizeof(lqt_codec_info_t));  if(info->gettext_domain && info->gettext_directory)    {    bindtextdomain(info->gettext_domain, info->gettext_directory);    gettext_domain = info->gettext_domain;    }  else    {    lqt_translation_init();    gettext_domain = PACKAGE;    }    ret->compatibility_flags = info->compatibility_flags;      if(info->name)    ret->name = __lqt_strdup(info->name);  if(info->long_name)    ret->long_name = __lqt_strdup(info->long_name);  if(info->description)    ret->description = __lqt_strdup(info->description);  if(info->module_filename)    ret->module_filename = __lqt_strdup(info->module_filename);  ret->module_index = info->module_index;    ret->type = info->type;  ret->direction = info->direction;    ret->num_fourccs = info->num_fourccs;  if(ret->num_fourccs)    {    ret->fourccs = malloc(ret->num_fourccs * sizeof(char*));    for(i = 0; i < ret->num_fourccs; i++)      ret->fourccs[i] = __lqt_fourccdup(info->fourccs[i]);    }  ret->num_wav_ids = info->num_wav_ids;  if(ret->num_wav_ids)    {    ret->wav_ids = malloc(ret->num_wav_ids * sizeof(int));    for(i = 0; i < ret->num_wav_ids; i++)      ret->wav_ids[i] = info->wav_ids[i];        }      ret->num_encoding_parameters = info->num_encoding_parameters;    if(ret->num_encoding_parameters)    {    ret->encoding_parameters =      calloc(ret->num_encoding_parameters+1, sizeof(lqt_parameter_info_t));    for(i = 0; i < ret->num_encoding_parameters; i++)      copy_parameter_info(&(ret->encoding_parameters[i]),                          &(info->encoding_parameters[i]), gettext_domain);    }  ret->num_decoding_parameters = info->num_decoding_parameters;  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(&(ret->decoding_parameters[i]),                          &(info->decoding_parameters[i]), gettext_domain);    }  return ret;  }/* *   Seek a codec in the database */static lqt_codec_info_t * find_codec_by_filename(lqt_codec_info_t ** list,                                                 const char * filename,                                                 uint32_t time)  {  lqt_codec_info_t * new_list =     (lqt_codec_info_t*)0;  lqt_codec_info_t * new_list_end = (lqt_codec_info_t*)0;  lqt_codec_info_t * ret =          (lqt_codec_info_t*)0;  lqt_codec_info_t * ret_end =      (lqt_codec_info_t*)0;  lqt_codec_info_t * tmp_ptr;    lqt_codec_info_t * ptr = *list;   if(!ptr)    return (lqt_codec_info_t*)0;  while(ptr)    {    if(!strcmp(ptr->module_filename, filename))      {      /*       *  File is there, but newer than our database entry       *  -> Remove from the list       */      if(ptr->file_time < time)        {        tmp_ptr = ptr->next;        destroy_codec_info(ptr);        ptr = tmp_ptr;        }      else        {        if(ret)          {          ret_end->next = ptr;          ret_end = ret_end->next;          }        else          {          ret = ptr;          ret_end = ptr;          }        ptr = ptr->next;        }      }    else /* Not our file, return to database */      {      if(new_list)        {        new_list_end->next = ptr;        new_list_end = new_list_end->next;        }      else        {        new_list = ptr;        new_list_end = ptr;        }      ptr = ptr->next;      }    }  /* Prepare for returning */  if(new_list)    {    new_list_end->next = (lqt_codec_info_t*)0;    }  *list = new_list;  if(ret_end)    ret_end->next = (lqt_codec_info_t*)0;      return ret;  }static lqt_codec_info_t * load_codec_info_from_plugin(char * plugin_filename,                                                      uint32_t time)  {  void * module;  lqt_codec_info_t * ret_end;    int i;  int num_codecs;  int codec_api_version_module;  int codec_api_version_us = lqt_get_codec_api_version();      int (*get_num_codecs)();  int (*get_codec_api_version)();  lqt_codec_info_static_t * (*get_codec_info)(int);    lqt_codec_info_t * ret = (lqt_codec_info_t*)0;    module = dlopen(plugin_filename, RTLD_NOW);  if(!module)    {    lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN, "dlopen failed for %s: %s",            plugin_filename, dlerror());    return ret;    }    /* Now, get the codec parameters */  /* Check the api version */  get_codec_api_version = (int (*)())(dlsym(module, "get_codec_api_version"));  if(!get_codec_api_version)    {    lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN,            "Module %s has no API version and is thus terribly old",            plugin_filename);    dlclose(module);    return ret;    }  codec_api_version_module = get_codec_api_version();  if(codec_api_version_module != codec_api_version_us)    {    lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN,            "Codec interface version mismatch of module %s: %d [module] != %d [lqt]",            plugin_filename,            codec_api_version_module,            codec_api_version_us);    dlclose(module);    return ret;    }  get_num_codecs = (int (*)())(dlsym(module, "get_num_codecs"));  if(!get_num_codecs)    {    lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN, "Symbol get_num_codecs not found in %s",            plugin_filename);    dlclose(module);    return ret;    }    get_codec_info = (lqt_codec_info_static_t*(*)(int))(dlsym(module, "get_codec_info"));  if(!get_codec_info)    {    lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN, "Symbol get_codec_info not found in %s",            plugin_filename);    dlclose(module);    return ret;    }  /* Now, create the structure */  num_codecs = get_num_codecs();  if(!num_codecs)    {    lqt_log(NULL, LQT_LOG_ERROR, LOG_DOMAIN, "No codecs found in %s",            plugin_filename);    dlclose(module);    return ret;    }  ret = lqt_create_codec_info(get_codec_info(0));  /* Complete the structure */  ret_end = ret;    ret_end->module_index = 0;  /* Filename of the module  */  ret_end->module_filename = __lqt_strdup(plugin_filename);  ret_end->file_time = time; /* File modification time  */    for(i = 1; i < num_codecs; i++)    {    ret_end->next = lqt_create_codec_info(get_codec_info(i));    ret_end = ret_end->next;        ret_end->module_index = i;    /* Filename of the module  */    ret_end->module_filename = __lqt_strdup(plugin_filename);    /* File modification time  */    ret_end->file_time = time;    }  ret_end->next = (lqt_codec_info_t*)0;  dlclose(module);  return ret;  }/* *   Register all codecs found in list */static void register_codecs(lqt_codec_info_t * list,                            lqt_codec_info_t ** audio_codecs_end,                            lqt_codec_info_t ** video_codecs_end)  {  lqt_codec_info_t * tmp_ptr;  while(list)    {    if(list->type == LQT_CODEC_AUDIO)      {      if(*audio_codecs_end)        {        (*audio_codecs_end)->next = list;        *audio_codecs_end = (*audio_codecs_end)->next;        }      else        {        lqt_audio_codecs = list;            (*audio_codecs_end) = lqt_audio_codecs;        }      lqt_num_audio_codecs++;      }    if(list->type == LQT_CODEC_VIDEO)      {      if((*video_codecs_end))        {        (*video_codecs_end)->next = list;        (*video_codecs_end) = (*video_codecs_end)->next;        }      else        {        lqt_video_codecs = list;        (*video_codecs_end) = lqt_video_codecs;        }      lqt_num_video_codecs++;      }    tmp_ptr = list;    list = list->next;    tmp_ptr->next = (lqt_codec_info_t*)0;    }  }static int scan_for_plugins(const char * plugin_dir, lqt_codec_info_t ** database)  {  char * pos;  int ret;  char * filename;  DIR * directory;  struct dirent * directory_entry;  struct stat status;  lqt_codec_info_t * codecs;  lqt_codec_info_t * video_codecs_end;  lqt_codec_info_t * audio_codecs_end;  filename = malloc(PATH_MAX * sizeof(char));  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -