用VLC打开rtsp流,并用OPencv处理播放
2015-12-25 14:07
429 查看
用VLC打开rtsp流,并用OPencv处理播放;
原始出处:https://forum.videolan.org/viewtopic.php?t=87031,
自己测试代码如下vlc2.2.1, opencv2.4.11
#define
_SKY_VIDEO_WIDTH 800
#define
_SKY_VIDEO_HEIGHT 600
#define _WINDOWN_SHOW
"YS_SHOW"
typedef
struct _CTX_
{
cv::Mat *image;
HANDLE mutex;
uchar* pixels;
}CTX, *PCTX;
//Vlc
libvlc_instance_t* pVlcInstance;
libvlc_media_player_t* pMediaPlayer;
libvlc_media_t* pMedia;
libvlc_event_manager_t *pEventManager;
//结构体
PCTXpContext;
static
void *lock(void* data,
void** p_pixels);
static
voiddisplay(void *data,
void *id);
static
void unlock(void *data,
void* id, void* const* p_pixels);
static void handleEvent(const
libvlc_event_t* pEvt,
void* pUserData);
//构造函数
const char* _vlc_args[] = {
"-I",
"dumy",
"--ignore-config",
"--plugin-path=./plugins",
"--no-video-title-show",
"--rtsp-tcp"
};
char* _playurl =
"rtmp://live.hkstv.hk.lxdns.com/live/hks";
//char*_playurl = "rtsp://=====;
//char*_playurl = "D:\\Video\\CitySky.mp4";
pVlcInstance = libvlc_new(sizeof(_vlc_args)/
sizeof(_vlc_args[0]),_vlc_args);
pContext = (PCTX)malloc(sizeof(CTX));
pContext->mutex = ::CreateMutex(NULL,
FALSE,
NULL);
pContext->image = new cv::Mat(_SKY_VIDEO_HEIGHT,
_SKY_VIDEO_WIDTH,
CV_8UC3);
pContext->pixels = (unsigned
char*)pContext->image->data;
//cv::imshow(_WINDOWN_SHOW,*pContext->image);
cv::namedWindow(_WINDOWN_SHOW);
//pMedia= libvlc_media_new_path(pVlcInstance, _playurl);//用这个可以播放本地的文件
pMedia = libvlc_media_new_location(pVlcInstance, _playurl);//
播放rtsp或者rtmp的时候用这个,
pMediaPlayer = libvlc_media_player_new_from_media(pMedia);
libvlc_media_release(pMedia);
libvlc_video_set_callbacks(pMediaPlayer, lock, unlock, display, pContext);
libvlc_video_set_format(pMediaPlayer,
"RV24",
_SKY_VIDEO_WIDTH, _SKY_VIDEO_HEIGHT,
_SKY_VIDEO_WIDTH * 24 / 8);
libvlc_media_player_play(pMediaPlayer);
void*
vlcopencv::lock(void*
data, void** p_pixels)
{
PCTX _ctx = (PCTX)data;
WaitForSingleObject(_ctx->mutex,
INFINITE);
// pixelwill be stored on image pixel space
*p_pixels = _ctx->pixels;
return
NULL;
}
void
vlcopencv::display(void *data,
void *id)
{
(void)data;
assert(id ==
NULL);
}
void
vlcopencv::unlock(void *data,
void* id,
void* const* p_pixels)
{
// getback data structure
PCTX _ctx = (PCTX)data;
/* VLCjust rendered the video, but we can also render stuff */
// showrendered image
std::string _text =
"VLC-OPENCV";
srand(time(NULL));
cv::putText(*_ctx->image, _text, cv::Point(15, 25), cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(rand()
%255, rand() %255,
rand() %255));
cv::imshow(_WINDOWN_SHOW,*_ctx->image);
ReleaseMutex(_ctx->mutex);
}
//如果中间要打开新的流串,把构造函数里的代码封装成一个函数,重新走一遍,否者程序会“停止运行”,注意内存的释放。
//用的是rmtp串测试的,最新的vlc支持rtmp,截图如下:
原始出处:https://forum.videolan.org/viewtopic.php?t=87031,
自己测试代码如下vlc2.2.1, opencv2.4.11
#define
_SKY_VIDEO_WIDTH 800
#define
_SKY_VIDEO_HEIGHT 600
#define _WINDOWN_SHOW
"YS_SHOW"
typedef
struct _CTX_
{
cv::Mat *image;
HANDLE mutex;
uchar* pixels;
}CTX, *PCTX;
//Vlc
libvlc_instance_t* pVlcInstance;
libvlc_media_player_t* pMediaPlayer;
libvlc_media_t* pMedia;
libvlc_event_manager_t *pEventManager;
//结构体
PCTXpContext;
static
void *lock(void* data,
void** p_pixels);
static
voiddisplay(void *data,
void *id);
static
void unlock(void *data,
void* id, void* const* p_pixels);
static void handleEvent(const
libvlc_event_t* pEvt,
void* pUserData);
//构造函数
const char* _vlc_args[] = {
"-I",
"dumy",
"--ignore-config",
"--plugin-path=./plugins",
"--no-video-title-show",
"--rtsp-tcp"
};
char* _playurl =
"rtmp://live.hkstv.hk.lxdns.com/live/hks";
//char*_playurl = "rtsp://=====;
//char*_playurl = "D:\\Video\\CitySky.mp4";
pVlcInstance = libvlc_new(sizeof(_vlc_args)/
sizeof(_vlc_args[0]),_vlc_args);
pContext = (PCTX)malloc(sizeof(CTX));
pContext->mutex = ::CreateMutex(NULL,
FALSE,
NULL);
pContext->image = new cv::Mat(_SKY_VIDEO_HEIGHT,
_SKY_VIDEO_WIDTH,
CV_8UC3);
pContext->pixels = (unsigned
char*)pContext->image->data;
//cv::imshow(_WINDOWN_SHOW,*pContext->image);
cv::namedWindow(_WINDOWN_SHOW);
//pMedia= libvlc_media_new_path(pVlcInstance, _playurl);//用这个可以播放本地的文件
pMedia = libvlc_media_new_location(pVlcInstance, _playurl);//
播放rtsp或者rtmp的时候用这个,
pMediaPlayer = libvlc_media_player_new_from_media(pMedia);
libvlc_media_release(pMedia);
libvlc_video_set_callbacks(pMediaPlayer, lock, unlock, display, pContext);
libvlc_video_set_format(pMediaPlayer,
"RV24",
_SKY_VIDEO_WIDTH, _SKY_VIDEO_HEIGHT,
_SKY_VIDEO_WIDTH * 24 / 8);
libvlc_media_player_play(pMediaPlayer);
void*
vlcopencv::lock(void*
data, void** p_pixels)
{
PCTX _ctx = (PCTX)data;
WaitForSingleObject(_ctx->mutex,
INFINITE);
// pixelwill be stored on image pixel space
*p_pixels = _ctx->pixels;
return
NULL;
}
void
vlcopencv::display(void *data,
void *id)
{
(void)data;
assert(id ==
NULL);
}
void
vlcopencv::unlock(void *data,
void* id,
void* const* p_pixels)
{
// getback data structure
PCTX _ctx = (PCTX)data;
/* VLCjust rendered the video, but we can also render stuff */
// showrendered image
std::string _text =
"VLC-OPENCV";
srand(time(NULL));
cv::putText(*_ctx->image, _text, cv::Point(15, 25), cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(rand()
%255, rand() %255,
rand() %255));
cv::imshow(_WINDOWN_SHOW,*_ctx->image);
ReleaseMutex(_ctx->mutex);
}
//如果中间要打开新的流串,把构造函数里的代码封装成一个函数,重新走一遍,否者程序会“停止运行”,注意内存的释放。
//用的是rmtp串测试的,最新的vlc支持rtmp,截图如下:
相关文章推荐
- linux通过远程桌面访问windows
- 嵌入式Linux学习-----根文件系统
- 嵌入式Linux学习-------Linux内核移植
- centos6.4安装mysql5.5
- 《循序渐进Linux》第二版即将出版发行(附封面)
- 《循序渐进Linux》第二版即将出版发行(附封面)
- 嵌入式Linux学习-----u-boot移植
- 搭建Apache+mod_wsgi+python+flask+virtualenv网站正式环境
- Web.xml配置详解之context-param
- 在线旅游平台如何借监控宝确保第三方API高可用
- 帆软报表FineReport中数据连接之Tomcat配置JNDI连接
- 在线旅游平台如何借监控工具确保第三方API高可用
- window启动关闭nginx
- centos6.4合并两个DVD作为本地yun源
- with check option(视图 )
- Linux常用Terminal命令與快捷鍵參考
- Linux平台下安装SSH,免密码登录
- CentOS安装IPython
- Roy Docker Image Build
- OpenCV 透视变换实例