[WASAPI] fix stream types and frequencies enumeration
[xbmc.git] / xbmc / storage / cdioSupport.h
blobd1a6823a185c53daad0a18b1ac531b4ea7d8bfaa
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #pragma once
11 // CCdInfo - Information about media type of an inserted cd
12 // CCdIoSupport - Wrapper class for libcdio with the interface of CIoSupport
13 // and detecting the filesystem on the Disc.
15 // by Bobbin007 in 2003
16 // CD-Text support by Mog - Oct 2004
18 #include "threads/CriticalSection.h"
20 #include <map>
21 #include <memory>
22 #include <string>
23 #include <utility>
25 #include "PlatformDefs.h" // for ssize_t typedef, used by cdio
27 #include <cdio/cdio.h>
29 namespace MEDIA_DETECT
32 #define STRONG "__________________________________\n"
33 //#define NORMAL ""
35 #define FS_NO_DATA 0 /* audio only */
36 #define FS_HIGH_SIERRA 1
37 #define FS_ISO_9660 2
38 #define FS_INTERACTIVE 3
39 #define FS_HFS 4
40 #define FS_UFS 5
41 #define FS_EXT2 6
42 #define FS_ISO_HFS 7 /* both hfs & isofs filesystem */
43 #define FS_ISO_9660_INTERACTIVE 8 /* both CD-RTOS and isofs filesystem */
44 #define FS_3DO 9
45 #define FS_UDF 11
46 #define FS_ISO_UDF 12
47 #define FS_UNKNOWN 15
48 #define FS_MASK 15
50 #define XA 16
51 #define MULTISESSION 32
52 #define PHOTO_CD 64
53 #define HIDDEN_TRACK 128
54 #define CDTV 256
55 #define BOOTABLE 512
56 #define VIDEOCDI 1024
57 #define ROCKRIDGE 2048
58 #define JOLIET 4096
59 #define CVD 8192 /* Choiji Video CD */
61 #define IS_ISOFS 0
62 #define IS_CD_I 1
63 #define IS_CDTV 2
64 #define IS_CD_RTOS 3
65 #define IS_HS 4
66 #define IS_BRIDGE 5
67 #define IS_XA 6
68 #define IS_PHOTO_CD 7
69 #define IS_EXT2 8
70 #define IS_UFS 9
71 #define IS_BOOTABLE 10
72 #define IS_VIDEO_CD 11 /* Video CD */
73 #define IS_CVD 12 /* Chinese Video CD - slightly incompatible with SVCD */
74 #define IS_UDF 14
76 typedef struct signature
78 unsigned int buf_num;
79 unsigned int offset;
80 const char *sig_str;
81 const char *description;
83 signature_t;
85 typedef std::map<cdtext_field_t, std::string> xbmc_cdtext_t;
87 typedef struct TRACKINFO
89 int nfsInfo; // Information of the Tracks Filesystem
90 int nJolietLevel; // Jouliet Level
91 int ms_offset; // Multisession Offset
92 int isofs_size; // Size of the ISO9660 Filesystem
93 int nFrames; // Can be used for cddb query
94 int nMins; // minutes playtime part of Track
95 int nSecs; // seconds playtime part of Track
96 xbmc_cdtext_t cdtext; // CD-Text for this track
98 trackinfo;
100 /*! \brief Helper enum class for the MMC tray state
102 enum class CdioTrayStatus
104 /* The MMC tray state is reported closed */
105 CLOSED,
106 /* The MMC tray state is reported open */
107 OPEN,
108 /* The MMC tray status operation is not supported */
109 UNKNOWN,
110 /* Generic driver error */
111 DRIVER_ERROR
114 class CCdInfo
116 public:
117 CCdInfo()
119 m_bHasCDDBInfo = true;
120 m_nLength = m_nFirstTrack = m_nNumTrack = m_nNumAudio = m_nFirstAudio = m_nNumData = m_nFirstData = 0;
123 trackinfo GetTrackInformation( int nTrack ) { return m_ti[nTrack -1]; }
124 const xbmc_cdtext_t& GetDiscCDTextInformation() const { return m_cdtext; }
126 bool HasDataTracks() { return (m_nNumData > 0); }
127 bool HasAudioTracks() { return (m_nNumAudio > 0); }
128 int GetFirstTrack() { return m_nFirstTrack; }
129 int GetTrackCount() { return m_nNumTrack; }
130 int GetFirstAudioTrack() { return m_nFirstAudio; }
131 int GetFirstDataTrack() { return m_nFirstData; }
132 int GetDataTrackCount() { return m_nNumData; }
133 int GetAudioTrackCount() { return m_nNumAudio; }
134 uint32_t GetCddbDiscId() { return m_ulCddbDiscId; }
135 int GetDiscLength() { return m_nLength; }
136 const std::string& GetDiscLabel() const { return m_strDiscLabel; }
138 // CD-ROM with ISO 9660 filesystem
139 bool IsIso9660( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_ISO_9660); }
140 // CD-ROM with joliet extension
141 bool IsJoliet( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & JOLIET) ? false : true; }
142 // Joliet extension level
143 int GetJolietLevel( int nTrack ) { return m_ti[nTrack - 1].nJolietLevel; }
144 // ISO filesystem size
145 int GetIsoSize( int nTrack ) { return m_ti[nTrack - 1].isofs_size; }
146 // CD-ROM with rockridge extensions
147 bool IsRockridge( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & ROCKRIDGE) ? false : true; }
149 // CD-ROM with CD-RTOS and ISO 9660 filesystem
150 bool IsIso9660Interactive( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_ISO_9660_INTERACTIVE); }
152 // CD-ROM with High Sierra filesystem
153 bool IsHighSierra( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_HIGH_SIERRA); }
155 // CD-Interactive, with audiotracks > 0 CD-Interactive/Ready
156 bool IsCDInteractive( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_INTERACTIVE); }
158 // CD-ROM with Macintosh HFS
159 bool IsHFS( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_HFS); }
161 // CD-ROM with both Macintosh HFS and ISO 9660 filesystem
162 bool IsISOHFS( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_ISO_HFS); }
164 // CD-ROM with both UDF and ISO 9660 filesystem
165 bool IsISOUDF( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_ISO_UDF); }
167 // CD-ROM with Unix UFS
168 bool IsUFS( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_UFS); }
170 // CD-ROM with Linux second extended filesystem
171 bool IsEXT2( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_EXT2); }
173 // CD-ROM with Panasonic 3DO filesystem
174 bool Is3DO( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_3DO); }
176 // Mixed Mode CD-ROM
177 bool IsMixedMode( int nTrack ) { return (m_nFirstData == 1 && m_nNumAudio > 0); }
179 // CD-ROM with XA sectors
180 bool IsXA( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & XA) ? false : true; }
182 // Multisession CD-ROM
183 bool IsMultiSession( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & MULTISESSION) ? false : true; }
184 // Gets multisession offset
185 int GetMultisessionOffset( int nTrack ) { return m_ti[nTrack - 1].ms_offset; }
187 // Hidden Track on Audio CD
188 bool IsHiddenTrack( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & HIDDEN_TRACK) ? false : true; }
190 // Photo CD, with audiotracks > 0 Portfolio Photo CD
191 bool IsPhotoCd( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & PHOTO_CD) ? false : true; }
193 // CD-ROM with Commodore CDTV
194 bool IsCdTv( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & CDTV) ? false : true; }
196 // CD-Plus/Extra
197 bool IsCDExtra( int nTrack ) { return (m_nFirstData > 1); }
199 // Bootable CD
200 bool IsBootable( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & BOOTABLE) ? false : true; }
202 // Video CD
203 bool IsVideoCd( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & VIDEOCDI && m_nNumAudio == 0); }
205 // Chaoji Video CD
206 bool IsChaojiVideoCD( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & CVD) ? false : true; }
208 // Audio Track
209 bool IsAudio( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_NO_DATA); }
211 // UDF filesystem
212 bool IsUDF( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_UDF); }
214 // Has the cd a filesystem that is readable by the xbox
215 bool IsValidFs() { return (IsISOHFS(1) || IsIso9660(1) || IsIso9660Interactive(1) || IsISOUDF(1) || IsUDF(1) || IsAudio(1)); }
217 void SetFirstTrack( int nTrack ) { m_nFirstTrack = nTrack; }
218 void SetTrackCount( int nCount ) { m_nNumTrack = nCount; }
219 void SetFirstAudioTrack( int nTrack ) { m_nFirstAudio = nTrack; }
220 void SetFirstDataTrack( int nTrack ) { m_nFirstData = nTrack; }
221 void SetDataTrackCount( int nCount ) { m_nNumData = nCount; }
222 void SetAudioTrackCount( int nCount ) { m_nNumAudio = nCount; }
223 void SetTrackInformation(int nTrack, trackinfo nInfo)
225 if (nTrack > 0 && nTrack <= 99)
226 m_ti[nTrack - 1] = std::move(nInfo);
228 void SetDiscCDTextInformation(xbmc_cdtext_t cdtext) { m_cdtext = std::move(cdtext); }
230 void SetCddbDiscId( uint32_t ulCddbDiscId ) { m_ulCddbDiscId = ulCddbDiscId; }
231 void SetDiscLength( int nLength ) { m_nLength = nLength; }
232 bool HasCDDBInfo() { return m_bHasCDDBInfo; }
233 void SetNoCDDBInfo() { m_bHasCDDBInfo = false; }
235 void SetDiscLabel(const std::string& strDiscLabel){ m_strDiscLabel = strDiscLabel; }
237 private:
238 int m_nFirstData; /* # of first data track */
239 int m_nNumData; /* # of data tracks */
240 int m_nFirstAudio; /* # of first audio track */
241 int m_nNumAudio; /* # of audio tracks */
242 int m_nNumTrack;
243 int m_nFirstTrack;
244 trackinfo m_ti[100];
245 uint32_t m_ulCddbDiscId;
246 int m_nLength; // Disclength can be used for cddb query, also see trackinfo.nFrames
247 bool m_bHasCDDBInfo;
248 std::string m_strDiscLabel;
249 xbmc_cdtext_t m_cdtext; // CD-Text for this disc
252 class CLibcdio : public CCriticalSection
254 private:
255 CLibcdio();
256 public:
257 virtual ~CLibcdio();
259 static void ReleaseInstance();
260 static std::shared_ptr<CLibcdio> GetInstance();
262 // libcdio is not thread safe so these are wrappers to libcdio routines
263 CdIo_t* cdio_open(const char *psz_source, driver_id_t driver_id);
264 CdIo_t* cdio_open_win32(const char *psz_source);
265 void cdio_destroy(CdIo_t *p_cdio);
266 discmode_t cdio_get_discmode(CdIo_t *p_cdio);
267 CdioTrayStatus mmc_get_tray_status(const CdIo_t* p_cdio);
268 driver_return_code_t cdio_eject_media(CdIo_t** p_cdio);
269 track_t cdio_get_last_track_num(const CdIo_t *p_cdio);
270 lsn_t cdio_get_track_lsn(const CdIo_t *p_cdio, track_t i_track);
271 lsn_t cdio_get_track_last_lsn(const CdIo_t *p_cdio, track_t i_track);
272 driver_return_code_t cdio_read_audio_sectors(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, uint32_t i_blocks);
273 driver_return_code_t cdio_close_tray(const char* psz_source, driver_id_t* driver_id);
274 const char* cdio_driver_errmsg(driver_return_code_t drc);
276 char* GetDeviceFileName();
278 private:
279 char* s_defaultDevice;
280 CCriticalSection m_critSection;
281 static std::shared_ptr<CLibcdio> m_pInstance;
284 class CCdIoSupport
286 public:
287 CCdIoSupport();
288 virtual ~CCdIoSupport();
290 bool EjectTray();
291 bool CloseTray();
293 HANDLE OpenCDROM();
294 HANDLE OpenIMAGE( std::string& strFilename );
295 int ReadSector(HANDLE hDevice, DWORD dwSector, char* lpczBuffer);
296 int ReadSectorMode2(HANDLE hDevice, DWORD dwSector, char* lpczBuffer);
297 int ReadSectorCDDA(HANDLE hDevice, DWORD dwSector, char* lpczBuffer);
298 void CloseCDROM(HANDLE hDevice);
300 void PrintAnalysis(int fs, int num_audio);
302 CCdInfo* GetCdInfo(char* cDeviceFileName=NULL);
303 void GetCdTextInfo(xbmc_cdtext_t &xcdt, int trackNum);
305 protected:
306 int ReadBlock(int superblock, uint32_t offset, uint8_t bufnum, track_t track_num);
307 bool IsIt(int num);
308 int IsHFS(void);
309 int Is3DO(void);
310 int IsJoliet(void);
311 int IsUDF(void);
312 int GetSize(void);
313 int GetJolietLevel( void );
314 int GuessFilesystem(int start_session, track_t track_num);
316 uint32_t CddbDiscId();
317 int CddbDecDigitSum(int n);
318 unsigned int MsfSeconds(msf_t *msf);
320 private:
321 char buffer[7][CDIO_CD_FRAMESIZE_RAW]; /* for CD-Data */
322 static signature_t sigs[17];
323 int i = 0, j = 0; /* index */
324 int m_nStartTrack; /* first sector of track */
325 int m_nIsofsSize; /* size of session */
326 int m_nJolietLevel;
327 int m_nMsOffset; /* multisession offset found by track-walking */
328 int m_nDataStart; /* start of data area */
329 int m_nFs;
330 int m_nUDFVerMinor;
331 int m_nUDFVerMajor;
333 CdIo* cdio;
334 track_t m_nNumTracks = CDIO_INVALID_TRACK;
335 track_t m_nFirstTrackNum = CDIO_INVALID_TRACK;
337 std::string m_strDiscLabel;
339 int m_nFirstData; /* # of first data track */
340 int m_nNumData; /* # of data tracks */
341 int m_nFirstAudio; /* # of first audio track */
342 int m_nNumAudio; /* # of audio tracks */
344 std::shared_ptr<CLibcdio> m_cdio;