最近用 dv2xvid 这个东东很多,上两周几乎每天都用它跑一个晚上压缩2个小时的视频。于是又萌发了把它改进得更通用的念头。
目前 dv2xvid 有一个很严重的问题,就是只支持 xvid-1.1.0-beta2 的压缩。而事实上目前大家用的最多的是应该都是正式版本,比如 1.0.3 或者 1.1.0 之类。如果想能支持更多版本的 xvid codec,就必须能在压缩之前判断 xvid 的版本。
恶心的是安装的 xvid 的目标文件没有 Windows Dll 的版本属性,查了半天,调用 xvidcore.dll 里面的一个函数可以获得 xvidcore.dll 的版本号:
#include "xvid.h"{ xvid_gbl_info_t info; HINSTANCE m_hdll;
memset(&info, 0, sizeof(info)); info.version = XVID_VERSION; m_hdll = LoadLibrary(XVID_DLL_NAME); if (m_hdll != NULL) { ((int (__cdecl *)(void *, int, void *, void*))GetProcAddress(m_hdll, "xvid_global"))(0, XVID_GBL_INFO, &info, NULL); printf("xvidcore.dll version %d.%d.%d (\"%s\")", XVID_VERSION_MAJOR(info.actual_version), XVID_VERSION_MINOR(info.actual_version), XVID_VERSION_PATCH(info.actual_version), info.build);
FreeLibrary(m_hdll); } else { printf("xvidcore.dll not found!"); }}
如果在 python 里面做到这个事情,可以通过 ctypes 模块来完成。但查遍 ctypes 有关的中文文档,都没有关于怎样在函数中传入结构体指针的说明,只能自己 google 之,后来发现应该这么来做:
from ctypes import *### 定义结构体class xvid_gbl_info_t(Structure): _fields_ = [("version", c_int), ("actual_version", c_int), ("build", c_char_p), ("cpu_flags", c_uint), ("num_threads", c_int)]
XVID_GBL_INFO = 1
dll = cdll.load("c:\\windows\\system32\\xvidcore.dll")xvid_global = dll.xvid_global
### 构造 pinfo 结构体, 然后赋值pinfo = xvid_gbl_info_t()pinfo.version = ((((1)&0xff)<<16) | (((0)&0xff)<<8) | ((0)&0xff))
x = c_voidp(0)y = c_voidp(0)### 用 byref 传入指针if xvid_global(x, c_int(XVID_GBL_INFO), byref(pinfo), y) == 0: major_version = (pinfo.actual_version>>16)&0xff minor_version = (pinfo.actual_version>>8)&0xff patch_version = (pinfo.actual_version>>0)&0xff print major_version, minor_version, patch_version print pinfo.build print pinfo.cpu_flags print pinfo.num_threadselse: print "ERROR"
相关资源:敏捷开发V1.0.pptx