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

📄 codec_plugin.cpp

📁 jpeg and mpeg 编解码技术源代码
💻 CPP
字号:
/*
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 * 
 * The Original Code is MPEG4IP.
 * 
 * The Initial Developer of the Original Code is Cisco Systems Inc.
 * Portions created by Cisco Systems Inc. are
 * Copyright (C) Cisco Systems Inc. 2002.  All Rights Reserved.
 * 
 * Contributor(s): 
 *              Bill May        wmay@cisco.com
 */
/*
 * codec_plugin.cpp - read and process for plugins
 */

#ifndef _WIN32
#include <sys/types.h>
#include <dlfcn.h>
#include <dirent.h>
#endif

#include "codec_plugin_private.h"
#include "player_util.h"
#include "our_config_file.h"
#include "player_session.h"
#include "player_media.h"
#include "our_bytestream_file.h"
#include "audio.h"
#include "video.h"

/*
 * Portability hacks
 */
#ifdef _WIN32
#define LIBRARY_HANDLE    HINSTANCE
#define DLL_GET_SYM       GetProcAddress
#define DLL_CLOSE         FreeLibrary
#define DLL_ERROR         GetLastError
#define PLAYER_PLUGIN_DIR "."
typedef struct dir_list_t {
  WIN32_FIND_DATA dptr;
  HANDLE shandle;
} dir_list_t;

#else
#define LIBRARY_HANDLE    void *
#define DLL_GET_SYM       dlsym
#define DLL_CLOSE         dlclose
#define DLL_ERROR         dlerror
// PLAYER_PLUGIN_DIR is set via configure.in
typedef struct dir_list_t {
  DIR *dptr;
  char fname[PATH_MAX];
} dir_list_t;
#endif

/*
 * codec_plugin_list_t is how we store the codec links
 */
typedef struct codec_plugin_list_t {
  struct codec_plugin_list_t *next_codec;
  LIBRARY_HANDLE dl_handle;
  codec_plugin_t *codec;
} codec_plugin_list_t;

static codec_plugin_list_t *audio_codecs, *video_codecs;

static void close_file_search (dir_list_t *ptr)
{
#ifndef _WIN32
  closedir(ptr->dptr);
#endif
}
/*
 * portable way to find the next file.  In unix, we're looking for
 * any .so files.  In windows, we've already started looking for .dll
 */
static const char *find_next_file (dir_list_t *ptr,
				   const char *name)
{
#ifndef _WIN32
  struct dirent *fptr;

  while ((fptr = readdir(ptr->dptr)) != NULL) {
    int len = strlen(fptr->d_name);
    if (len > 3 && strcmp(fptr->d_name + len - 3, ".so") == 0) {
      sprintf(ptr->fname, "%s/%s", 
	      name, fptr->d_name);
      return (ptr->fname);
    }
  }
  return NULL;
#else
  if (FindNextFile(ptr->shandle, &ptr->dptr) == FALSE)
    return NULL;
  return ptr->dptr.cFileName;
#endif
}

/*
 * get_first_file
 * start directory search for plugin files
 */
static const char *get_first_file (dir_list_t *ptr, 
				   const char *name)
{
#ifndef _WIN32
  ptr->dptr = opendir(name);
  if (ptr->dptr == NULL) 
    return NULL;
  return (find_next_file(ptr, name));
#else
  ptr->shandle = FindFirstFile("*.dll", &ptr->dptr);
  if (ptr->shandle == INVALID_HANDLE_VALUE) return NULL;
  return ptr->dptr.cFileName;
#endif
}

/*
 * initialize_plugins
 * Start search for plugins - classify them as audio or video
 */
