MythTV master
mythdvdinfo.cpp
Go to the documentation of this file.
1// Std
2#include <fcntl.h>
3#include <zlib.h>
4
5#undef Z_NULL
6#define Z_NULL nullptr
7
8// Qt
9#include <QDir>
10
11// MythTV
13
14#include "io/mythiowrapper.h"
15#include "mythdvdinfo.h"
16
17MythDVDInfo::MythDVDInfo(const QString &Filename)
18{
19 LOG(VB_PLAYBACK, LOG_INFO, QString("DVDInfo: Trying %1").arg(Filename));
20 QString name = Filename;
21 if (name.startsWith("dvd:"))
22 {
23 name.remove(0,4);
24 while (name.startsWith("//"))
25 name.remove(0,1);
26 }
27
28 QByteArray fname = name.toLocal8Bit();
29 dvdnav_status_t res = dvdnav_open(&m_nav, fname.constData());
30 if (res == DVDNAV_STATUS_ERR)
31 {
32 m_lastError = tr("Failed to open device at %1").arg(fname.constData());
33 LOG(VB_GENERAL, LOG_ERR, QString("DVDInfo: ") + m_lastError);
34 return;
35 }
36
37 GetNameAndSerialNum(m_nav, m_name, m_serialnumber, name, QString("DVDInfo: "));
38}
39
41{
42 if (m_nav)
43 dvdnav_close(m_nav);
44 LOG(VB_PLAYBACK, LOG_INFO, QString("DVDInfo: Finishing."));
45}
46
47bool MythDVDInfo::IsValid(void) const
48{
49 return m_nav != nullptr;
50}
51
53 QString &Name,
54 QString &Serialnum,
55 const QString &Filename,
56 const QString &LogPrefix)
57{
58 const char* dvdname = nullptr;
59 const char* dvdserial = nullptr;
60
61 if (dvdnav_get_title_string(Nav, &dvdname) == DVDNAV_STATUS_ERR)
62 LOG(VB_GENERAL, LOG_ERR, LogPrefix + "Failed to get name.");
63 if (dvdnav_get_serial_string(Nav, &dvdserial) == DVDNAV_STATUS_ERR)
64 LOG(VB_GENERAL, LOG_ERR, LogPrefix + "Failed to get serial number.");
65
66 Name = QString(dvdname);
67 Serialnum = QString(dvdserial);
68
69 if (Name.isEmpty() && Serialnum.isEmpty())
70 {
71 struct stat stat {};
72 if ((MythFileStat(Filename.toLocal8Bit(), &stat) == 0) && S_ISDIR(stat.st_mode))
73 {
74 // Name and serial number are empty because we're reading
75 // from a directory (and not a device or image).
76
77 // Use the directory name for the DVD name
78 QDir dir(Filename);
79 Name = dir.dirName();
80 LOG(VB_PLAYBACK, LOG_DEBUG, LogPrefix + QString("Generated dvd name '%1'")
81 .arg(Name));
82
83 // And use the CRC of VTS_01_0.IFO as a serial number
84 QString ifo = Filename + QString("/VIDEO_TS/VTS_01_0.IFO");
85 int fd = MythFileOpen(ifo.toLocal8Bit(), O_RDONLY);
86
87 if (fd > 0)
88 {
89 DvdBuffer buf {};
90 ssize_t read = 0;
91 auto crc = static_cast<uint32_t>(crc32(0L, Z_NULL, 0));
92
93 while((read = MythFileRead(fd, buf.data(), buf.size())) > 0)
94 crc = static_cast<uint32_t>(crc32(crc, buf.data(), static_cast<uint>(read)));
95
96 MythfileClose(fd);
97 Serialnum = QString("%1__gen").arg(crc, 0, 16, QChar('0'));
98 LOG(VB_PLAYBACK, LOG_DEBUG, LogPrefix + QString("Generated serial number '%1'")
99 .arg(Serialnum));
100 }
101 else
102 {
103 LOG(VB_GENERAL, LOG_ERR, LogPrefix + QString("Unable to open %2 to generate serial number")
104 .arg(ifo));
105 }
106 }
107 }
108}
109
110bool MythDVDInfo::GetNameAndSerialNum(QString &Name, QString &SerialNumber)
111{
112 Name = m_name;
113 SerialNumber = m_serialnumber;
114 return !(Name.isEmpty() && SerialNumber.isEmpty());
115}
116
117QString MythDVDInfo::GetLastError(void) const
118{
119 return m_lastError;
120}
dvdnav_t * m_nav
Definition: mythdvdinfo.h:37
QString m_name
Definition: mythdvdinfo.h:38
QString GetLastError(void) const
~MythDVDInfo(void)
Definition: mythdvdinfo.cpp:40
bool GetNameAndSerialNum(QString &Name, QString &SerialNumber)
QString m_lastError
Definition: mythdvdinfo.h:40
MythDVDInfo(const QString &Filename)
Definition: mythdvdinfo.cpp:17
bool IsValid(void) const
Definition: mythdvdinfo.cpp:47
QString m_serialnumber
Definition: mythdvdinfo.h:39
static uint32_t crc32(const unsigned char *data, int len)
Definition: dsmcc.cpp:617
unsigned int uint
Definition: freesurround.h:24
#define Z_NULL
Definition: mythdvdinfo.cpp:6
std::array< uint8_t, DVD_BLOCK_SIZE > DvdBuffer
Definition: mythdvdinfo.h:17
ssize_t MythFileRead(int FileID, void *Buffer, size_t Count)
int MythfileClose(int FileID)
int MythFileOpen(const char *Pathname, int Flags)
int MythFileStat(const char *Path, struct stat *Buf)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
def read(device=None, features=[])
Definition: disc.py:35