]> git.sesse.net Git - vlc/blob - plugins/vcd/linux_cdrom_tools.c
Some heavy changes today:
[vlc] / plugins / vcd / linux_cdrom_tools.c
1 /****************************************************************************
2  * linux_cdrom_tools.c: linux cdrom tools
3  *****************************************************************************
4  * Copyright (C) 1998-2001 VideoLAN
5  *
6  * Author: Johan Bilien <jobi@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  * 
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26 #include <stdio.h>
27 #include <stdlib.h>
28
29 #include <videolan/vlc.h>
30
31 #ifdef HAVE_UNISTD_H
32 #   include <unistd.h>
33 #endif
34
35 #include <fcntl.h>
36 #include <sys/types.h>
37 #include <string.h>
38 #include <errno.h>
39
40 #include <sys/ioctl.h>
41
42 #include "linux_cdrom_tools.h"
43
44 /*****************************************************************************
45  * ioctl_ReadTocHeader: Read the TOC header and return the track number.
46  *****************************************************************************/
47 int ioctl_GetTrackCount( int i_fd )
48 {
49     struct cdrom_tochdr   tochdr;
50
51     /* First we read the TOC header */
52     if( ioctl( i_fd, CDROMREADTOCHDR, &tochdr ) == -1 )
53     {
54         intf_ErrMsg( "vcd error: could not read TOCHDR" );
55         return -1;
56     }
57
58     return tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
59 }
60
61 /*****************************************************************************
62  * ioctl_GetSectors: Read the Table of Contents and fill p_vcd.
63  *****************************************************************************/
64 int * ioctl_GetSectors( int i_fd )
65 {
66     int  i, i_tracks;
67     int *p_sectors;
68     struct cdrom_tochdr   tochdr;
69     struct cdrom_tocentry tocent;
70
71     /* First we read the TOC header */
72     if( ioctl( i_fd, CDROMREADTOCHDR, &tochdr ) == -1 )
73     {
74         intf_ErrMsg( "vcd error: could not read TOCHDR" );
75         return NULL;
76     }
77
78     i_tracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
79
80     p_sectors = malloc( (i_tracks + 1) * sizeof(int) );
81     if( p_sectors == NULL )
82     {
83         intf_ErrMsg( "vcd error: could not allocate p_sectors" );
84         return NULL;
85     }
86
87     /* Fill the p_sectors structure with the track/sector matches */
88     for( i = 0 ; i <= i_tracks ; i++ )
89     {
90         tocent.cdte_format = CDROM_LBA;
91         tocent.cdte_track =
92             ( i == i_tracks ) ? CDROM_LEADOUT : tochdr.cdth_trk0 + i;
93
94         if( ioctl( i_fd, CDROMREADTOCENTRY, &tocent ) == -1 )
95         {
96             intf_ErrMsg( "vcd error: could not read TOCENTRY" );
97             free( p_sectors );
98             return NULL;
99         }
100
101         p_sectors[ i ] = tocent.cdte_addr.lba;
102     }
103
104     return p_sectors;
105 }
106
107 /****************************************************************************
108  * ioctl_ReadSector: Read a sector (2324 bytes)
109  ****************************************************************************/
110 int ioctl_ReadSector( int i_fd, int i_sector, byte_t * p_buffer )
111 {
112     byte_t p_block[ VCD_SECTOR_SIZE ];
113     int    i_dummy = i_sector + 2 * CD_FRAMES;
114
115 #define p_msf ((struct cdrom_msf0 *)p_block)
116     p_msf->minute =   i_dummy / (CD_FRAMES * CD_SECS);
117     p_msf->second = ( i_dummy % (CD_FRAMES * CD_SECS) ) / CD_FRAMES;
118     p_msf->frame =  ( i_dummy % (CD_FRAMES * CD_SECS) ) % CD_FRAMES;
119
120     intf_DbgMsg( "vcd debug: playing frame %d:%d-%d",
121                  p_msf->minute, p_msf->second, p_msf->frame);
122 #undef p_msf
123
124     if( ioctl(i_fd, CDROMREADRAW, p_block) == -1 )
125     {
126         intf_ErrMsg( "vcd error: could not read block %i from disc",
127                      i_sector );
128         return -1;
129     }
130
131     /* We don't want to keep the header of the read sector */
132     FAST_MEMCPY( p_buffer, p_block + VCD_DATA_START, VCD_DATA_SIZE );
133
134     return 0;
135 }
136