void initialize_plugins (void)
{
  LIBRARY_HANDLE handle;
  codec_plugin_t *cptr;
  dir_list_t dir;
  const char *fname;

  audio_codecs = video_codecs = NULL;

  fname = get_first_file(&dir, PLAYER_PLUGIN_DIR);

  while (fname != NULL) {
#ifdef _WIN32
    handle = LoadLibrary(fname);
#else
    handle = dlopen(fname, RTLD_LAZY);
#endif
    if (handle != NULL) {
      cptr = (codec_plugin_t *)DLL_GET_SYM(handle, "mpeg4ip_codec_plugin");
      if (cptr != NULL) {
	if (strcmp(cptr->c_version, PLUGIN_VERSION) == 0) {
	  codec_plugin_list_t *p;
	  p = (codec_plugin_list_t *)malloc(sizeof(codec_plugin_list_t));
	  if (p == NULL) exit(-1);
			  
	  p->codec = cptr;
	  p->dl_handle = handle;
	  p->next_codec = NULL;
			  
	  if (strcmp(cptr->c_type, "audio") == 0) {
	    p->next_codec = audio_codecs;
	    audio_codecs = p;
	    message(LOG_INFO, "plugin", "Adding audio plugin %s %s", 
		    cptr->c_name, fname);
	  } else if (strcmp(cptr->c_type, "video") == 0) {
	    p->next_codec = video_codecs;
	    video_codecs = p;
	    message(LOG_INFO, "plugin", "Adding video plugin %s %s", 
		    cptr->c_name, fname);
	  } else {
	    free(p);
	    message(LOG_CRIT, "plugin", "Unknown plugin type %s in plugin %s", 
		    cptr->c_type, fname);
	  }
	} else {
	  message(LOG_ERR, "plugin", "Plugin %s has wrong version %s", 
		  cptr->c_type, cptr->c_version);
	}
      } else {
	message(LOG_ERR, "plugin", "Can't find export point in plugin %s", 
		fname);
      }
    } else {
      message(LOG_ERR, "plugin", "Can't dlopen plugin %s - %s", fname,
	      DLL_ERROR());
    }
    fname = find_next_file(&dir, PLAYER_PLUGIN_DIR);
  }
  close_file_search(&dir);
}

/*
 * check_for_audio_codec
 * search the list of audio codecs for one that matches the parameters
 */
codec_plugin_t *check_for_audio_codec (const char *compressor,
				       format_list_t *fptr,
				       int audio_type,
				       int profile, 
				       const uint8_t *userdata,
				       uint32_t userdata_size)
{
  codec_plugin_list_t *aptr;
  int best_value = 0;
  codec_plugin_t *ret;

  ret = NULL;
  aptr = audio_codecs;
  while (aptr != NULL) {
    if (aptr->codec->c_compress_check != NULL) {
      int temp;
      temp = (aptr->codec->c_compress_check)(message,
					     compressor,
					     audio_type,
					     profile, 
					     fptr,
					     userdata,
					     userdata_size);
      if (temp > best_value) {
	best_value = temp;
	ret = aptr->codec;
      }
    }
    aptr = aptr->next_codec;
  }
  if (ret != NULL) {
    message(LOG_DEBUG, "plugin", 
	    "Found matching audio plugin %s", ret->c_name);
  }
  return (ret);
}

/*
 * check_for_video_codec
 * search the list of video plugins  for one that matches the parameters
 */
codec_plugin_t *check_for_video_codec (const char *compressor,
				       format_list_t *fptr,
				       int type,
				       int profile, 
				       const uint8_t *userdata,
				       uint32_t userdata_size)
{
  codec_plugin_list_t *vptr;
  int best_value = 0;
  codec_plugin_t *ret;

  ret = NULL;
  vptr = video_codecs;
  while (vptr != NULL) {
    if (vptr->codec->c_compress_check != NULL) {
      int temp;
      temp = (vptr->codec->c_compress_check)(message,
					     compressor,
					     type,
					     profile, 
					     fptr,
					     userdata,
					     userdata_size);
      if (temp > 0 &&
	  config.get_config_value(CONFIG_USE_MPEG4_ISO_ONLY) &&
	  strcmp(vptr->codec->c_name, "MPEG4 ISO") == 0) {
	temp = INT_MAX;
      }

      if (temp > best_value) {
	best_value = temp;
	ret = vptr->codec;
      }
    }
    vptr = vptr->next_codec;
  }
  if (ret != NULL) {
    message(LOG_DEBUG, "plugin", 
	    "Found matching video plugin %s", ret->c_name);
  }
  return (ret);
}

