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