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.