raw device access under Linux

Keith Packard keithp at keithp.com
Tue Nov 6 00:27:47 CET 2001



Around 23 o'clock on Nov 5, Christophe Massiot wrote:

> Maybe you've already sent it to someone, but since I haven't seen it 
> in the CVS yet, I'll try again... We'd be delighted to have this 
> feature in libdvdcss, and I'd love to see it in the next release 
> (which should be announced later this week). Would it be ok for you ?

I sent it to a few people, but it's short so I'll included it here for 
those interested in looking at it.  Note that this is from 0.0.3 which is 
quite a bit different than current CVS; I've been unable to get current 
CVS to work with xine.  I don't believe this diff affects the changed 
portions of the library though.

Is there any plan to ship the CSS keys from DeCSS?  I've found DVD playing 
with the current discovery mechanism to take a *long* time for most of the 
discs I've got; using the keys is a lot nicer.

-keith


-- Attached file included as plaintext by Listar --
-- File: libdvdcss.diff
-- Desc: libdvdcss.diff

diff -rc libdvdcss-0.0.3/extras/libdvdcss/libdvdcss.c libdvdcss-0.0.3.keithp/extras/libdvdcss/libdvdcss.c
*** libdvdcss-0.0.3/extras/libdvdcss/libdvdcss.c	Mon Aug  6 06:28:00 2001
--- libdvdcss-0.0.3.keithp/extras/libdvdcss/libdvdcss.c	Mon Oct 22 21:45:06 2001
***************
*** 61,68 ****
  static int _dvdcss_open  ( dvdcss_handle, char *psz_target );
  static int _dvdcss_close ( dvdcss_handle );
  static int _dvdcss_seek  ( dvdcss_handle, int i_blocks );
! static int _dvdcss_read  ( dvdcss_handle, void *p_buffer, int i_blocks );
! static int _dvdcss_readv ( dvdcss_handle, struct iovec *p_iovec, int i_blocks );
  
  /*****************************************************************************
   * Local prototypes, win32 specific
--- 61,68 ----
  static int _dvdcss_open  ( dvdcss_handle, char *psz_target );
  static int _dvdcss_close ( dvdcss_handle );
  static int _dvdcss_seek  ( dvdcss_handle, int i_blocks );
! static int _dvdcss_read  ( dvdcss_handle, void *p_buffer, int i_blocks, int i_flags );
! static int _dvdcss_readv ( dvdcss_handle, struct iovec *p_iovec, int i_blocks, int i_flags );
  
  /*****************************************************************************
   * Local prototypes, win32 specific
***************
*** 251,257 ****
      dvd_title_t *p_title;
      int i_ret, i_index;
  
!     i_ret = _dvdcss_read( dvdcss, p_buffer, i_blocks );
  
      if( i_ret <= 0
           || !dvdcss->b_encrypted
--- 251,257 ----
      dvd_title_t *p_title;
      int i_ret, i_index;
  
!     i_ret = _dvdcss_read( dvdcss, p_buffer, i_blocks, i_flags );
  
      if( i_ret <= 0
           || !dvdcss->b_encrypted
***************
*** 299,305 ****
      void *iov_base;
      size_t iov_len;
  
!     i_ret = _dvdcss_readv( dvdcss, P_IOVEC, i_blocks );
  
      if( i_ret <= 0
           || !dvdcss->b_encrypted
--- 299,305 ----
      void *iov_base;
      size_t iov_len;
  
!     i_ret = _dvdcss_readv( dvdcss, P_IOVEC, i_blocks, i_flags );
  
      if( i_ret <= 0
           || !dvdcss->b_encrypted
***************
*** 385,390 ****
--- 385,402 ----
  
  /* Following functions are local */
  
+ static int _dvdcss_open_raw (char *target, int mode)
+ {
+     char    raw[256];
+ 
+     if (strncmp (target, "/dev/", 5) || strlen (target) > sizeof (raw) - 3)
+ 	return -1;
+ 
+     strcpy (raw, "/dev/r");
+     strcat (raw, target + 5);
+     return open (raw, mode);
+ }
+ 
  static int _dvdcss_open ( dvdcss_handle dvdcss, char *psz_target )
  {
  #if defined( WIN32 )
***************
*** 424,429 ****
--- 436,445 ----
          _dvdcss_error( dvdcss, "failed opening device" );
          return -1;
      }
+     
+     dvdcss->i_raw_fd = _dvdcss_open_raw (psz_target, 0);
+     dvdcss->i_filepos = 0;
+     dvdcss->i_raw_filepos = 0;
  
  #endif
  
***************
*** 452,457 ****
--- 468,478 ----
  
  #else
      close( dvdcss->i_fd );
+     if (dvdcss->i_raw_fd >= 0)
+     {
+ 	close (dvdcss->i_raw_fd);
+ 	dvdcss->i_raw_fd = -1;
+     }
  
  #endif
  
***************
*** 490,508 ****
          return ( _win32_dvdcss_aseek( dvdcss->i_fd, i_blocks, SEEK_SET ) );
      }
  #else
-     off_t i_read;
- 
      dvdcss->i_seekpos = i_blocks;
  
!     i_read = lseek( dvdcss->i_fd,
!                     (off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE, SEEK_SET );
! 
!     return i_read / DVDCSS_BLOCK_SIZE;
  #endif
  
  }
  
! static int _dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, int i_blocks )
  {
  #if defined( WIN32 ) 
      if( WIN2K )
--- 511,525 ----
          return ( _win32_dvdcss_aseek( dvdcss->i_fd, i_blocks, SEEK_SET ) );
      }
  #else
      dvdcss->i_seekpos = i_blocks;
