[vlc-devel] Re: Problem with an access_demux module
Sigmund Augdal Helberg
dnumgis at videolan.org
Wed Jun 7 12:44:25 CEST 2006
On Wed, 2006-06-07 at 06:54 +0200, Christophe Démaret wrote:
> 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;
I think perhaps you need to set i_visible_width and i_visible_height as
well.
Sigmund
> 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