Feeding vlc with memory stored data : option imem

This forum is about all development around libVLC.
asqz
New Cone
New Cone
Posts: 4
Joined: 25 Jun 2013 15:34

Feeding vlc with memory stored data : option imem

Postby asqz » 28 Jun 2013 10:59

Hi,

I am developing an application using libVLC in which I feed vlc with data stored in my memory for streaming it. The only way I found to do this is by configuring vlc with the option imem :
--imem-width
--imem-height
--imem-get
--imem-release
--imem-data
I know that imem-get and imem-release are pointer to callback function. But I don't know what is the definition that this functions must match with. Could you give me the definition of this callback functions and the description of their arguments/return ?

I know that defining a vlc instance (libvlc_instance_t) with arguments is a bad practice, so is it possible to execute the same process with functions instead of command options ?

Rémi Denis-Courmont
Developer
Developer
Posts: 15267
Joined: 07 Jun 2004 16:01
VLC version: master
Operating System: Linux
Contact:

Re: Feeding vlc with memory stored data : option imem

Postby Rémi Denis-Courmont » 28 Jun 2013 17:46

Functions should be added to wrap custom input streams, just like for audio and video output. Nobody volunteered though.
Rémi Denis-Courmont
https://www.remlab.net/
Private messages soliciting support will be systematically discarded

marcov83
New Cone
New Cone
Posts: 3
Joined: 08 Oct 2013 16:58

Re: Feeding vlc with memory stored data : option imem

Postby marcov83 » 08 Oct 2013 17:44

I have developed an application with imem/smem module with libvlc. I have read the source code of these modules to understand how them work, due to lack of documentation.
It works very good.

So, i can help you (if you have not solved yet).

the most important parameters are imem-get/imem-release/imem-data/imem-cat, the others are self-explenatory (imem-width, imem-height, imem-channels and so forth). The callback-function signature are:
imem-get ==> int VLCGetBuffers(void *data, const char *cookie, int64_t *dts, int64_t *pts, unsigned *flags, size_t * bufferSize, void ** buffer);
imem-release ==> void VLCReleaseBuffers (void *data, const char *cookie, size_t bufferSize, void * buffer);
For the imem-get:
-void *data: custom data passed to the callback (useful for "this" pointers). it is the "imem-data" value passed in the module arguments list;
-const char *cookie: custom string passed as module parameter;
-int64_t *dts, int64_t *pts: DTS, PTS for the stream (fundamental);
-unsigned *flags: flags, but reading the code seems to be not used;
-size_t *bufferSize: buffer size (expressed in bytes);
-void **buffer: the data you want to pass to vlc.

For the imem-release:
-void *data: same as imem-get;
-const char *cookie: as above;
-size_t bufferSize: size of buffer;
-void *buffer: buffer

The paradigm for the module is easy. You pass the data in the imem-get assign directy to *buffer and fill the other fields with the correct data (size, pts, dts); in the imem-release you will called to free that buffer (in order to not call new/malloc i use a static buffer between calls). Consider that VLC core will COPY the data in a internal block strutcure, so you should lock the buffer between the imem-get and the imem-release call (if you are in a multithreading scenario).
The first thing to do is to init the module...this is the worst aspect of this module. The callback function are passed as "long int" converted as strings.... to be more clear I show the code i used (stream PCM):
char *vlc_args[12];

vlc_args[0] = "-vvvvv";
vlc_args[1] = (char*)calloc(200,1);
sprintf(vlc_args[1], "--imem-get=%ld", my_get_cb);
vlc_args[2] = (char*)calloc(200,1);
sprintf(vlc_args[2], "--imem-release=%ld", my_release_cb);
vlc_args[3] = (char*)calloc(200,1);
sprintf(vlc_args[3], "--imem-cat=1"); //CAT 1 == AUDIO
vlc_args[4] = (char*)calloc(200,1);
sprintf(vlc_args[4], "--imem-data=%ld", /** my context custom data to be passed callbacks **/);
vlc_args[5] = "--imem-id=0";
vlc_args[6] = (char*)calloc(200,1);
sprintf(vlc_args[6], "--imem-codec=s16l"); //CODEC, format of the data passed to vlc in the buffers
vlc_args[7] = (char*)calloc(200,1);
sprintf(vlc_args[7], "--imem-channels=%d", mNumInputs); //number of channels
vlc_args[8] = (char *)calloc(200,1);
sprintf(vlc_args[8], "--imem-samplerate=%d", mSampleFreq); //sample frequency
vlc_args[9] = "--rtp-caching=100";

//create vlc
mVlcInstance = libvlc_new(sizeof(vlc_args)/sizeof(char *), vlc_args);

/***
other initializations...then start stream!
***/

//add instance to the VLM (but you can simply start play)
libvlc_vlm_add_broadcast(mVlcInstance, VLM_STREAM_NAME, "imem://", mSoutString, 0, 0, 1, 1);
libvlc_vlm_play_media(mVlcInstance, VLM_STREAM_NAME);
(the mSoutString is a string for the sout module, you can use if you want for on-the fly transcoding or network streaming).

One important aspect is the use of the imem-cat parameter. If you use AUDIO (imem-cat == 1) or VIDEO (imem-cat == 2), VLC will load the module as ACCESS-DEMUX so it will ask you for PTS and DTS. The calculation of correct PTS and DTS require you to parse the stream if is encoded (not always easy step...i use PCM so the calculation is very easy). Otherwise, if you don't want to use these category, you can use imem-cat == 4; with this option VLC will load the submodule ACCESS, and will not ask you for DTS and PTS, so you simply pass the raw data and the core will demux/decode the stream for you. with imem-cat == 4 you can pass directy piece of file (fread to be clear).

you can read this older post, that is clearer than mine!
https://forum.videolan.org/viewtopic.php?f=32&t=93842

hope this helps.


Return to “Development around libVLC”

Who is online

Users browsing this forum: No registered users and 9 guests