Page 1 of 1

libVLC as video output

Posted: 28 Nov 2008 16:02
by bercik
libVLC can be use as input video to my app (via vmem - http://wiki.videolan.org/LibVLC_SampleCode_SDL),
but is possible (and if yes how made it?) use libVLC as (network streaming) video-output (for example from SDL app)?

Re: libVLC as video output

Posted: 02 Dec 2008 01:05
by bercik
I don't find simple metod to use libvlc as output from rendering software, so I write decoder module (uses fake acess module). This module make possible making video stream from raw-image generating (to memory) from rendering program uses libvlc.

Code: Select all

/***************************************************************************** * invmem_decoder.c: memory video driver for vlc ***************************************************************************** * Copyright (C) 2008 the VideoLAN team * $Id$ * * Authors: Robert Paciorek <robert@opcode.eu.org> * based on: * - vmem video output module (Gildas Bazin <gbazin@videolan.org>) * - png video decodec module (Sam Hocevar <sam@zoy.org>) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /* Bulding outside VLC tree: INSTAL_PATH='/home/rrp/Desktop/SYMW/moduly' mkdir .libs; mkdir .deps gcc -std=gnu99 -I/usr/include/vlc/plugins -DMOD_DESC="\"Memory video decoder RRP build `date +"%F %T"`\"" -DSYS_LINUX -D_FILE_OFFSET_BITS=64 -D__USE_UNIX98 -D_LARGEFILE64_SOURCE -D_REENTRANT -D_THREAD_SAFE -D__LIBVLC__ -D__PLUGIN__ -DMODULE_NAME=invmem_decoder -DMODULE_NAME_IS_invmem_decoder -DMODULE_STRING=\"invmem_decoder\" -O3 -ffast-math -funroll-loops -mtune=pentium2 -fomit-frame-pointer -Wall -Wextra -Wsign-compare -Wundef -Wpointer-arith -Wbad-function-cast -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wvolatile-register-var -MT libinvmem_decoder_plugin_la-invmem_decoder.lo -MD -MP -MF .deps/libinvmem_decoder_plugin_la-invmem_decoder.Tpo -c invmem_decoder.c -fPIC -DPIC -o .libs/libinvmem_decoder_plugin_la-invmem_decoder.o mv -f .deps/libinvmem_decoder_plugin_la-invmem_decoder.Tpo .deps/libinvmem_decoder_plugin_la-invmem_decoder.Plo rm -fr .libs/libinvmem_decoder_plugin.la .libs/libinvmem_decoder_plugin.lai .libs/libinvmem_decoder_plugin.so .libs/libinvmem_decoder_plugin.soT gcc -std=gnu99 -shared .libs/libinvmem_decoder_plugin_la-invmem_decoder.o -Wl,-rpath -Wl, /usr/lib/libvlccore.so -lhal -ldbus-1 -lrt -lpthread -ldl -lm -mtune=pentium2 -Wl,-soname -Wl,libinvmem_decoder_plugin.so -o .libs/libinvmem_decoder_plugin.so ( cd ".libs" && rm -f "libinvmem_decoder_plugin.la" && ln -s "../libinvmem_decoder_plugin.la" "libinvmem_decoder_plugin.la" ) gcc -std=gnu99 -shared .libs/libinvmem_decoder_plugin_la-invmem_decoder.o -L/usr/local/lib -lvlccore -lhal -ldbus-1 -lrt -lpthread -ldl -lm -mtune=pentium2 -Wl,-soname -Wl,libinvmem_decoder_plugin.so -o .libs/libinvmem_decoder_plugin.so mkdir "$INSTAL_PATH" /usr/bin/install -c .libs/libinvmem_decoder_plugin.so "$INSTAL_PATH/libinvmem_decoder_plugin.so" rm -fr .libs mkdir .deps libinvmem_decoder_plugin_la-invmem_decoder.Tpo libinvmem_decoder_plugin_la-invmem_decoder.o */ #define N_(str) (str) /***************************************************************************** * Preamble *****************************************************************************/ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <vlc_common.h> #include <vlc_plugin.h> #include <vlc_codec.h> #include <vlc_image.h> #include <vlc_filter.h> #include <vlc_charset.h> /***************************************************************************** * Local prototypes *****************************************************************************/ static int OpenDecoder ( vlc_object_t * ); static void CloseDecoder ( vlc_object_t * ); static picture_t *DecodeBlock ( decoder_t *, block_t ** ); /***************************************************************************** * Module descriptor *****************************************************************************/ #define T_WIDTH N_( "Width" ) #define LT_WIDTH N_( "Video memory buffer width." ) #define T_HEIGHT N_( "Height" ) #define LT_HEIGHT N_( "Video memory buffer height." ) #define T_LOCK N_( "Lock function" ) #define LT_LOCK N_( "Address of the locking callback function. This " \ "function must return a valid memory address for use " \ "by the video renderer." ) #define T_UNLOCK N_( "Unlock function" ) #define LT_UNLOCK N_( "Address of the unlocking callback function" ) #define T_DATA N_( "Callback data" ) #define LT_DATA N_( "Data for the locking and unlocking functions" ) vlc_module_begin(); set_category( CAT_INPUT ); set_subcategory( SUBCAT_INPUT_VCODEC ); set_shortname( N_("Memory video decoder") ); //set_description( N_("Memory video decoder") ); set_description( MOD_DESC ); set_capability( "decoder", 1000 ); set_callbacks( OpenDecoder, CloseDecoder ); add_shortcut( "invmem" ); add_integer( "invmem-width", "0", NULL, T_WIDTH, LT_WIDTH, false ); add_integer( "invmem-height", "0", NULL, T_HEIGHT, LT_HEIGHT, false ); add_string( "invmem-lock", "0", NULL, T_LOCK, LT_LOCK, true ); add_string( "invmem-unlock", "0", NULL, T_UNLOCK, LT_UNLOCK, true ); add_string( "invmem-data", "0", NULL, T_DATA, LT_DATA, true ); vlc_module_end(); struct decoder_sys_t { void * (*pf_lock) (void *); void (*pf_unlock) (void *); void *p_data; int i_width; int i_height; picture_t *p_pic }; /***************************************************************************** * OpenDecoder: probe the decoder and return score *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t*)p_this; decoder_sys_t *p_sys; char *psz_tmp; msg_Dbg( p_dec, "Initialize INVMEM DECODER moduule" ); if( p_dec->fmt_in.i_codec != VLC_FOURCC('f','a','k','e')) { return VLC_EGENERIC; } /* Allocate the memory needed to store the decoder's structure */ if( ( p_dec->p_sys = p_sys = (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL ) return VLC_ENOMEM; // get parametrs p_sys->i_width = config_GetInt( p_this, "invmem-width" ); p_sys->i_height = config_GetInt( p_this, "invmem-height" ); if (p_sys->i_width == 0 || p_sys->i_height == 0) { msg_Err( p_dec, "--vmem-width and --vmem-height must be > 0" ); return VLC_EGENERIC; } psz_tmp = config_GetPsz( p_dec, "invmem-lock" ); p_sys->pf_lock = (void * (*) (void *))(intptr_t)atoll( psz_tmp ); free( psz_tmp ); psz_tmp = config_GetPsz( p_dec, "invmem-unlock" ); p_sys->pf_unlock = (void (*) (void *))(intptr_t)atoll( psz_tmp ); free( psz_tmp ); psz_tmp = config_GetPsz( p_dec, "invmem-data" ); p_sys->p_data = (void *)(intptr_t)atoll( psz_tmp ); free( psz_tmp ); if( !p_sys->pf_lock || !p_sys->pf_unlock ) { msg_Err( p_dec, "Invalid lock or unlock callbacks" ); return VLC_EGENERIC; } /* Set output properties */ p_dec->fmt_out.i_cat = VIDEO_ES; //p_dec->fmt_out.i_codec = VLC_FOURCC('R','G','B','A'); p_dec->fmt_out.i_codec = VLC_FOURCC('R','V','2','4'); p_dec->fmt_out.video.i_width = p_dec->p_sys->i_width; p_dec->fmt_out.video.i_height = p_dec->p_sys->i_height; p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * p_dec->p_sys->i_width / p_dec->p_sys->i_height; p_dec->fmt_out.video.i_rmask = 0xff0000; p_dec->fmt_out.video.i_gmask = 0x00ff00; p_dec->fmt_out.video.i_bmask = 0x0000ff; p_dec->fmt_out.i_cat = VIDEO_ES; // create new picture p_dec->p_sys->p_pic = p_dec->pf_vout_buffer_new( p_dec ); /* Set callbacks */ p_dec->pf_decode_video = DecodeBlock; return VLC_SUCCESS; } /**************************************************************************** * DecodeBlock: the whole thing **************************************************************************** * This function must be fed with a complete compressed frame. ****************************************************************************/ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) { decoder_sys_t *p_sys = p_dec->p_sys; if( !pp_block || !*pp_block ) return NULL; // create new picture picture_Release( p_dec->p_sys->p_pic ); p_dec->p_sys->p_pic = p_dec->pf_vout_buffer_new( p_dec ); p_dec->p_sys->p_pic->b_force = true; p_dec->p_sys->p_pic->p->i_pitch = p_dec->p_sys->i_width*3; // lock input and copy to picture p_dec->p_sys->p_pic->p->p_pixels = p_dec->p_sys->pf_lock( p_dec->p_sys->p_data ); // unlock input p_dec->p_sys->pf_unlock( p_dec->p_sys->p_data ); block_Release( *pp_block ); *pp_block = NULL; return p_dec->p_sys->p_pic; } /***************************************************************************** * CloseDecoder: png decoder destruction *****************************************************************************/ static void CloseDecoder( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t *)p_this; decoder_sys_t *p_sys = p_dec->p_sys; free( p_sys ); }
Usage is similar to vmem output module.

We need next vlc_argv[] options:

Code: Select all

"--codec", "invmem", "--invmem-width", width, "--invmem-height", height, "--invmem-lock", clock, "--invmem-unlock", cunlock, "--invmem-data", cdata,
and calling libvlc_media_new with "fake://" access string:

Code: Select all

libvlc_media_new(libvlc, "fake://", &ex);
I hope that is useful not only for me :-)

