首页 > 代码库 > 用libvlc 播放指定缓冲区中的视频流
用libvlc 播放指定缓冲区中的视频流
有时候,我们需要播放别的模块传输过来的视频流,VLC提供了这样的机制,但一般很少这样用,下面的例子实现了这样的功能。
其中用到一个关键的模块 imem. vlc提供多种创建媒体的方式,如要从指定缓存中数据,可以如下方式指定
// Create a media item from file m = libvlc_media_new_location (inst, "imem://"); /*##use memory as input*/
下面是完整的示例
// vlcTest.cpp : 定义控制台应用程序的入口点。 // #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"; ////////////////////////////////////////////////////////////////////////// /** \brief Callback method triggered by VLC to get image data from a custom memory source. This is used to tell VLC where the data is and to allocate buffers as needed. To set this callback, use the "--imem-get=<memory_address>" option, with memory_address the address of this function in memory. When using IMEM, be sure to indicate the format for your data using "--imem-cat=2" where 2 is video. Other options for categories are 0 = Unknown, 1 = Audio, 2 = Video, 3 = Subtitle, 4 = Data When creating your media instance, use libvlc_media_new_location and set the location to "imem:/" and then play. \param[in] data Pointer to user-defined data, this is your data that you set by passing the "--imem-data=http://www.mamicode.com/" option when initializing VLC instance. \param[in] cookie A user defined string. This works the same way as data, but for string. You set it by adding the "--imem-cookie=<your_string>" option when you initialize VLC. Use this when multiple VLC instances are running. \param[out] dts The decode timestamp, value is in microseconds. This value is the time when the frame was decoded/generated. For example, 30 fps video would be every 33 ms, so values would be 0, 33333, 66666, 99999, etc. \param[out] pts The presentation timestamp, value is in microseconds. This value tells the receiver when to present the frame. For example, 30 fps video would be every 33 ms, so values would be 0, 33333, 66666, 99999, etc. \param[out] flags Unused,ignore. \param[out] bufferSize Use this to set the size of the buffer in bytes. \param[out] buffer Change to point to your encoded frame/audio/video data. The codec format of the frame is user defined and set using the "--imem-codec=<four_letter>," where 4 letter is the code for your codec of your source data. */ int MyImemGetCallback (void *data, const char *cookie, int64_t *dts, int64_t *pts, unsigned *flags, size_t * bufferSize, void ** buffer) { static int64_t _dts = 0, _pts = 0; if (!g_isInit){ /*load local file*/ local = fopen(TestFile,"rb"); if (!local){ return true; } size_t count = fread(in_buffer,1,IMG_WIDTH*IMG_HEIGHT*4,local); *bufferSize = count; *buffer = in_buffer; g_isInit = true; *dts = _dts; *pts = _pts; _dts+=30; _pts+=30; return 0 ; } size_t count = fread(in_buffer,1,IMG_WIDTH*IMG_HEIGHT*4,local); *bufferSize = count; *buffer = in_buffer; *dts = _dts; *pts = _pts; _dts+=30; _pts+=30; if(count>0) { printf("read %d bytes\n",count); return 0; }else{ return true; /*eof*/ } } /** \brief Callback method triggered by VLC to release memory allocated during the GET callback. To set this callback, use the "--imem-release=<memory_address>" option, with memory_address the address of this function in memory. \param[in] data Pointer to user-defined data, this is your data that you set by passing the "--imem-data=http://www.mamicode.com/" option when initializing VLC instance. \param[in] cookie A user defined string. This works the same way as data, but for string. You set it by adding the "--imem-cookie=<your_string>" option when you initialize VLC. Use this when multiple VLC instances are running. \param[int] bufferSize The size of the buffer in bytes. \param[out] buffer Pointer to data you allocated or set during the GET callback to handle or delete as needed. */ int MyImemReleaseCallback (void *data, const char *cookie, size_t bufferSize, void * buffer) { // Since I did not allocate any new memory, I don‘t need // to delete it here. However, if you did in your get method, you // should delete/free it here. return 0; } ////////////////////////////////////////////////////////////////////////// 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; std::vector<const char*> options; std::vector<const char*>::iterator option; options.push_back("--no-video-title-show"); char imemDataArg[256]; sprintf(imemDataArg, "--imem-data=http://www.mamicode.com/%#p", in_buffer); options.push_back(imemDataArg); char imemGetArg[256]; sprintf(imemGetArg, "--imem-get=%#p", MyImemGetCallback); options.push_back(imemGetArg); char imemReleaseArg[256]; sprintf(imemReleaseArg, "--imem-release=%#p", MyImemReleaseCallback); options.push_back(imemReleaseArg); options.push_back("--imem-cookie=\"IMEM\""); options.push_back("--imem-codec=H264"); // Video data. options.push_back("--imem-cat=2"); /* 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 media item from file m = libvlc_media_new_location (inst, "imem://"); /*##use memory as input*/ // Set media options for(option = options.begin(); option != options.end(); option++){ libvlc_media_add_option(m, *option); } /* 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); // 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; }
以上代码要注意的是: 用OPTIONS 告诉VLC , 要使用imem作为输入,还要告诉vlc 其中用到哪些回调函数, 这个与直接设置回调的方式不一样, 它用options中的字符串表示。
用libvlc 播放指定缓冲区中的视频流
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。