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