Stream to memory (smem) tutorial

From VideoLAN Wiki
Revision as of 12:30, 19 June 2010 by Berthe (talk | contribs) (→‎Implementing callbacks: Added some info about PCM (TBC))
Jump to navigation Jump to search

Here is a small tutorial intended to make a quick tour of the stream to memory module (smem) , included in VLC 1.1.0. This module allows you to write a code which handles the video and audio data read by VLC. This page shows a basic code written in C which uses this module.

Including VLC library

An easy part : we just have to include one header. Don't forget to have the linker add the library.

#include <stdio.h>
#include <stdint.h>

#include <vlc/vlc.h>

Defining callbacks

VLC sends you the data you need via two functions that you define yourself. They will be run before and after the data is rendered. There are two functions for the audio data, and two for the video one. In this example I will just show how to deal with audio data, the process is the same for video handling.

void prepareRender(void* p_audio_data, uint8_t** pp_pcm_buffer , unsigned int size); // Audio prerender callback
void handleStream(void* p_audio_data, uint8_t* p_pcm_buffer, unsigned int channels, unsigned int rate, unsigned int nb_samples, unsigned int bits_per_sample, unsigned int size, int64_t pts); // Audio postrender callback
// Video prerender and postrender callbacks not implemented.

Creating a VLC instance

As with every application you build with libvlc, you have to initialize the library. But you also have to tell VLC the address of each callback you wrote. This is made by writing the address in the parameters used to launch VLC.

int main(int argc, char **argv)
{
        // VLC pointers
        libvlc_instance_t *vlcInstance;
        libvlc_media_player_t *mp;
        libvlc_media_t *media;

        // VLC options
        char smem_options[256];

        sprintf(smem_options, "#transcode{acodec=s16l}:smem{audio-postrender-callback=%lld,audio-prerender-callback=%lld}",
                // We are using transcode because smem only support raw audio and video formats

                 (long long int)(intptr_t)(void*)&handleStream, (long long int)(intptr_t)(void*)&prepareRender);
                // We print (as a decimal value) the addresses. Note that you can also define smem-audio-data : this pointer
                // will be passed to your callbacks (it may be useful to retrive some extra informations) but isn't required at all.

        const char * const vlc_args[] = {
              "-I", "dummy", // Don't use any interface
              "--ignore-config", // Don't use VLC's config
              "--extraintf=logger", // Log anything
              "--verbose=2", // Be much more verbose then normal for debugging purpose
              "--sout", smem_options // Stream to memory
               };

        // We launch VLC
        vlcInstance = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);

        mp = libvlc_media_player_new(vlcInstance);

        // To be continued.

        return 0;
}

Implementing callbacks

The smem module sends us the data in PCM format.

TODO: Here some text describing the behaviour of callbacks

void prepareRender (void* p_audio_data, uint8_t** pp_pcm_buffer , unsigned int size)
{
        // TODO: Lock the mutex

        *pp_pcm_buffer = // TODO
}

void handleStream(void* p_audio_data, uint8_t* p_pcm_buffer, unsigned int channels, unsigned int rate, unsigned int nb_samples, unsigned int bits_per_sample, unsigned int size, int64_t pts )
{
        // TODO: explain how data should be handled
        // TODO: Unlock the mutex
}