基于OpenCV的视频图像组态 (13):VLC Player解码帧数据
来源:互联网 发布:哪些网站可以注册域名 编辑:程序博客网 时间:2024/04/30 14:03
网上示例
vlc是一套优秀的开源媒体库,其特点是提供了完整的流媒体框架, 用它可以非常方便的实现抓取解码帧的功能。
与此功能有关的关键API为
libvlc_video_set_callbacks /*设置回调,用来抓取解码后的帧*/
libvlc_video_set_format /*设置解码帧的格式 yuv or rgba ?*/
这个函数将三个函数指针作为参数
/*callback function, lock the shared memory, and tell vlc
where to put the output frame data*/
static void *lock(void *data, void **p_pixels);
/*##get the out frame data AND u can save it to file, or sent it
to a next module*/
static void unlock(void *data, void *id, void *const *p_pixels);
/*how to display the result frame data, u can let vlc do not pop out the displaying gui via this fuction. */
static void display(void *data, void *id);
下面是完整示例子:
#include "stdafx.h"#include <Windows.h>#include "vlc/vlc.h"#include <vector>#include <qmutex>#include <sstream>#include <qimage> QMutex g_mutex;bool g_isInit = false;int IMG_WIDTH = 640;int IMG_HEIGHT = 480;char in_buffer[640*480*4];char out_buffer[640*480*4];FILE *local;int frameNum = 0; const char* TestFile = "b040_20170106.dat";//////////////////////////////////////////////////////////////////////////static void *lock(void *data, void **p_pixels){g_mutex.lock();*p_pixels = out_buffer; /*tell VLC to put decoded data to this buffer*/return 0; /* picture identifier, not needed here */} /*##get the argb picture AND save to file*/static void unlock(void *data, void *id, void *const *p_pixels){QImage image((unsigned char*)out_buffer,640,480,QImage::Format_ARGB32);std::ostringstream oss;oss << "d:/img"<< frameNum<< ".jpg";frameNum++;image.save(oss.str().c_str());g_mutex.unlock();} static void display(void *data, void *id){/* do not display the video */(void) data;} //////////////////////////////////////////////////////////////////////////int main(int argc, char* argv[]){libvlc_instance_t * inst;libvlc_media_player_t *mp;libvlc_media_t *m; libvlc_time_t length;int wait_time=5000; /* Load the VLC engine */inst = libvlc_new (int(options.size()), options.data()); // Configure any transcoding or streaming// options for the media source.options.clear(); //Create a new item//Method 1://m = libvlc_media_new_location (inst, "file:///F:\\movie\\cuc_ieschool.flv");//Screen Capture//m = libvlc_media_new_location (inst, "screen://");//Method 2:m = libvlc_media_new_path (inst, "D:\\warehouse\\data\\615\\haze.mp4");/* Create a media player playing environment */mp = libvlc_media_player_new_from_media (m); /* No need to keep the media now */libvlc_media_release (m); /*##comment the followint 2 lines , if you want the out frame display in screen*/libvlc_video_set_callbacks(mp, lock, unlock, display, 0);libvlc_video_set_format(mp, "RGBA", IMG_WIDTH, IMG_HEIGHT,IMG_WIDTH*4); // play the media_playerlibvlc_media_player_play (mp); //wait until the tracks are created_sleep (wait_time);length = libvlc_media_player_get_length(mp);IMG_WIDTH = libvlc_video_get_width(mp);IMG_HEIGHT = libvlc_video_get_height(mp);printf("Stream Duration: %ds\n",length/1000);printf("Resolution: %d x %d\n",IMG_WIDTH,IMG_HEIGHT); //Let it play_sleep (length-wait_time); // Stop playinglibvlc_media_player_stop (mp); // Free the media_playerlibvlc_media_player_release (mp); libvlc_release (inst); return 0;}改编实现
仔细研究网上代码,最终将VLCWrapper改造一下。
static void *lock(void *opaque, void **plane) { VLCWrapper *vlcWrapper = (VLCWrapper*)opaque; vlcWrapper->Lock(); *plane = vlcWrapper->FMat.data; return NULL;} static void unlock(void *opaque, void *pic, void * const *plane) { VLCWrapper *vlcWrapper = (VLCWrapper*)opaque; vlcWrapper->Draw(); vlcWrapper->Unlock();} static void display(void *opaque, void *pic) { (void)opaque;} void __fastcall VLCWrapper::Lock() { EnterCriticalSection(&g_VlcCriticalSection);} void __fastcall VLCWrapper::Unlock() { LeaveCriticalSection(&g_VlcCriticalSection);}void __fastcall VLCWrapper::Draw() { static int radius = 100; // 测试画一个不断长大的圆 radius += 3; if(radius > 1000) radius = 100; circle(FMat, cv::Point(100, 100), radius / 10, cv::Scalar(255, 255, 255), 3); GlobalOpenCVObject->DrawMat(hWnd, FMat, FDisplayWidth, FDisplayHeight);} void __fastcall VLCWrapper::SetTriggleCallback(bool value) {Lock();try {FTriggleCallback = value;if(FTriggleCallback)libvlc_video_set_callbacks(pImpl_->pMediaPlayer_, lock, unlock, display, this);elselibvlc_video_set_callbacks(pImpl_->pMediaPlayer_, NULL, NULL, NULL, NULL);} __finally {Unlock();}}演示效果
(因为视频文件大小限制,所以最终生成的帧频为2,导致看起来很不流畅)
- 基于OpenCV的视频图像组态 (13):VLC Player解码帧数据
- 基于OpenCV的视频图像组态 (1) :时钟
- 基于OpenCV的视频图像组态 (2) :动画总体
- 基于OpenCV的视频图像组态 (4) :劈裂动画效果
- 基于OpenCV的视频图像组态 (5) :擦除动画效果
- 基于OpenCV的视频图像组态 (6): 形状动画效果
- 基于OpenCV的视频图像组态 (7) :轮子动画效果
- 基于OpenCV的视频图像组态 (9):CEF浏览器初步
- 基于OpenCV的视频图像组态 (14):音量控制
- 基于OpenCV的视频图像组态 (3):常见PPT动画1
- 基于OpenCV的视频图像组态 (8) :随机线条动画效果
- 基于OpenCV的视频图像组态 (10): CEF浏览器与图形软件互嵌
- 基于OpenCV的视频图像组态 (11): CEF浏览器与C++通信
- 基于OpenCV的视频图像组态 (12): 翻转式由远到近动画效果
- 视频帧数的控制
- v4l2采集视频,opencv处理帧数据第一难关:qt的QImage转换为opencv的IplImage 函数代码实现
- 基于OPENCV的视频图像处理算法和应用
- 基于FFMPEG的视频解码
- MySql常用SQL语句
- 413. Arithmetic Slices
- 点击标题就可以选中输入框input
- JDBC基本实现原理
- 论SQL语句中的Left join-多表关系
- 基于OpenCV的视频图像组态 (13):VLC Player解码帧数据
- oracle数据库中主要文件
- poj1251 Jungle Roads
- 在CSS中,编写“新闻列表”2.0版
- NOIP2013 神经网络(拓扑)
- Yii2.0实现语言包切换功能
- poj1258 Agri-Net
- poj 1873
- C语言趣味一百道_第十二题