用libvlc 抓取解码后的帧数据

Posted 小阳明

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用libvlc 抓取解码后的帧数据相关的知识,希望对你有一定的参考价值。

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_player libvlc_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 playing libvlc_media_player_stop (mp); // Free the media_player libvlc_media_player_release (mp); libvlc_release (inst); return 0; }

 

以上是关于用libvlc 抓取解码后的帧数据的主要内容,如果未能解决你的问题,请参考以下文章

AVFrame 解析

用OpenCV和Python识别二维码与条形码

H.264/AVC视频编解码技术详解二十六帧间预测编码:宏块的帧间预测解码

H.264/AVC视频编解码技术详解二十六帧间预测编码:宏块的帧间预测解码

用爬虫抓取网页得到的源代码和浏览器中看到的不一样运用了啥技术?

libVLC 视频缩放