MythTV master
mythcdrom.cpp
Go to the documentation of this file.
1#include "mythcdrom.h"
2
3#ifdef HAVE_LIBUDFREAD
4#include <udfread/udfread.h>
5#include <udfread/blockinput.h>
6#else
7#include "udfread.h"
8#include "blockinput.h"
9#endif
10
11#include <QtGlobal>
12#include <QDir>
13#include <QFileInfo>
14
15#include "compat.h"
16#include "mythconfig.h"
17#include "mythlogging.h"
18#include "remotefile.h"
19
20#ifdef __linux__
21# include "mythcdrom-linux.h"
22#elif defined(__FreeBSD__)
23# include "mythcdrom-freebsd.h"
24#elif defined(Q_OS_DARWIN)
25# include "mythcdrom-darwin.h"
26#endif
27
28// If your DVD has directories in lowercase, then it is wrongly mounted!
29// DVDs use the UDF filesystem, NOT ISO9660. Fix your /etc/fstab.
30
31// This allows a warning for the above mentioned OS setup fault
32static constexpr const char* PATHTO_BAD_DVD_MOUNT { "/video_ts" };
33
34static constexpr const char* PATHTO_DVD_DETECT { "/VIDEO_TS" };
35static constexpr const char* PATHTO_BD_DETECT { "/BDMV" };
36static constexpr const char* PATHTO_VCD_DETECT { "/vcd" };
37static constexpr const char* PATHTO_SVCD_DETECT { "/svcd" };
38
39// Mac OS X mounts audio CDs ready to use
40static constexpr const char* PATHTO_AUDIO_DETECT { "/.TOC.plist" };
41
42
43MythCDROM* MythCDROM::get(QObject* par, const QString& devicePath,
44 bool SuperMount, bool AllowEject)
45{
46#if defined(__linux__) && !defined(Q_OS_ANDROID)
47 return GetMythCDROMLinux(par, devicePath, SuperMount, AllowEject);
48#elif defined(__FreeBSD__)
49 return GetMythCDROMFreeBSD(par, devicePath, SuperMount, AllowEject);
50#elif defined(Q_OS_DARWIN)
51 return GetMythCDROMDarwin(par, devicePath, SuperMount, AllowEject);
52#else
53 return new MythCDROM(par, devicePath, SuperMount, AllowEject);
54#endif
55}
56
57MythCDROM::MythCDROM(QObject* par, const QString& DevicePath, bool SuperMount,
58 bool AllowEject)
59 : MythMediaDevice(par, DevicePath, SuperMount, AllowEject)
60{
61}
62
64{
65 if (!QDir(m_mountPath).exists())
66 {
67 LOG(VB_GENERAL, LOG_ERR, QString("Mountpoint '%1' doesn't exist")
68 .arg(m_mountPath));
71 return;
72 }
73
74 QFileInfo audio = QFileInfo(m_mountPath + PATHTO_AUDIO_DETECT);
75 QDir dvd = QDir(m_mountPath + PATHTO_DVD_DETECT);
76 QDir svcd = QDir(m_mountPath + PATHTO_SVCD_DETECT);
77 QDir vcd = QDir(m_mountPath + PATHTO_VCD_DETECT);
78 QDir bad_dvd = QDir(m_mountPath + PATHTO_BAD_DVD_MOUNT);
79 QDir bd = QDir(m_mountPath + PATHTO_BD_DETECT);
80
81 // Default is data media
83
84 // Default is mounted media
86
87 if (dvd.exists())
88 {
89 LOG(VB_MEDIA, LOG_INFO, "Probable DVD detected.");
92 }
93 else if (bd.exists())
94 {
95 LOG(VB_MEDIA, LOG_INFO, "Probable Blu-ray detected.");
98 }
99 else if (audio.exists())
100 {
101 LOG(VB_MEDIA, LOG_INFO, "Probable Audio CD detected.");
104 }
105 else if (vcd.exists() || svcd.exists())
106 {
107 LOG(VB_MEDIA, LOG_INFO, "Probable VCD/SVCD detected.");
110 }
111 else if (bad_dvd.exists())
112 {
113 LOG(VB_GENERAL, LOG_ERR,
114 "DVD incorrectly mounted? (ISO9660 instead of UDF)");
115 }
116 else
117 {
118 LOG(VB_GENERAL, LOG_ERR,
119 QString("CD/DVD '%1' contained none of\n").arg(m_mountPath) +
120 QString("\t\t\t%1, %2, %3 or %4")
123 LOG(VB_GENERAL, LOG_INFO, "Searching CD statistically - file by file!");
124 }
125
126 // If not DVD/AudioCD/VCD/SVCD, use parent's more generic version
129
130 // Unlock the door, and if appropriate unmount the media,
131 // so the user can press the manual eject button
132 if (m_allowEject)
133 {
134 unlock();
136 unmount();
137 }
138}
139
140void MythCDROM::setDeviceSpeed(const char *devicePath, int speed)
141{
142 LOG(VB_MEDIA, LOG_INFO,
143 QString("SetDeviceSpeed(%1,%2) - not implemented on this OS.")
144 .arg(devicePath).arg(speed));
145}
146
148{
149 udfread_block_input m_input; /* This *must* be the first entry in the struct */
151};
152
153static int def_close(udfread_block_input *p_gen)
154{
155 auto *p = (blockInput_t *)p_gen;
156 int result = -1;
157
158 if (p && p->m_file)
159 {
160 delete p->m_file;
161 p->m_file = nullptr;
162 result = 0;
163 }
164
165 return result;
166}
167
168static uint32_t def_size(udfread_block_input *p_gen)
169{
170 auto *p = (blockInput_t *)p_gen;
171
172 return (uint32_t)(p->m_file->GetRealFileSize() / UDF_BLOCK_SIZE);
173}
174
175static int def_read(udfread_block_input *p_gen, uint32_t lba,
176 void *buf, uint32_t nblocks,
177 [[maybe_unused]] int flags)
178{
179 int result = -1;
180 auto *p = (blockInput_t *)p_gen;
181
182 if (p && p->m_file && (p->m_file->Seek(static_cast<long long>(lba) * UDF_BLOCK_SIZE, SEEK_SET) != -1))
183 result = p->m_file->Read(buf, nblocks * UDF_BLOCK_SIZE) / UDF_BLOCK_SIZE;
184
185 return result;
186}
187
189{
190 ImageType imageType = kUnknown;
191
192 if (path.startsWith("bd:"))
193 imageType = kBluray;
194 else if (path.startsWith("dvd:"))
195 imageType = kDVD;
196 else
197 {
198 blockInput_t blockInput {};
199
200 blockInput.m_file = new RemoteFile(path); // Normally deleted via a call to udfread_close
201 blockInput.m_input.close = def_close;
202 blockInput.m_input.read = def_read;
203 blockInput.m_input.size = def_size;
204
205 if (blockInput.m_file->isOpen())
206 {
207 udfread *udf = udfread_init();
208 if (udfread_open_input(udf, &blockInput.m_input) == 0)
209 {
210 UDFDIR *dir = udfread_opendir(udf, "/BDMV");
211
212 if (dir)
213 {
214 LOG(VB_MEDIA, LOG_INFO, QString("Found Bluray at %1").arg(path));
215 imageType = kBluray;
216 }
217 else
218 {
219 dir = udfread_opendir(udf, "/VIDEO_TS");
220
221 if (dir)
222 {
223 LOG(VB_MEDIA, LOG_INFO, QString("Found DVD at %1").arg(path));
224 imageType = kDVD;
225 }
226 else
227 {
228 LOG(VB_MEDIA, LOG_ERR, QString("inspectImage - unknown"));
229 }
230 }
231
232 if (dir)
233 {
234 udfread_closedir(dir);
235 }
236
237 udfread_close(udf);
238 }
239 else
240 {
241 // Open failed, so we have clean this up here
242 delete blockInput.m_file;
243 }
244 }
245 else
246 {
247 LOG(VB_MEDIA, LOG_ERR, QString("inspectImage - unable to open \"%1\"").arg(path));
248 delete blockInput.m_file;
249 }
250 }
251
252 return imageType;
253}
static MythCDROM * get(QObject *par, const QString &devicePath, bool SuperMount, bool AllowEject)
Definition: mythcdrom.cpp:43
MythCDROM(QObject *par, const QString &DevicePath, bool SuperMount, bool AllowEject)
Definition: mythcdrom.cpp:57
@ kUnknown
Definition: mythcdrom.h:28
void setDeviceSpeed(const char *devicePath, int speed) override
Definition: mythcdrom.cpp:140
static ImageType inspectImage(const QString &path)
Definition: mythcdrom.cpp:188
void onDeviceMounted() override
Override this to perform any post mount logic.
Definition: mythcdrom.cpp:63
bool unmount()
Definition: mythmedia.h:108
virtual void onDeviceMounted(void)
Override this to perform any post mount logic.
Definition: mythmedia.h:133
QString m_mountPath
The path to this media's mount point.
Definition: mythmedia.h:153
bool m_allowEject
Allow the user to eject the media?. Read only.
Definition: mythmedia.h:165
MythMediaType m_mediaType
The type of media. Read only.
Definition: mythmedia.h:162
virtual MythMediaError unlock()
Definition: mythmedia.cpp:352
MythMediaStatus m_status
The status of the media as of the last call to checkMedia.
Definition: mythmedia.h:159
MythCDROM * GetMythCDROMDarwin(QObject *par, const QString &devicePath, bool SuperMount, bool AllowEject)
MythCDROM * GetMythCDROMFreeBSD(QObject *par, const QString &devicePath, bool SuperMount, bool AllowEject)
MythCDROM * GetMythCDROMLinux(QObject *par, const QString &devicePath, bool SuperMount, bool AllowEject)
static int def_close(udfread_block_input *p_gen)
Definition: mythcdrom.cpp:153
static constexpr const char * PATHTO_VCD_DETECT
Definition: mythcdrom.cpp:36
static constexpr const char * PATHTO_DVD_DETECT
Definition: mythcdrom.cpp:34
static uint32_t def_size(udfread_block_input *p_gen)
Definition: mythcdrom.cpp:168
static int def_read(udfread_block_input *p_gen, uint32_t lba, void *buf, uint32_t nblocks, int flags)
Definition: mythcdrom.cpp:175
static constexpr const char * PATHTO_SVCD_DETECT
Definition: mythcdrom.cpp:37
static constexpr const char * PATHTO_BD_DETECT
Definition: mythcdrom.cpp:35
static constexpr const char * PATHTO_AUDIO_DETECT
Definition: mythcdrom.cpp:40
static constexpr const char * PATHTO_BAD_DVD_MOUNT
Definition: mythcdrom.cpp:32
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
@ MEDIATYPE_BD
Definition: mythmedia.h:34
@ MEDIATYPE_DVD
Definition: mythmedia.h:29
@ MEDIATYPE_VCD
Definition: mythmedia.h:30
@ MEDIATYPE_AUDIO
Definition: mythmedia.h:28
@ MEDIATYPE_UNKNOWN
Definition: mythmedia.h:25
@ MEDIATYPE_DATA
Definition: mythmedia.h:26
@ MEDIASTAT_USEABLE
Definition: mythmedia.h:19
@ MEDIASTAT_MOUNTED
Definition: mythmedia.h:21
@ MEDIASTAT_ERROR
Unable to mount, but could be usable.
Definition: mythmedia.h:13
bool exists(str path)
Definition: xbmcvfs.py:51
RemoteFile * m_file
Definition: mythcdrom.cpp:150
udfread_block_input m_input
Definition: mythcdrom.cpp:149