1
/****************************************************************************
2
* linux_cdrom_tools.c: linux cdrom tools
3
*****************************************************************************
4
* Copyright (C) 1998-2001 VideoLAN
6
* Author: Johan Bilien <jobi@via.ecp.fr>
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.
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.
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
*****************************************************************************/
23
/*****************************************************************************
24
* Functions declared in this file use lots of ioctl calls, thus they are
26
****************************************************************************/
38
#include <sys/types.h>
42
#ifdef STRNCASECMP_IN_STRINGS_H
47
# include <io.h> /* read() */
49
# include <sys/uio.h> /* struct iovec */
52
#include <sys/ioctl.h>
61
# include "input_iovec.h"
64
#include "stream_control.h"
65
#include "input_ext-intf.h"
66
#include "input_ext-dec.h"
67
#include "input_ext-plugins.h"
72
#include "modules_export.h"
75
#include "input_vcd.h"
76
#include "linux_cdrom_tools.h"
77
/*****************************************************************************
78
* read_toc : Reads the Table of Content of a CD-ROM and fills p_vcd with *
79
* the read information *
80
*****************************************************************************/
81
int read_toc ( thread_vcd_data_t * p_vcd )
84
struct cdrom_tochdr tochdr ;
85
struct cdrom_tocentry tocent ;
86
int fd = p_vcd->vcdhandle ;
88
/* first we read the TOC header */
89
if (ioctl(fd, CDROMREADTOCHDR, &tochdr) == -1)
91
intf_ErrMsg("problem occured when reading CD's TOCHDR\n") ;
95
p_vcd->nb_tracks = tochdr.cdth_trk1;
96
/* nb_tracks + 1 because we put the lead_out tracks for computing last
98
p_vcd->tracks_sector = malloc( ( p_vcd->nb_tracks + 1 )
100
if ( p_vcd->tracks_sector == NULL )
102
intf_ErrMsg("could not malloc tracks_sector");
106
/* then for each track we read its TOC entry */
108
for( i=tochdr.cdth_trk0 ; i <= tochdr.cdth_trk1 ; i++ )
110
tocent.cdte_track = i;
111
tocent.cdte_format = CDROM_LBA;
112
if (ioctl( fd, CDROMREADTOCENTRY, &tocent) == -1 )
114
intf_ErrMsg( "problem occured when reading CD's TOCENTRY\n" );
115
free ( p_vcd->tracks_sector );
119
p_vcd->tracks_sector[i-1] = tocent.cdte_addr.lba ;
123
/* finally we read the lead-out track toc entry */
125
tocent.cdte_track = CDROM_LEADOUT ;
126
tocent.cdte_format = CDROM_LBA ;
127
if (ioctl(fd, CDROMREADTOCENTRY, &tocent) == -1)
129
intf_ErrMsg("problem occured when readind CD's
130
lead-out track TOC entry") ;
131
free (p_vcd->tracks_sector) ;
135
p_vcd->tracks_sector[p_vcd->nb_tracks] = tocent.cdte_addr.lba ;
141
/****************************************************************************
142
* VCD_sector_read : Function that reads a sector (2324 bytes) from VCD
143
****************************************************************************/
144
int VCD_sector_read ( struct thread_vcd_data_s * p_vcd, byte_t * p_buffer )
146
byte_t p_read_block[VCD_SECTOR_SIZE] ;
147
struct cdrom_msf0 msf_cursor ;
149
msf_cursor = lba2msf( p_vcd->current_sector ) ;
152
intf_DbgMsg("Playing frame %d:%d-%d\n", msf_cursor.minute,
153
msf_cursor.second, msf_cursor.frame) ;
156
memcpy(p_read_block, &msf_cursor, sizeof(struct cdrom_msf0)) ;
158
if (ioctl(p_vcd->vcdhandle, CDROMREADRAW, p_read_block) == -1)
160
intf_ErrMsg("problem occured when reading CD") ;
161
free (p_read_block) ;
165
/* we don't want to keep the header of the read sector */
166
memcpy( p_buffer, &p_read_block[VCD_DATA_START],
170
p_vcd->current_sector ++;
172
if ( p_vcd->current_sector ==
173
p_vcd->tracks_sector[p_vcd->current_track + 1] )
175
p_vcd->b_end_of_track = 1;
182
/*****************************************************************************
183
* lba2msf : converts a logical block address into a minute/second/frame
185
*****************************************************************************/
187
struct cdrom_msf0 lba2msf( int lba)
189
struct cdrom_msf0 msf_result ;
191
/* we add 2*CD_FRAMES since the 2 first seconds are not played*/
193
msf_result.minute = (lba+2*CD_FRAMES) / ( CD_FRAMES * CD_SECS ) ;
194
msf_result.second = ( (lba+2*CD_FRAMES) % ( CD_FRAMES * CD_SECS ) )
196
msf_result.frame = ( (lba+2*CD_FRAMES) % ( CD_FRAMES * CD_SECS ) )