PS1 sory for post after post ...
PS2 sory for my english ...

Re: libVLC as video output

Posted: 02 Dec 2008 09:23
by Jean-Baptiste Kempf
This is interesting, can you send this in form of a patch or a git diff to the mailing list?

Re: libVLC as video output

Posted: 02 Dec 2008 13:07
by bercik
I send git-patch to vlc-devel mailing list

Re: libVLC as video output

Posted: 02 Dec 2008 15:22
by Jean-Baptiste Kempf
Great. Moderated there.

Re: libVLC as video output

Posted: 03 Dec 2008 12:14
by bercik
Great. Moderated there.
Thanks. Can you moderate my patch to this module and reply to Rémi Denis-Courmont mail

Re: libVLC as video output

Posted: 03 Dec 2008 14:42
by Jean-Baptiste Kempf
Done.
I also gave you the rights to mail wihtout moderation.

Re: libVLC as video output

Posted: 26 May 2009 02:34
by yohan2
Is there a way to use this for raw audio samples as well (inamem)?

Re: libVLC as video output

Posted: 26 May 2009 14:40
by Jean-Baptiste Kempf
Not yet.

Re: libVLC as video output

Posted: 27 May 2009 18:41
by Rémi Denis-Courmont
For audio, you can always use a pipe, as the memory copy overhead is not as tremendous as with video. Just configure the audio output to file, set the file path to a named FIFO and skip the WAVE/RIFF header at the other end.