我正在尝试使用libvlc
从网络流读取帧,然后使用opencv
对这些帧应用一些处理。这是我用来检索帧的代码:
struct ctx
{
IplImage* image;
HANDLE mutex;
uchar* pixels;
};
void *lock(void *data, void**p_pixels)
{
struct ctx *ctx = (struct ctx*)data;
WaitForSingleObject(ctx->mutex, INFINITE);
*p_pixels = ctx->pixels;
return NULL;
}
void display(void *data, void *id)
{
(void) data;
assert(id == NULL);
}
void unlock(void *data, void *id, void *const *p_pixels){
struct ctx *ctx = (struct ctx*)data;
// VLC just rendered the video, but we can also render stuff
uchar *pixels = (uchar*)*p_pixels;
cvShowImage("image", ctx->image);
ReleaseMutex(ctx->mutex);
assert(id == NULL); // picture identifier, not needed here
}
int main()
{
cvNamedWindow("image", CV_WINDOW_AUTOSIZE);
libvlc_media_t* media = NULL;
libvlc_media_player_t* mediaPlayer = NULL;
//char const* vlc_argv[] = {"--plugin-path", "C:\Users\Oscar\Documents\libvlc\vlc-1.1.4"};
libvlc_instance_t* instance = libvlc_new(0,NULL);
mediaPlayer = libvlc_media_player_new(instance);
media = libvlc_media_new_location(instance, "rtsp://134.202.84.79:554/user=a&password=abcdef&channel=6&stream=0.sdp/");
struct ctx* context = ( struct ctx* )malloc( sizeof( *context ) );
context->mutex = CreateMutex(NULL, FALSE,NULL);
//context->image = cvCreateImage(cvSize(libvlc_video_get_height(mediaPlayer), libvlc_video_get_width(mediaPlayer)), IPL_DEPTH_8U, 4);
context->image = cvCreateImage(cvSize(640,480), IPL_DEPTH_8U, 4);
context->pixels = (unsigned char *)context->image->imageData;
libvlc_media_player_set_media( mediaPlayer, media);
libvlc_video_set_callbacks(mediaPlayer, lock, unlock, display, context);
libvlc_video_set_format(mediaPlayer, "RV32", 640, 480, 640*4);
libvlc_media_player_play(mediaPlayer);
while(true)
{
if (waitKey(30)==27)
{
break;
}
}
return 0;
}
问题是,这在调试模式下工作时很好,但当我切换到发布模式时,它说:
过程入口点cvCreateImage无法在动态链接库libvcl .dll中找到。
我也尝试改变链接优化标志,但问题仍然存在。
我刚刚遇到了一个类似的glut问题(我的应用程序试图在libvcl .dll中找到一个glut-procedure)。
虽然我不知道是什么原因导致这个问题,但我能用下面的方法解决它:
我没有使用VLC附带的.lib文件,而是按照以下步骤从dll文件生成lib。
使用这个库为我解决了这个问题,尽管我不知道为什么它会首先发生。
我似乎已经修复了它。在另一篇关于VS 2008编译问题的文章中(在调试中一切都很好)。切换并在发布模式下构建所有内容,它就会崩溃)。我注意到他们一直在调整/OPT
链接标志从/OPT:REF
到/OPT:NOREF
,这似乎解决了他们遇到的另一个问题。
- 打开项目的Property Pages对话框。有关详情,请参阅> Visual c++ Project Properties.
- 选择链接器文件夹
- 选择命令行属性页
- 在"附加选项"中输入选项:
/OPT:NOREF
REF | NOREF/OPT:REF删除了从未被引用过的函数和/或数据,而>/OPT:NOREF保留了从未被引用过的函数和/或数据。
LINK
默认删除未引用的打包函数。如果对象使用/Gy
选项进行编译,则该对象包含打包函数(comdat)。这种优化称为传递COMDAT消除。要覆盖此默认值并在程序中保留未引用的comdat,请指定/OPT:NOREF
。您可以使用/INCLUDE
选项来覆盖特定符号的删除。