1 /*
2  * Based on work by Rocky Bernstein <rocky@panix.com>, 2004,
3  * adapted by Ingo Brückl.
4  *
5  * This file is part of MPlayer.
6  *
7  * MPlayer is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * MPlayer is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 
22 #ifndef MPLAYER_VCD_READ_LIBCDIO_H
23 #define MPLAYER_VCD_READ_LIBCDIO_H
24 
25 #include <stdlib.h>
26 #include <string.h>
27 
28 #if HAVE_CDIO_PARANOIA_H
29 #include <cdio/cdda.h>
30 #include <cdio/paranoia.h>
31 #elif HAVE_CDIO_PARANOIA_PARANOIA_H
32 #include <cdio/paranoia/cdda.h>
33 #include <cdio/paranoia/paranoia.h>
34 #endif
35 
36 /** Private vcd data. */
37 typedef struct {
38     track_t track;     /**< Current track being played. */
39     lsn_t lsn;         /**< Current logical sector number. */
40     CdIo *cdio;        /**< Pointer to internal libcdio data. */
41 } mp_vcd_priv_t;
42 
43 /**
44  * @brief Prepare reading of the Video CD.
45  *
46  * @param fd (unused)
47  *
48  * @return pointer to the newly allocated private vcd data
49  */
vcd_read_toc(int fd)50 static inline mp_vcd_priv_t *vcd_read_toc(int fd)
51 {
52     mp_vcd_priv_t *vcd = malloc(sizeof(mp_vcd_priv_t));
53 
54     return vcd;
55 }
56 
57 /**
58  * @brief Set the track of the Video CD to be read next.
59  *
60  * @param vcd pointer to the private vcd data
61  * @param track track to be read next
62  *
63  * @return sector offset in bytes or -1 (error)
64  */
vcd_seek_to_track(mp_vcd_priv_t * vcd,int track)65 static int vcd_seek_to_track(mp_vcd_priv_t *vcd, int track)
66 {
67     vcd->lsn = cdio_get_track_lsn(vcd->cdio, track);
68 
69     if (vcd->lsn == CDIO_INVALID_LSN)
70         return -1;
71 
72     return M2F2_SECTOR_SIZE * vcd->lsn;
73 }
74 
75 /**
76  * @brief Determine the number of sectors of a Video CD track.
77  *
78  * @param vcd pointer to the private vcd data
79  * @param track track to examine
80  *
81  * @return sector offset in bytes or -1 (error)
82  */
vcd_get_track_end(mp_vcd_priv_t * vcd,int track)83 static int vcd_get_track_end(mp_vcd_priv_t *vcd, int track)
84 {
85     lsn_t end_lsn;
86 
87     if (vcd_seek_to_track(vcd, track) == -1)
88         return -1;
89 
90     end_lsn = vcd->lsn + cdio_get_track_sec_count(vcd->cdio, track) - 1;
91 
92     if (end_lsn == CDIO_INVALID_LSN)
93         return -1;
94 
95     return M2F2_SECTOR_SIZE * end_lsn;
96 }
97 
98 /**
99  * @brief Get last track number of the Video CD.
100  *
101  * @param vcd pointer to the private vcd data
102  *
103  * @return last track number
104  */
vcd_end_track(mp_vcd_priv_t * vcd)105 static inline int vcd_end_track(mp_vcd_priv_t *vcd)
106 {
107     return cdio_get_last_track_num(vcd->cdio);
108 }
109 
110 /**
111  * @brief Set the sector of the Video CD to be read next.
112  *
113  * @param vcd pointer to the private vcd data
114  * @param sect sector to be read next
115  */
vcd_set_msf(mp_vcd_priv_t * vcd,unsigned int sect)116 static inline void vcd_set_msf(mp_vcd_priv_t *vcd, unsigned int sect)
117 {
118     vcd->lsn = sect;
119 }
120 
121 /**
122  * @brief Read a sector of the Video CD.
123  *
124  * @note As a side effect, the sector pointer will be incremented.
125  *
126  * @param vcd pointer to the private vcd data
127  * @param buffer pointer to a buffer suitable to store the data
128  *
129  * @return number of bytes read or 0 (error)
130  */
vcd_read(mp_vcd_priv_t * vcd,char * buffer)131 static int vcd_read(mp_vcd_priv_t *vcd, char *buffer)
132 {
133     struct {
134         uint8_t subheader[CDIO_CD_SUBHEADER_SIZE];
135         uint8_t data[M2F2_SECTOR_SIZE];
136         uint8_t spare[4];
137     } vcd_sector;
138 
139     if (cdio_read_mode2_sector(vcd->cdio, &vcd_sector, vcd->lsn, true) != 0)
140         return 0;
141 
142     memcpy(buffer, vcd_sector.data, M2F2_SECTOR_SIZE);
143     vcd->lsn++;
144 
145     return M2F2_SECTOR_SIZE;
146 }
147 
148 #endif /* MPLAYER_VCD_READ_LIBCDIO_H */
149