diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/mediaScan/include/AbstractMedia.h | 10 | ||||
-rw-r--r-- | libs/mediaScan/include/Audio.h | 3 | ||||
-rw-r--r-- | libs/mediaScan/include/Movie.h | 5 | ||||
-rw-r--r-- | libs/mediaScan/src/AbstractMedia.cc | 18 | ||||
-rw-r--r-- | libs/mediaScan/src/Audio.cc | 49 | ||||
-rw-r--r-- | libs/mediaScan/src/Movie.cc | 20 | ||||
-rw-r--r-- | libs/util/include/util.h | 5 | ||||
-rw-r--r-- | libs/util/src/util.cc | 138 |
8 files changed, 245 insertions, 3 deletions
diff --git a/libs/mediaScan/include/AbstractMedia.h b/libs/mediaScan/include/AbstractMedia.h index 6dbf673..f877fb3 100644 --- a/libs/mediaScan/include/AbstractMedia.h +++ b/libs/mediaScan/include/AbstractMedia.h @@ -59,6 +59,7 @@ public: SupportedMediaType MediaType(void) const { return mediaType; } const char *MimeType(void) const { return mimeType; } const char *AbsolutePath(void) const; + const char *Format(void) const { return format; } virtual const char *KeyFile(void) const; ulong LastModified(void) const; const char *LogicalPath(void) const { return logicalPath; } @@ -72,15 +73,23 @@ public: virtual size_t ReadChunk(char *buf, size_t bufSize); ///< used to hide the differences between single- and multi-file media. virtual void Reset(void); + int Width(void) const { return width; } + int Height(void) const { return height; } void Dump(void) const; static const char *MediaType2Text(int Type); protected: cAbstractMedia(const cFile &File, const char *Mime, SupportedMediaType Type); + virtual void SetFormat(const char *Format); void SetMediaType(int NewType); void SetMimeType(const char *MimeType); const cFile &KeyPath(void) const { return keyPath; } + std::vector<cMediainfoReader::InfoEntry *> meta; int fd; + char *format; + short width; + short height; + double aspect; private: SupportedMediaType mediaType; @@ -88,7 +97,6 @@ private: char *uri; char *logicalPath; cFile keyPath; - std::vector<cMediainfoReader::InfoEntry *> meta; }; #endif /* ABSTRACTMEDIA_H */ diff --git a/libs/mediaScan/include/Audio.h b/libs/mediaScan/include/Audio.h index 3dc8faa..1677c53 100644 --- a/libs/mediaScan/include/Audio.h +++ b/libs/mediaScan/include/Audio.h @@ -32,11 +32,14 @@ public: cAudio(const cFile &File, const char *Mime); virtual ~cAudio(); + virtual void AddMeta(cMediainfoReader::InfoEntry *Entry); + virtual const char *Name(void) const; virtual bool NeedsFurtherScan(void) const; static void EnableDeepScan(bool DoScan); private: static const char *ContentType(const char *Extension); + mutable char *name; static SupportedExtension knownExtensions[]; friend class cMediaFactory; friend class FScanTest; diff --git a/libs/mediaScan/include/Movie.h b/libs/mediaScan/include/Movie.h index 36355b3..64d024d 100644 --- a/libs/mediaScan/include/Movie.h +++ b/libs/mediaScan/include/Movie.h @@ -33,11 +33,16 @@ public: virtual ~cMovie(); virtual void AddMeta(cMediainfoReader::InfoEntry *Entry); + bool IsHD(void) const { return isHD; } virtual bool NeedsFurtherScan(void) const; static void EnableDeepScan(bool DoScan); +protected: + virtual void SetFormat(const char *Format); + private: static const char *ContentType(const char *Extension); + bool isHD; static SupportedExtension knownExtensions[]; friend class cMediaFactory; friend class FScanTest; diff --git a/libs/mediaScan/src/AbstractMedia.cc b/libs/mediaScan/src/AbstractMedia.cc index 2cc85c5..40b94ea 100644 --- a/libs/mediaScan/src/AbstractMedia.cc +++ b/libs/mediaScan/src/AbstractMedia.cc @@ -36,9 +36,14 @@ #include <unistd.h> #include <tuple> #include <iostream> +#include <string> cAbstractMedia::cAbstractMedia(const cFile &File, const char *Mime, SupportedMediaType Type) : fd(-1) + , format(NULL) + , width(0) + , height(0) + , aspect(0) , mediaType(Type) , mimeType(Mime ? strdup(Mime) : NULL) , uri(NULL) @@ -54,10 +59,18 @@ cAbstractMedia::~cAbstractMedia() free(mimeType); free(uri); free(logicalPath); + free(format); } void cAbstractMedia::AddMeta(cMediainfoReader::InfoEntry* Entry) { + if (!Entry) return; + std::string name = std::get<0>(*Entry); + std::string value = std::get<1>(*Entry); + + if (!strcmp("Format", name.c_str()) && !format) SetFormat(value.c_str()); + else if (!strcmp("Width", name.c_str())) width = parseInt(value); + else if (!strcmp("Height", name.c_str())) height = parseInt(value); meta.push_back(Entry); } @@ -117,6 +130,11 @@ void cAbstractMedia::Reset(void) } } +void cAbstractMedia::SetFormat(const char *Format) +{ + format = strdup(Format); +} + void cAbstractMedia::SetMediaType(int NewType) { switch (NewType) { diff --git a/libs/mediaScan/src/Audio.cc b/libs/mediaScan/src/Audio.cc index fdaae7e..9420db6 100644 --- a/libs/mediaScan/src/Audio.cc +++ b/libs/mediaScan/src/Audio.cc @@ -23,8 +23,10 @@ * -------------------------------------------------------------- */ #include <Audio.h> +#include <StringBuilder.h> #include <stddef.h> #include <string.h> +#include <util.h> static bool deepScanEnabled = false; @@ -50,11 +52,23 @@ SupportedExtension cAudio::knownExtensions[] = { cAudio::cAudio(const cFile &File, const char *Mime) : cAbstractMedia(File, Mime, Audio) + , name(NULL) { } cAudio::~cAudio() { + free(name); +} + +void cAudio::AddMeta(cMediainfoReader::InfoEntry* Entry) +{ + if (!Entry) return; + std::string name = std::get<0>(*Entry); + std::string value = std::get<1>(*Entry); + + if (!strcmp("Bit rate", name.c_str())) width = parseInt(value); + cAbstractMedia::AddMeta(Entry); } void cAudio::EnableDeepScan(bool DoScan) @@ -70,6 +84,41 @@ const char *cAudio::ContentType(const char* Extension) return NULL; } +const char *cAudio::Name(void) const +{ + if (!name) { + cMediainfoReader::InfoEntry *performer = NULL, *album = NULL, *track = NULL; + + for (size_t i=0; i < meta.size(); ++i) { + cMediainfoReader::InfoEntry *ie = meta[i]; + std::string name = std::get<0>(*ie); + + if (!strcmp("Album", name.c_str())) album = ie; + else if (!strcmp("Performer", name.c_str())) performer = ie; + else if (!strcmp("Track name", name.c_str())) track = ie; + } + + if (track) { + std::string tmp = std::get<1>(*track); + cStringBuilder sb(tmp.c_str()); + + if (performer) { + tmp = std::get<1>(*performer); + sb.Append(" / ").Append(tmp.c_str()); + } + if (album) { + tmp = std::get<1>(*album); + sb.Append(" (").Append(tmp.c_str()).Append(")"); + } + name = sb.toString(); + } + else { + name = strdup(cAbstractMedia::Name()); + } + } + return name; +} + bool cAudio::NeedsFurtherScan(void) const { return deepScanEnabled; diff --git a/libs/mediaScan/src/Movie.cc b/libs/mediaScan/src/Movie.cc index d161dfe..51d1ff9 100644 --- a/libs/mediaScan/src/Movie.cc +++ b/libs/mediaScan/src/Movie.cc @@ -25,6 +25,7 @@ #include <Movie.h> #include <stddef.h> #include <string.h> +#include <util.h> static bool deepScanEnabled = true; @@ -64,8 +65,16 @@ const char *cMovie::ContentType(const char* Extension) void cMovie::AddMeta(cMediainfoReader::InfoEntry *Entry) { - if (!strcmp("Scan type", std::get<0>(*Entry).c_str())) { - if (!strcmp("Interlaced", std::get<1>(*Entry).c_str())) SetMediaType(MediaType() + 1); + if (!Entry) return; + std::string name = std::get<0>(*Entry); + std::string value = std::get<1>(*Entry); + + if (!strcmp("Scan type", name.c_str())) { + if (!strcmp("Interlaced", value.c_str())) SetMediaType(MediaType() + 1); + } + else if (!strcmp("Aspect", name.c_str())) { + aspect = parseAspect(value); + if (height > 0 && width > 0) width = height * aspect; } cAbstractMedia::AddMeta(Entry); } @@ -79,3 +88,10 @@ bool cMovie::NeedsFurtherScan(void) const { return deepScanEnabled; } + +void cMovie::SetFormat(const char* Format) { + if (!strcmp("Matroska", Format) || !strcmp("Flash Video", Format) + || !strcmp("MPEG-PS", Format) || !strcmp("MPEG-TS", Format) || !strcmp("MPEG-PES", Format)) + return; // skip containers + cAbstractMedia::SetFormat(Format); +}
\ No newline at end of file diff --git a/libs/util/include/util.h b/libs/util/include/util.h index 023c435..1f92380 100644 --- a/libs/util/include/util.h +++ b/libs/util/include/util.h @@ -26,6 +26,7 @@ #define UTIL_H #include <stdlib.h> +#include <string> #define FREE(m) { void *_tmp_ = m; m = NULL; free(_tmp_); } #define TO_STRING(s) #s #define EVER ;; @@ -37,6 +38,10 @@ extern const char *skipWhitespace(const char *Buffer); extern const char *getWord(char *buf, int bufSize, const char *src); extern const char *restOfLine(char *buf, int bufSize, const char *src); +extern double parseAspect(const char *input, const char **next = NULL); +extern double parseAspect(const std::string &input, const char **next = NULL); +extern long parseInt(const char *input, const char **next = NULL); +extern long parseInt(const std::string &input, const char **next = NULL); #endif /* UTIL_H */ diff --git a/libs/util/src/util.cc b/libs/util/src/util.cc index 61027a1..fa679da 100644 --- a/libs/util/src/util.cc +++ b/libs/util/src/util.cc @@ -59,3 +59,141 @@ const char *restOfLine(char *buf, int bufSize, const char *src) return *s ? s : NULL; } + +double parseAspect(const std::string &input, const char **next) +{ + return parseAspect(input.c_str(), next); +} + +double parseAspect(const char *input, const char **next) +{ + enum { Double, TwoInt, OneInt } mode = OneInt; + char buf[32]; + char *pd, *pmd, *nextBuf; + const char *ps, *pms; + + for (pd = buf, pmd = buf + sizeof(buf) - 1, ps=input, pms = input + strlen(input); ps < pms && pd < pmd; ++ps) { + switch (*ps) { + case ' ': + case '\t': + continue; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + *pd++ = *ps; + break; + + case '.': + mode = Double; + pms = ps; + break; + + case ':': + mode = TwoInt; + pms = ps; + break; + + default: + pms = --ps; + break; + } + } + *pd = 0; + + if (mode == OneInt) { + if (next) *next = ps; + return strtod(buf, NULL); + } + nextBuf = mode == TwoInt ? pd + 1 : pd; + + for (pd = nextBuf; ps < pms && pd < pmd; ++ps) { + switch (*ps) { + case ' ': + case '\t': + continue; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + *pd++ = *ps; + break; + + case '.': + mode = Double; + pms = ps; + break; + + case ':': + mode = TwoInt; + pms = ps; + break; + + default: + pms = --ps; + break; + } + } + *pd = 0; + if (next) *next = ps; + if (mode == Double) return strtod(buf, NULL); + long a = atol(buf); + long b = atol(nextBuf); + + return (double)a / (double)b; +} + +long parseInt(const std::string &input, const char **next) +{ + return parseInt(input.c_str(), next); +} + +long parseInt(const char *input, const char **next) +{ + char buf[32]; + char *pd, *pmd; + const char *ps, *pms; + + for (pd = buf, pmd = buf + sizeof(buf) - 1, ps=input, pms = input + strlen(input); ps < pms && pd < pmd; ++ps) { + switch (*ps) { + case ' ': + case '\t': + continue; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + *pd++ = *ps; + break; + + default: + pms = --ps; + break; + } + } + *pd = 0; + if (next) *next = ps; + + return atol(buf); +} |