/*
 * video_codec_check_for_raw_file
 * goes through list of video codecs to see if "name" has a raw file
 * match
 */
int video_codec_check_for_raw_file (CPlayerSession *psptr,
				    const char *name)
{
  codec_plugin_list_t *vptr;
  codec_data_t *cifptr;
  char *desc[4];
  double maxtime;
  int slen = strlen(name);

  desc[0] = NULL;
  desc[1] = NULL;
  desc[2] = NULL;
  desc[3] = NULL;

  vptr = video_codecs;
  
  while (vptr != NULL) {

    if (vptr->codec->c_raw_file_check != NULL) {
      if (config.get_config_value(CONFIG_USE_MPEG4_ISO_ONLY) != 0 &&
	  strcmp("MPEG4 ISO", vptr->codec->c_name) != 0 && 
	  strcmp(".divx", name + slen - 5) == 0) {
	vptr = vptr->next_codec;
	continue;
      }
							   
      cifptr = vptr->codec->c_raw_file_check(message,
					     name,
					     &maxtime,
					     desc);
      if (cifptr != NULL) {
	player_debug_message("Found raw file codec %s", vptr->codec->c_name);
	CPlayerMedia *mptr;
   
	/*
	 * Create the player media, and the bytestream
	 */
	mptr = new CPlayerMedia(psptr);

	COurInByteStreamFile *fbyte;
	fbyte = new COurInByteStreamFile(vptr->codec,
					 cifptr,
					 maxtime);
	mptr->create_from_file(fbyte, TRUE);
	mptr->set_plugin_data(vptr->codec, cifptr, get_video_vft(), NULL);

	for (int ix = 0; ix < 4; ix++) 
	  if (desc[ix] != NULL) 
	    psptr->set_session_desc(ix, desc[ix]);

	if (maxtime != 0.0) {
	  psptr->session_set_seekable(1);
	}

	return 0;
      }
      return -1;
    } else {
      vptr = vptr->next_codec;
    }
  }
  return -1;
}

/*
 * audio_codec_check_for_raw_file
 * goes through the list of audio codecs, looking for raw file
 * support
 */
int audio_codec_check_for_raw_file (CPlayerSession *psptr,
				    const char *name)
{
  codec_plugin_list_t *aptr;
  codec_data_t *cifptr;
  char *desc[4];
  double maxtime;

  desc[0] = NULL;
  desc[1] = NULL;
  desc[2] = NULL;
  desc[3] = NULL;

  aptr = audio_codecs;
  while (aptr != NULL) {

    if (aptr->codec->c_raw_file_check != NULL) {
      cifptr = aptr->codec->c_raw_file_check(message,
					     name,
					     &maxtime,
					     desc);
      if (cifptr != NULL) {
	CPlayerMedia *mptr;
      
	mptr = new CPlayerMedia(psptr);

	COurInByteStreamFile *fbyte;
	fbyte = new COurInByteStreamFile(aptr->codec,
					 cifptr,
					 maxtime);
	mptr->create_from_file(fbyte, FALSE);
	mptr->set_plugin_data(aptr->codec, cifptr, NULL, get_audio_vft());

	for (int ix = 0; ix < 4; ix++) 
	  if (desc[ix] != NULL) 
	    psptr->set_session_desc(ix, desc[ix]);

	if (maxtime != 0.0) {
	  psptr->session_set_seekable(1);
	}

	return 0;
      }
    }
					   
    aptr = aptr->next_codec;
  }
  return -1;
}

/*
 * close_plugins
 * closes and frees plugin lists
 */
void close_plugins (void) 
{
  codec_plugin_list_t *p;

  while (audio_codecs != NULL) {
    p = audio_codecs;
	DLL_CLOSE(p->dl_handle);
    audio_codecs = audio_codecs->next_codec;
    free(p);
  }
  while (video_codecs != NULL) {
    p = video_codecs;
    DLL_CLOSE(p->dl_handle);
    video_codecs = video_codecs->next_codec;
    free(p);
  }
}

/* end file codec_plugin.cpp */

⌨️ 快捷键说明

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