+     dvdcss->i_req_filepos = (off_t) i_blocks * (off_t) DVDCSS_BLOCK_SIZE;
  
!     return i_blocks;
  #endif
  
  }
  
! static int _dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, int i_blocks, int i_flags )
  {
  #if defined( WIN32 ) 
      if( WIN2K )
***************
*** 523,543 ****
      }
  
  #else
!     int i_bytes;
  
!     i_bytes = read( dvdcss->i_fd, p_buffer,
!                     (size_t)i_blocks * DVDCSS_BLOCK_SIZE );
      return i_bytes / DVDCSS_BLOCK_SIZE;
  #endif
  
  }
  
  static int _dvdcss_readv ( dvdcss_handle dvdcss, struct iovec *p_iovec,
!                            int i_blocks )
  {
      int i_read;
  
- #if defined( WIN32 )
      /* Check the size of the readv temp buffer, just in case we need to
       * realloc something bigger */
      if( dvdcss->i_readv_buf_size < i_blocks * DVDCSS_BLOCK_SIZE )
--- 540,582 ----
      }
  
  #else
!     int i_bytes = -1;
  
!     if ((i_flags & DVDCSS_READ_DECRYPT) && dvdcss->i_raw_fd >= 0)
!     {
! 	if (dvdcss->i_req_filepos != dvdcss->i_raw_filepos)
! 	    dvdcss->i_raw_filepos = lseek (dvdcss->i_raw_fd, dvdcss->i_req_filepos, SEEK_SET);
! 	i_bytes = read( dvdcss->i_raw_fd, p_buffer,
! 		       (size_t)i_blocks * DVDCSS_BLOCK_SIZE );
! 	if (i_bytes > 0)
! 	{
! 	    dvdcss->i_raw_filepos += i_bytes;
! 	    dvdcss->i_req_filepos += i_bytes;
! 	}
!     }
!     if (i_bytes < 0)
!     {
! 	if (dvdcss->i_req_filepos != dvdcss->i_filepos)
! 	    dvdcss->i_filepos = lseek (dvdcss->i_fd, dvdcss->i_req_filepos, SEEK_SET);
! 	i_bytes = read( dvdcss->i_fd, p_buffer,
! 		       (size_t)i_blocks * DVDCSS_BLOCK_SIZE );
! 	if (i_bytes > 0)
! 	{
! 	    dvdcss->i_filepos += i_bytes;
! 	    dvdcss->i_req_filepos += i_bytes;
! 	}
!     }
      return i_bytes / DVDCSS_BLOCK_SIZE;
  #endif
  
  }
  
  static int _dvdcss_readv ( dvdcss_handle dvdcss, struct iovec *p_iovec,
!                            int i_blocks, int i_flags )
  {
+ #if defined( WIN32 )
      int i_read;
  
      /* Check the size of the readv temp buffer, just in case we need to
       * realloc something bigger */
      if( dvdcss->i_readv_buf_size < i_blocks * DVDCSS_BLOCK_SIZE )
***************
*** 561,569 ****
      return i_read;
  
  #else
!     i_read = readv( dvdcss->i_fd, p_iovec, i_blocks );
!     return i_read / DVDCSS_BLOCK_SIZE;
  
  #endif
  }
  
--- 600,630 ----
      return i_read;
  
  #else
!     int i_bytes = -1;
  
+     if ((i_flags & DVDCSS_READ_DECRYPT) && dvdcss->i_raw_fd >= 0)
+     {
+ 	if (dvdcss->i_req_filepos != dvdcss->i_raw_filepos)
+ 	    dvdcss->i_raw_filepos = lseek (dvdcss->i_raw_fd, dvdcss->i_req_filepos, SEEK_SET);
+ 	i_bytes = readv( dvdcss->i_raw_fd, p_iovec, i_blocks);
+ 	if (i_bytes > 0)
+ 	{
+ 	    dvdcss->i_raw_filepos += i_bytes;
+ 	    dvdcss->i_req_filepos += i_bytes;
+ 	}
+     }
+     if (i_bytes < 0)
+     {
+ 	if (dvdcss->i_req_filepos != dvdcss->i_filepos)
+ 	    dvdcss->i_filepos = lseek (dvdcss->i_fd, dvdcss->i_req_filepos, SEEK_SET);
+ 	i_bytes = readv( dvdcss->i_fd, p_iovec, i_blocks);
+ 	if (i_bytes > 0)
+ 	{
+ 	    dvdcss->i_filepos += i_bytes;
+ 	    dvdcss->i_req_filepos += i_bytes;
+ 	}
+     }
+     return i_bytes / DVDCSS_BLOCK_SIZE;
  #endif
  }
  
diff -rc libdvdcss-0.0.3/extras/libdvdcss/libdvdcss.h libdvdcss-0.0.3.keithp/extras/libdvdcss/libdvdcss.h
*** libdvdcss-0.0.3/extras/libdvdcss/libdvdcss.h	Wed Jul 25 04:42:45 2001
--- libdvdcss-0.0.3.keithp/extras/libdvdcss/libdvdcss.h	Mon Oct 22 21:38:58 2001
***************
*** 49,54 ****
--- 49,59 ----
  #if defined( WIN32 )
      char *p_readv_buffer;
      int  i_readv_buf_size;
+ #else
+     int i_raw_fd;
+     off_t i_req_filepos;
+     off_t i_filepos;
+     off_t i_raw_filepos;
  #endif
  };
  





More information about the vlc-devel mailing list