[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