[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