[vlc-devel] Re: Problem with an access_demux module
Christophe Démaret
vlc at cdemaret.com
Wed Jun 7 06:54:48 CEST 2006
Laurent Aimar a écrit :
> I think your bug is here, you need to init p_sys->fmt before adding
> the es (p_sys->es = es_out_Add() ).
> (Otherwise, as fmt is not correct, vlc will throw away all your data ...)
> Regards,
This worked perfectly, thanx a lots :)
Now i have another issue with a similar plug-in.
I'm trying to read RAW RGB 24 bits from a buffer.
it looks like rawvideo.c wants the dimensions, this seems logical :)
So I made this: (full code at the end)
my problem is that I do this:
in open() (and even in demux just in case...):
/* basic infos about the stream */
p_sys->fmt.video.i_width = FPGA_WIDTH;
p_sys->fmt.video.i_height = FPGA_HEIGHT;
p_sys->fmt.video.i_bits_per_pixel = 24;
msg_Dbg( p_demux, "screen width: %i, height: %i, depth: %i",
p_sys->fmt.video.i_width, p_sys->fmt.video.i_height,
p_sys->fmt.video.i_bits_per_pixel );
/* RGB stuff to give the component order*/
p_sys->fmt.video.i_rmask = 0x00ff0000;
p_sys->fmt.video.i_gmask = 0x0000ff00;
p_sys->fmt.video.i_bmask = 0x000000ff;
So my packet should have the i_width and i_heigth correctly set and
effectively they are displayed. by the debug message.
BUT then in the -vvv we have:
[00000162] main input debug: selecting program id=0
[00000163] fpga demuxer debug: screen width: 320, height: 240, depth: 24
[00000157] main module debug: using access_demux module "fpga"
[00000164] main decoder debug: looking for decoder module: 9 candidates
[00000164] rawvideo decoder error: invalid display size 0x0
[00000164] main decoder error: no suitable decoder module for fourcc `RV24'.
VLC probably does not support this sound or video format.
This is pretty sad because the fmt_in in rawvideo.c is supposed to be
the same that the fmt in my demuxer right ?
Is there something other i did not understood ?
Thanks :)
Christophe
--- CODE BEGIN ---
/*****************************************************************************
* Defines: some useful stuff...
******************************************************************************/
#define FPGA_FPS .1
#define CACHING_TEXT N_("Caching value in ms")
#define CACHING_LONGTEXT N_( \
"Allows you to modify the default caching value for fpga streams.
This " \
"value should be set in millisecond units." )
#define FPS_TEXT N_("Framerate")
#define FPS_LONGTEXT N_( \
"Specifies the number of frames per second (eg. 24, 25, 29.97, 30).")
#define ID_TEXT N_("ID")
#define ID_LONGTEXT N_( \
"Allows you to set the ID of the fake elementary stream for use in " \
"#duplicate{} constructs (default 0).")
#define FPGA_WIDTH 320
#define FPGA_HEIGHT 240
#define FPGA_OFF_H 240
#define FPGA_OFF_V 180
#define FPGA_TOTAL_WIDTH 600
/*****************************************************************************
* Module descriptor
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close( vlc_object_t * );
vlc_module_begin();
set_shortname( _("FPGA SMVP") );
set_description( _("SMVP card FPGA frame reader") );
set_category( CAT_INPUT );
set_subcategory( SUBCAT_INPUT_ACCESS );
add_integer( "fpga-caching", DEFAULT_PTS_DELAY / 1000, NULL,
CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
add_float( "fpga-fps", FPGA_FPS, NULL, FPS_TEXT, FPS_LONGTEXT,
VLC_TRUE );
add_integer( "fpga-id", 0, NULL, ID_TEXT, ID_LONGTEXT, VLC_TRUE );
add_shortcut( "fpga" );
set_capability( "access_demux", 10 );
set_callbacks( Open, Close );
vlc_module_end();
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Control( demux_t *, int, va_list );
static int Demux ( demux_t * );
struct demux_sys_t
{
es_format_t fmt;
es_out_id_t *es;
float f_fps;
mtime_t i_next_date;
int i_incr;
int fd;
};
/*****************************************************************************
* DemuxOpen:
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys;
vlc_value_t val;
/* Fill p_demux field */
/* callbacks*/
p_demux->pf_demux = Demux;
p_demux->pf_control = Control;
p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
memset( p_sys, 0, sizeof( demux_sys_t ) );
msg_Dbg( p_demux, "opening fpga access_demux");
var_Create( p_demux, "fpga-caching",
VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
var_Create( p_demux, "fpga-fps", VLC_VAR_FLOAT|VLC_VAR_DOINHERIT );
var_Get( p_demux, "fpga-fps", &val );
p_sys->f_fps = val.f_float;
p_sys->i_incr = 1000000 / val.f_float;
p_sys->i_next_date = 0;
#if 0
/* open the device */
p_sys->fd = open(FPGA_DEVICE_PATH, O_RDWR);
if( p_sys->fd == -1)
{
msg_Err( p_demux, "failed to open the device");
return VLC_EGENERIC;
}
else
{
msg_Dbg( p_demux, "device %s sucessfully opened",
FPGA_DEVICE_PATH);
}
#endif
#if 0
if( screen_InitCapture( p_demux ) != VLC_SUCCESS )
{
free( p_sys );
return VLC_EGENERIC;
}
msg_Dbg( p_demux, "screen width: %i, height: %i, depth: %i",
p_sys->fmt.video.i_width, p_sys->fmt.video.i_height,
p_sys->fmt.video.i_bits_per_pixel );
#endif
es_format_Init( &p_sys->fmt, VIDEO_ES, VLC_FOURCC('R','V','2','4') );
p_sys->es = es_out_Add( p_demux->out, &p_sys->fmt );
/* msg_Dbg( p_demux, "es_out_Add done, ex = %x (%d)", p_sys->es,
p_sys->es);*/
/* basic infos about the stream */
p_sys->fmt.video.i_width = FPGA_WIDTH;
p_sys->fmt.video.i_height = FPGA_HEIGHT;
p_sys->fmt.video.i_bits_per_pixel = 24;
msg_Dbg( p_demux, "screen width: %i, height: %i, depth: %i",
p_sys->fmt.video.i_width, p_sys->fmt.video.i_height,
p_sys->fmt.video.i_bits_per_pixel );
/* RGB stuff to give the component order*/
p_sys->fmt.video.i_rmask = 0x00ff0000;
p_sys->fmt.video.i_gmask = 0x0000ff00;
p_sys->fmt.video.i_bmask = 0x000000ff;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close:
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys = p_demux->p_sys;
#if 0
screen_CloseCapture( p_demux );
#endif
close(p_sys->fd);
free( p_sys );
}
/*****************************************************************************
* Demux:
*****************************************************************************
* Returns -1 in case of error, 0 in case of EOF, 1 otherwise
*****************************************************************************/
static int Demux( demux_t *p_demux )
{
int i_size, ret_read;
demux_sys_t *p_sys = p_demux->p_sys;
block_t *p_block;
int i,j,k;
unsigned long i_src;
uint8_t *p_dst;
/* 24/32 bits conversion: 24/32 = 3/4*/
unsigned char i_width_word = (unsigned char) (FPGA_WIDTH*3/4);
if( !p_sys->i_next_date ) p_sys->i_next_date = mdate();
/* Frame skipping if necessary */
while( mdate() >= p_sys->i_next_date + p_sys->i_incr )
p_sys->i_next_date += p_sys->i_incr;
mwait( p_sys->i_next_date );
// SHOULD NOT BE HERE, DEBUGGING PURPOSE !!
/* basic infos about the stream */
p_sys->fmt.video.i_width = FPGA_WIDTH;
p_sys->fmt.video.i_height = FPGA_HEIGHT;
p_sys->fmt.video.i_bits_per_pixel = 24;
msg_Dbg( p_demux, "screen width: %i, height: %i, depth: %i",
p_sys->fmt.video.i_width, p_sys->fmt.video.i_height,
p_sys->fmt.video.i_bits_per_pixel );
/* RGB stuff to give the component order*/
p_sys->fmt.video.i_rmask = 0x00ff0000;
p_sys->fmt.video.i_gmask = 0x0000ff00;
p_sys->fmt.video.i_bmask = 0x000000ff;
// END
#if 0 /* FPGA */
msg_Dbg( p_demux, "preparing for ioctl, fd=%d", p_sys->fd);
i_size = ioctl( p_sys->fd, VJ2C_READSIZE, 0);
#endif
i_size = FPGA_HEIGHT * FPGA_WIDTH * 3;
/* allocating the new block */
msg_Dbg( p_demux, "preparing for block_New, i_size=%d", i_size);
if( !( p_block = block_New( p_demux, i_size ) ) )
{
msg_Err( p_demux, "cannot get block, p_block=%x", p_block );
}
else
{
/* effectively reading data from the driver */
#if 0 /* FPGA */
ret_read=read(p_sys->fd, p_block->p_buffer, i_size);
if (ret_read == -1)
{
msg_Err( p_demux, "failed to read frame");
free (p_block);
p_block = NULL;
}
else
{
msg_Dbg( p_demux, "Everything is fine, block created",
p_sys->fd);
}
#endif
p_dst = p_block->p_buffer;
i_src = 0x000000; /* plane 0 */
i_src += FPGA_OFF_V * FPGA_TOTAL_WIDTH;
for (i=0;i++;i<FPGA_HEIGHT)
{
fpga_sdram_dump(i_src + FPGA_OFF_H, i_width_word, p_dst);
i_src += FPGA_TOTAL_WIDTH;
p_dst += (unsigned long) i_width_word; /* 3/4*FPGA_WIDTH */
}
}
if( !p_block )
{
/* allocation failed */
p_sys->i_next_date += p_sys->i_incr;
return 1;
}
p_block->i_dts = p_block->i_pts = p_sys->i_next_date;
msg_Dbg( p_demux, "Finished. p_block=%p, date=%lld", p_block,
p_block->i_dts );
es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );
es_out_Send( p_demux->out, p_sys->es, p_block );
p_sys->i_next_date += p_sys->i_incr;
return 1;
}
/*****************************************************************************
* Control:
*****************************************************************************/
static int Control( demux_t *p_demux, int i_query, va_list args )
{
vlc_bool_t *pb;
int64_t *pi64;
switch( i_query )
{
/* Special for access_demux */
case DEMUX_CAN_PAUSE:
case DEMUX_CAN_CONTROL_PACE:
/* TODO */
pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
*pb = VLC_FALSE;
return VLC_SUCCESS;
case DEMUX_GET_PTS_DELAY:
pi64 = (int64_t*)va_arg( args, int64_t * );
*pi64 = (int64_t)var_GetInteger( p_demux, "fpga-caching" )
*1000;
return VLC_SUCCESS;
/* TODO implement others */
default:
return VLC_EGENERIC;
}
}
---CODE END ---
--
This is the vlc-devel mailing-list, see http://www.videolan.org/vlc/
To unsubscribe, please read http://developers.videolan.org/lists.html
More information about the vlc-devel
mailing list