codec_plugin.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:10k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2002.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  *              Bill May        wmay@cisco.com
  20.  */
  21. /*
  22.  * codec_plugin.cpp - read and process for plugins
  23.  */
  24. #ifndef _WIN32
  25. #include <sys/types.h>
  26. #include <dlfcn.h>
  27. #include <dirent.h>
  28. #endif
  29. #include "codec_plugin_private.h"
  30. #include "player_util.h"
  31. #include "our_config_file.h"
  32. #include "player_session.h"
  33. #include "player_media.h"
  34. #include "our_bytestream_file.h"
  35. #include "audio.h"
  36. #include "video.h"
  37. /*
  38.  * Portability hacks
  39.  */
  40. #ifdef _WIN32
  41. #define LIBRARY_HANDLE    HINSTANCE
  42. #define DLL_GET_SYM       GetProcAddress
  43. #define DLL_CLOSE         FreeLibrary
  44. #define DLL_ERROR         GetLastError
  45. #define PLAYER_PLUGIN_DIR "."
  46. typedef struct dir_list_t {
  47.   WIN32_FIND_DATA dptr;
  48.   HANDLE shandle;
  49. } dir_list_t;
  50. #else
  51. #define LIBRARY_HANDLE    void *
  52. #define DLL_GET_SYM       dlsym
  53. #define DLL_CLOSE         dlclose
  54. #define DLL_ERROR         dlerror
  55. // PLAYER_PLUGIN_DIR is set via configure.in
  56. typedef struct dir_list_t {
  57.   DIR *dptr;
  58.   char fname[PATH_MAX];
  59. } dir_list_t;
  60. #endif
  61. /*
  62.  * codec_plugin_list_t is how we store the codec links
  63.  */
  64. typedef struct codec_plugin_list_t {
  65.   struct codec_plugin_list_t *next_codec;
  66.   LIBRARY_HANDLE dl_handle;
  67.   codec_plugin_t *codec;
  68. } codec_plugin_list_t;
  69. static codec_plugin_list_t *audio_codecs, *video_codecs;
  70. static void close_file_search (dir_list_t *ptr)
  71. {
  72. #ifndef _WIN32
  73.   closedir(ptr->dptr);
  74. #endif
  75. }
  76. /*
  77.  * portable way to find the next file.  In unix, we're looking for
  78.  * any .so files.  In windows, we've already started looking for .dll
  79.  */
  80. static const char *find_next_file (dir_list_t *ptr,
  81.    const char *name)
  82. {
  83. #ifndef _WIN32
  84.   struct dirent *fptr;
  85.   while ((fptr = readdir(ptr->dptr)) != NULL) {
  86.     int len = strlen(fptr->d_name);
  87.     if (len > 3 && strcmp(fptr->d_name + len - 3, ".so") == 0) {
  88.       sprintf(ptr->fname, "%s/%s", 
  89.       name, fptr->d_name);
  90.       return (ptr->fname);
  91.     }
  92.   }
  93.   return NULL;
  94. #else
  95.   if (FindNextFile(ptr->shandle, &ptr->dptr) == FALSE)
  96.     return NULL;
  97.   return ptr->dptr.cFileName;
  98. #endif
  99. }
  100. /*
  101.  * get_first_file
  102.  * start directory search for plugin files
  103.  */
  104. static const char *get_first_file (dir_list_t *ptr, 
  105.    const char *name)
  106. {
  107. #ifndef _WIN32
  108.   ptr->dptr = opendir(name);
  109.   if (ptr->dptr == NULL) 
  110.     return NULL;
  111.   return (find_next_file(ptr, name));
  112. #else
  113.   ptr->shandle = FindFirstFile("*.dll", &ptr->dptr);
  114.   if (ptr->shandle == INVALID_HANDLE_VALUE) return NULL;
  115.   return ptr->dptr.cFileName;
  116. #endif
  117. }
  118. /*
  119.  * initialize_plugins
  120.  * Start search for plugins - classify them as audio or video
  121.  */
  122. void initialize_plugins (void)
  123. {
  124.   LIBRARY_HANDLE handle;
  125.   codec_plugin_t *cptr;
  126.   dir_list_t dir;
  127.   const char *fname;
  128.   audio_codecs = video_codecs = NULL;
  129.   fname = get_first_file(&dir, PLAYER_PLUGIN_DIR);
  130.   while (fname != NULL) {
  131. #ifdef _WIN32
  132.     handle = LoadLibrary(fname);
  133. #else
  134.     handle = dlopen(fname, RTLD_LAZY);
  135. #endif
  136.     if (handle != NULL) {
  137.       cptr = (codec_plugin_t *)DLL_GET_SYM(handle, "mpeg4ip_codec_plugin");
  138.       if (cptr != NULL) {
  139. if (strcmp(cptr->c_version, PLUGIN_VERSION) == 0) {
  140.   codec_plugin_list_t *p;
  141.   p = (codec_plugin_list_t *)malloc(sizeof(codec_plugin_list_t));
  142.   if (p == NULL) exit(-1);
  143.   
  144.   p->codec = cptr;
  145.   p->dl_handle = handle;
  146.   p->next_codec = NULL;
  147.   
  148.   if (strcmp(cptr->c_type, "audio") == 0) {
  149.     p->next_codec = audio_codecs;
  150.     audio_codecs = p;
  151.     message(LOG_INFO, "plugin", "Adding audio plugin %s %s", 
  152.     cptr->c_name, fname);
  153.   } else if (strcmp(cptr->c_type, "video") == 0) {
  154.     p->next_codec = video_codecs;
  155.     video_codecs = p;
  156.     message(LOG_INFO, "plugin", "Adding video plugin %s %s", 
  157.     cptr->c_name, fname);
  158.   } else {
  159.     free(p);
  160.     message(LOG_CRIT, "plugin", "Unknown plugin type %s in plugin %s", 
  161.     cptr->c_type, fname);
  162.   }
  163. } else {
  164.   message(LOG_ERR, "plugin", "Plugin %s has wrong version %s", 
  165.   cptr->c_type, cptr->c_version);
  166. }
  167.       } else {
  168. message(LOG_ERR, "plugin", "Can't find export point in plugin %s", 
  169. fname);
  170.       }
  171.     } else {
  172.       message(LOG_ERR, "plugin", "Can't dlopen plugin %s - %s", fname,
  173.       DLL_ERROR());
  174.     }
  175.     fname = find_next_file(&dir, PLAYER_PLUGIN_DIR);
  176.   }
  177.   close_file_search(&dir);
  178. }
  179. /*
  180.  * check_for_audio_codec
  181.  * search the list of audio codecs for one that matches the parameters
  182.  */
  183. codec_plugin_t *check_for_audio_codec (const char *compressor,
  184.        format_list_t *fptr,
  185.        int audio_type,
  186.        int profile, 
  187.        const uint8_t *userdata,
  188.        uint32_t userdata_size)
  189. {
  190.   codec_plugin_list_t *aptr;
  191.   int best_value = 0;
  192.   codec_plugin_t *ret;
  193.   ret = NULL;
  194.   aptr = audio_codecs;
  195.   while (aptr != NULL) {
  196.     if (aptr->codec->c_compress_check != NULL) {
  197.       int temp;
  198.       temp = (aptr->codec->c_compress_check)(message,
  199.      compressor,
  200.      audio_type,
  201.      profile, 
  202.      fptr,
  203.      userdata,
  204.      userdata_size);
  205.       if (temp > best_value) {
  206. best_value = temp;
  207. ret = aptr->codec;
  208.       }
  209.     }
  210.     aptr = aptr->next_codec;
  211.   }
  212.   if (ret != NULL) {
  213.     message(LOG_DEBUG, "plugin", 
  214.     "Found matching audio plugin %s", ret->c_name);
  215.   }
  216.   return (ret);
  217. }
  218. /*
  219.  * check_for_video_codec
  220.  * search the list of video plugins  for one that matches the parameters
  221.  */
  222. codec_plugin_t *check_for_video_codec (const char *compressor,
  223.        format_list_t *fptr,
  224.        int type,
  225.        int profile, 
  226.        const uint8_t *userdata,
  227.        uint32_t userdata_size)
  228. {
  229.   codec_plugin_list_t *vptr;
  230.   int best_value = 0;
  231.   codec_plugin_t *ret;
  232.   ret = NULL;
  233.   vptr = video_codecs;
  234.   while (vptr != NULL) {
  235.     if (vptr->codec->c_compress_check != NULL) {
  236.       int temp;
  237.       temp = (vptr->codec->c_compress_check)(message,
  238.      compressor,
  239.      type,
  240.      profile, 
  241.      fptr,
  242.      userdata,
  243.      userdata_size);
  244.       if (temp > 0 &&
  245.   config.get_config_value(CONFIG_USE_MPEG4_ISO_ONLY) &&
  246.   strcmp(vptr->codec->c_name, "MPEG4 ISO") == 0) {
  247. temp = INT_MAX;
  248.       }
  249.       if (temp > best_value) {
  250. best_value = temp;
  251. ret = vptr->codec;
  252.       }
  253.     }
  254.     vptr = vptr->next_codec;
  255.   }
  256.   if (ret != NULL) {
  257.     message(LOG_DEBUG, "plugin", 
  258.     "Found matching video plugin %s", ret->c_name);
  259.   }
  260.   return (ret);
  261. }
  262. /*
  263.  * video_codec_check_for_raw_file
  264.  * goes through list of video codecs to see if "name" has a raw file
  265.  * match
  266.  */
  267. int video_codec_check_for_raw_file (CPlayerSession *psptr,
  268.     const char *name)
  269. {
  270.   codec_plugin_list_t *vptr;
  271.   codec_data_t *cifptr;
  272.   char *desc[4];
  273.   double maxtime;
  274.   int slen = strlen(name);
  275.   desc[0] = NULL;
  276.   desc[1] = NULL;
  277.   desc[2] = NULL;
  278.   desc[3] = NULL;
  279.   vptr = video_codecs;
  280.   
  281.   while (vptr != NULL) {
  282.     if (vptr->codec->c_raw_file_check != NULL) {
  283.       if (config.get_config_value(CONFIG_USE_MPEG4_ISO_ONLY) != 0 &&
  284.   strcmp("MPEG4 ISO", vptr->codec->c_name) != 0 && 
  285.   strcmp(".divx", name + slen - 5) == 0) {
  286. vptr = vptr->next_codec;
  287. continue;
  288.       }
  289.    
  290.       cifptr = vptr->codec->c_raw_file_check(message,
  291.      name,
  292.      &maxtime,
  293.      desc);
  294.       if (cifptr != NULL) {
  295. player_debug_message("Found raw file codec %s", vptr->codec->c_name);
  296. CPlayerMedia *mptr;
  297.    
  298. /*
  299.  * Create the player media, and the bytestream
  300.  */
  301. mptr = new CPlayerMedia(psptr);
  302. COurInByteStreamFile *fbyte;
  303. fbyte = new COurInByteStreamFile(vptr->codec,
  304.  cifptr,
  305.  maxtime);
  306. mptr->create_from_file(fbyte, TRUE);
  307. mptr->set_plugin_data(vptr->codec, cifptr, get_video_vft(), NULL);
  308. for (int ix = 0; ix < 4; ix++) 
  309.   if (desc[ix] != NULL) 
  310.     psptr->set_session_desc(ix, desc[ix]);
  311. if (maxtime != 0.0) {
  312.   psptr->session_set_seekable(1);
  313. }
  314. return 0;
  315.       }
  316.       return -1;
  317.     } else {
  318.       vptr = vptr->next_codec;
  319.     }
  320.   }
  321.   return -1;
  322. }
  323. /*
  324.  * audio_codec_check_for_raw_file
  325.  * goes through the list of audio codecs, looking for raw file
  326.  * support
  327.  */
  328. int audio_codec_check_for_raw_file (CPlayerSession *psptr,
  329.     const char *name)
  330. {
  331.   codec_plugin_list_t *aptr;
  332.   codec_data_t *cifptr;
  333.   char *desc[4];
  334.   double maxtime;
  335.   desc[0] = NULL;
  336.   desc[1] = NULL;
  337.   desc[2] = NULL;
  338.   desc[3] = NULL;
  339.   aptr = audio_codecs;
  340.   while (aptr != NULL) {
  341.     if (aptr->codec->c_raw_file_check != NULL) {
  342.       cifptr = aptr->codec->c_raw_file_check(message,
  343.      name,
  344.      &maxtime,
  345.      desc);
  346.       if (cifptr != NULL) {
  347. CPlayerMedia *mptr;
  348.       
  349. mptr = new CPlayerMedia(psptr);
  350. COurInByteStreamFile *fbyte;
  351. fbyte = new COurInByteStreamFile(aptr->codec,
  352.  cifptr,
  353.  maxtime);
  354. mptr->create_from_file(fbyte, FALSE);
  355. mptr->set_plugin_data(aptr->codec, cifptr, NULL, get_audio_vft());
  356. for (int ix = 0; ix < 4; ix++) 
  357.   if (desc[ix] != NULL) 
  358.     psptr->set_session_desc(ix, desc[ix]);
  359. if (maxtime != 0.0) {
  360.   psptr->session_set_seekable(1);
  361. }
  362. return 0;
  363.       }
  364.     }
  365.    
  366.     aptr = aptr->next_codec;
  367.   }
  368.   return -1;
  369. }
  370. /*
  371.  * close_plugins
  372.  * closes and frees plugin lists
  373.  */
  374. void close_plugins (void) 
  375. {
  376.   codec_plugin_list_t *p;
  377.   while (audio_codecs != NULL) {
  378.     p = audio_codecs;
  379. DLL_CLOSE(p->dl_handle);
  380.     audio_codecs = audio_codecs->next_codec;
  381.     free(p);
  382.   }
  383.   while (video_codecs != NULL) {
  384.     p = video_codecs;
  385.     DLL_CLOSE(p->dl_handle);
  386.     video_codecs = video_codecs->next_codec;
  387.     free(p);
  388.   }
  389. }
  390. /* end file codec_plugin.cpp */