liblightmediascanner_la_LIBADD = -ldl @SQLITE3_LIBS@ @LTLIBICONV@
liblightmediascanner_la_LDFLAGS = -version-info @version_info@
-
-# shared sources/headers
-noinst_LTLIBRARIES = shared/libshared.la
-shared_libshared_la_SOURCES = shared/util.c
-
-noinst_HEADERS += shared/util.h
API int lms_db_video_free(lms_db_video_t *ldv) GNUC_NON_NULL(1);
API int lms_db_video_add(lms_db_video_t *ldv, struct lms_video_info *info) GNUC_NON_NULL(1, 2);
+ API int lms_stream_video_info_aspect_ratio_guess(struct lms_stream_video_info *info) GNUC_NON_NULL(1);
+
/* Playlist Records */
struct lms_playlist_info {
int64_t id;
return r;
}
+
+/**
+ * If aspect ratio wasn't set yet, guess it from stream video info size.
+ *
+ * This function calls lms_aspect_ratio_guess() and thus the
+ * aspect_ratio string will be allocated with malloc(). Remember to
+ * free() it afterwards.
+ *
+ * @param info where to query width and height, then setting aspect_ratio string.
+ *
+ * @return 1 on success, 0 on failure.
+ */
+int
+lms_stream_video_info_aspect_ratio_guess(struct lms_stream_video_info *info)
+{
+ if (info->aspect_ratio.len > 0)
+ return 1;
+
+ return lms_aspect_ratio_guess(&info->aspect_ratio,
+ info->width,
+ info->height);
+}
#include <lightmediascanner_utils.h>
#include <ctype.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <alloca.h>
+#include <math.h>
/**
* Strips string, in place.
return 1;
}
+/* Euclidean algorithm
+ * http://en.wikipedia.org/wiki/Euclidean_algorithm */
+static unsigned int
+gcd(unsigned int a, unsigned int b)
+{
+ unsigned int t;
+
+ while (b) {
+ t = b;
+ b = a % t;
+ a = t;
+ }
+
+ return a;
+}
+
+/**
+ * Guess aspect ratio from known ratios or Greatest Common Divisor.
+ *
+ * @param ret where to store the newly allocated string with ratio.
+ * @param width frame width to guess aspect ratio.
+ * @param height frame height to guess aspect ratio.
+ * @return 1 on success and @c ret->str must be @c free()d, 0 on failure.
+ */
+int
+lms_aspect_ratio_guess(struct lms_string_size *ret, int width, int height)
+{
+ static struct {
+ double ratio;
+ struct lms_string_size str;
+ } *itr, known_ratios[] = {
+ {16.0 / 9.0, LMS_STATIC_STRING_SIZE("16:9")},
+ {4.0 / 3.0, LMS_STATIC_STRING_SIZE("4:3")},
+ {3.0 / 2.0, LMS_STATIC_STRING_SIZE("3:2")},
+ {5.0 / 3.0, LMS_STATIC_STRING_SIZE("5:3")},
+ {8.0 / 5.0, LMS_STATIC_STRING_SIZE("8:5")},
+ {1.85, LMS_STATIC_STRING_SIZE("1.85:1")},
+ {1.4142, LMS_STATIC_STRING_SIZE("1.41:1")},
+ {2.39, LMS_STATIC_STRING_SIZE("2.39:1")},
+ {16.18 / 10.0, LMS_STATIC_STRING_SIZE("16.18:10")},
+ {-1.0, {NULL, 0}}
+ };
+ double ratio;
+ unsigned num, den, f;
+
+ if (width <= 0 || height <= 0) {
+ ret->len = 0;
+ ret->str = NULL;
+ return 0;
+ }
+
+ ratio = (double)width / (double)height;
+ for (itr = known_ratios; itr->ratio > 0.0; itr++) {
+ if (fabs(ratio - itr->ratio) <= 0.01)
+ return lms_string_size_dup(ret, &itr->str);
+ }
+
+ f = gcd(width, height);
+
+ num = width / f;
+ den = height / f;
+ ret->len = asprintf(&ret->str, "%u:%u", num, den);
+ if (ret->len == (unsigned int)-1) {
+ ret->len = 0;
+ ret->str = NULL;
+ return 0;
+ }
+
+ return 1;
+}
+
+
/**
* Find out which of the given extensions matches the given name.
*
return -1;
}
+
+/**
+ * Extract name from a path given its path string, length, base and extension.
+ *
+ * @param name where to store the result.
+ * @param path the input path to base the name on.
+ * @param pathlen the path size in bytes.
+ * @param baselen where (offset int bytes) in path starts the filename (base name).
+ * @param extlen the extension length in bytes.
+ * @param cs_conv charset conversion to use, if none use @c NULL.
+ * @return 1 on success, 0 on failure.
+ */
+int
+lms_name_from_path(struct lms_string_size *name, const char *path, unsigned int pathlen, unsigned int baselen, unsigned int extlen, struct lms_charset_conv *cs_conv)
+{
+ int size = pathlen - baselen - extlen;
+
+ name->str = malloc(size + 1);
+ if (!name->str) {
+ name->len = 0;
+ return 0;
+ }
+
+ name->len = size;
+ memcpy(name->str, path + baselen, size);
+ name->str[size] = '\0';
+
+ if (cs_conv)
+ lms_charset_conv(cs_conv, &name->str, &name->len);
+
+ return 1;
+}
extern "C" {
#endif
+#include <lightmediascanner_charset_conv.h>
struct lms_string_size {
char *str;
API int lms_string_size_dup(struct lms_string_size *dst, const struct lms_string_size *src) GNUC_NON_NULL(1, 2);
API int lms_string_size_strndup(struct lms_string_size *dst, const char *src, int size) GNUC_NON_NULL(1);
+ API int lms_aspect_ratio_guess(struct lms_string_size *ret, int width, int height) GNUC_NON_NULL(1);
+
API int lms_which_extension(const char *name, unsigned int name_len, const struct lms_string_size *exts, unsigned int exts_len) GNUC_NON_NULL(1, 3);
+ API int lms_name_from_path(struct lms_string_size *name, const char *path, unsigned int pathlen, unsigned int baselen, unsigned int extlen, struct lms_charset_conv *cs_conv) GNUC_NON_NULL(1, 2);
#ifdef __cplusplus
+++ /dev/null
-/**
- * Copyright (C) 2013 Intel Corporation. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- * @author Lucas De Marchi <lucas.demarchi@intel.com>
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "util.h"
-
-struct lms_string_size str_extract_name_from_path(
- const char *path, unsigned int pathlen, unsigned int baselen,
- const struct lms_string_size *ext, struct lms_charset_conv *cs_conv)
-{
- struct lms_string_size str;
-
- str.len = pathlen - baselen - ext->len;
- str.str = malloc(str.len + 1);
- if (!str.str)
- return (struct lms_string_size) { };
- memcpy(str.str, path + baselen, str.len);
- str.str[str.len] = '\0';
- if (cs_conv)
- lms_charset_conv(cs_conv, &str.str, &str.len);
-
- return str;
-}
-
-/* Euclidean algorithm
- * http://en.wikipedia.org/wiki/Euclidean_algorithm */
-static unsigned int gcd(unsigned int a, unsigned int b)
-{
- unsigned int t;
-
- while (b) {
- t = b;
- b = a % t;
- a = t;
- }
-
- return a;
-}
-
-void reduce_gcd(unsigned int w, unsigned int h, unsigned int *dw,
- unsigned int *dh)
-{
- unsigned int f;
-
- *dw = w;
- *dh = h;
-
- if (!w || !h)
- return;
-
- f = gcd(w, h);
- *dw /= f;
- *dh /= f;
-}
AM_LDFLAGS = -module -avoid-version -shared $(GCLDFLAGS)
AM_CFLAGS = -fvisibility=hidden $(WARNINGFLAGS)
AM_CPPFLAGS = -include $(top_builddir)/config.h \
- -I$(top_srcdir)/src/lib @SQLITE3_CFLAGS@
+ -I$(top_srcdir)/src/lib -I$(srcdir) @SQLITE3_CFLAGS@
pkgdir = $(pluginsdir)
-PLUGINS_LIBADD = $(top_builddir)/src/lib/liblightmediascanner.la \
- $(top_builddir)/src/lib/shared/libshared.la
+PLUGINS_LIBADD = $(top_builddir)/src/lib/liblightmediascanner.la
pkg_LTLIBRARIES =
BUILT_SOURCES =
EXTRA_DIST =
SUBDIRS =
-noinst_HEADERS =
+noinst_HEADERS = shared/util.h
if USE_MODULE_DUMMY
pkg_LTLIBRARIES += dummy/dummy.la
/* other fields are ignored */
} __attribute__((packed)) video;
- unsigned int num, den;
r = read(fd, &video, sizeof(video));
if (r != sizeof(video))
s->base.codec = *_video_codec_id_to_str(video.compression_id);
s->base.video.width = get_le32(&video.width);
s->base.video.height = get_le32(&video.height);
-
- reduce_gcd(s->base.video.width, s->base.video.height, &num, &den);
- asprintf(&s->base.video.aspect_ratio.str, "%u:%u", num, den);
- s->base.video.aspect_ratio.len = s->base.video.aspect_ratio.str ?
- strlen(s->base.video.aspect_ratio.str) : 0;
+ lms_stream_video_info_aspect_ratio_guess(&s->base.video);
}
_stream_copy_extension_properties(s);
lms_string_size_strip_and_free(&info.genre);
if (!info.title.str)
- info.title = str_extract_name_from_path(finfo->path, finfo->path_len,
- finfo->base,
- &_exts[((long) match) - 1],
- ctxt->cs_conv);
+ lms_name_from_path(&info.title, finfo->path, finfo->path_len,
+ finfo->base, _exts[((long) match) - 1].len,
+ ctxt->cs_conv);
if (info.type == LMS_STREAM_TYPE_AUDIO) {
struct lms_audio_info audio_info = { };
#include <lightmediascanner_plugin.h>
#include <lightmediascanner_db.h>
-#include <shared/util.h>
#include <stdio.h>
#include <stdlib.h>
title_fallback:
if (!info.title.str)
- info.title = str_extract_name_from_path(finfo->path, finfo->path_len,
- finfo->base,
- &_exts[((long) match) - 1],
- NULL);
+ lms_name_from_path(&info.title, finfo->path, finfo->path_len,
+ finfo->base, _exts[((long) match) - 1].len,
+ NULL);
if (info.title.str)
lms_charset_conv(ctxt->cs_conv, &info.title.str, &info.title.len);
}
if (!info.title.str)
- info.title = str_extract_name_from_path(finfo->path, finfo->path_len,
- finfo->base,
- &_exts[((long) match) - 1],
- ctxt->cs_conv);
+ lms_name_from_path(&info.title, finfo->path, finfo->path_len,
+ finfo->base, _exts[((long) match) - 1].len,
+ ctxt->cs_conv);
if (info.trackno == -1)
info.trackno = 0;
info.date = finfo->mtime;
if (!info.title.str)
- info.title = str_extract_name_from_path(finfo->path, finfo->path_len,
- finfo->base,
- &_exts[((long) match) - 1],
- ctxt->cs_conv);
+ lms_name_from_path(&info.title, finfo->path, finfo->path_len,
+ finfo->base, _exts[((long) match) - 1].len,
+ ctxt->cs_conv);
if (info.artist.str)
lms_charset_conv(ctxt->cs_conv, &info.artist.str, &info.artist.len);
#include <lightmediascanner_plugin.h>
#include <lightmediascanner_db.h>
-#include <shared/util.h>
#include <mp4v2/mp4v2.h>
#include <string.h>
return ret;
}
-static struct lms_string_size
-_guess_aspect_ratio(const struct lms_stream_video_info *info)
-{
- static struct {
- double ratio;
- struct lms_string_size str;
- } *itr, known_ratios[] = {
- {16.0 / 9.0, LMS_STATIC_STRING_SIZE("16:9")},
- {4.0 / 3.0, LMS_STATIC_STRING_SIZE("4:3")},
- {3.0 / 2.0, LMS_STATIC_STRING_SIZE("3:2")},
- {5.0 / 3.0, LMS_STATIC_STRING_SIZE("5:3")},
- {8.0 / 5.0, LMS_STATIC_STRING_SIZE("8:5")},
- {1.85, LMS_STATIC_STRING_SIZE("1.85:1")},
- {1.4142, LMS_STATIC_STRING_SIZE("1.41:1")},
- {2.39, LMS_STATIC_STRING_SIZE("2.39:1")},
- {16.18 / 10.0, LMS_STATIC_STRING_SIZE("16.18:10")},
- {-1.0, {NULL, 0}}
- };
- double ratio;
-
- if (info->width == 0 || info->height == 0)
- return nullstr;
-
- ratio = (double)info->width / (double)info->height;
- for (itr = known_ratios; itr->ratio > 0.0; itr++) {
- if (fabs(ratio - itr->ratio) <= 0.01)
- return itr->str;
- }
-
- return nullstr;
-}
-
static int
_parse(struct plugin *plugin, struct lms_context *ctxt, const struct lms_file_info *finfo, void *match)
{
s->video.width = MP4GetTrackVideoWidth(mp4_fh, id);
s->video.height = MP4GetTrackVideoHeight(mp4_fh, id);
s->video.framerate = MP4GetTrackVideoFrameRate(mp4_fh, id);
- s->video.aspect_ratio = _guess_aspect_ratio(&s->video);
+ lms_stream_video_info_aspect_ratio_guess(&s->video);
}
s->next = video_info.streams;
lms_string_size_strip_and_free(&info.genre);
if (!info.title.str)
- info.title = str_extract_name_from_path(finfo->path, finfo->path_len,
- finfo->base,
- &_exts[((long) match) - 1],
- NULL);
+ lms_name_from_path(&info.title, finfo->path, finfo->path_len,
+ finfo->base, _exts[((long) match) - 1].len,
+ NULL);
if (info.title.str)
lms_charset_conv(ctxt->cs_conv, &info.title.str, &info.title.len);
if (info.artist.str)
while (video_info.streams) {
struct lms_stream *s = video_info.streams;
video_info.streams = s->next;
- if (s->type == LMS_STREAM_TYPE_VIDEO)
+ if (s->type == LMS_STREAM_TYPE_VIDEO) {
free(s->codec.str); /* ugly, but h264 needs alloc */
+ free(s->video.aspect_ratio.str);
+ }
free(s->lang.str);
free(s);
}
#include <lightmediascanner_plugin.h>
#include <lightmediascanner_db.h>
#include <lightmediascanner_utils.h>
-#include <shared/util.h>
#include <assert.h>
#include <errno.h>
num = s->video.ti.aspect_numerator;
den = s->video.ti.aspect_denominator;
- if (num && den) {
- reduce_gcd(num, den, &num, &den);
- asprintf(&s->base.video.aspect_ratio.str, "%u:%u", num, den);
- s->base.video.aspect_ratio.len =
- s->base.video.aspect_ratio.str ?
- strlen(s->base.video.aspect_ratio.str) : 0;
- }
+ lms_aspect_ratio_guess(&s->base.video.aspect_ratio, num, den);
}
}
goto done;
if (!info.title.str)
- info.title = str_extract_name_from_path(finfo->path, finfo->path_len,
- finfo->base,
- &_exts[((long) match) - 1],
- NULL);
+ lms_name_from_path(&info.title, finfo->path, finfo->path_len,
+ finfo->base, _exts[((long) match) - 1].len,
+ NULL);
if (info.title.str)
lms_charset_conv(ctxt->cs_conv, &info.title.str, &info.title.len);
if (info.artist.str)
#include <lightmediascanner_plugin.h>
#include <lightmediascanner_utils.h>
#include <lightmediascanner_db.h>
-#include <shared/util.h>
#include <sys/types.h>
#include <sys/stat.h>
info.date = finfo->mtime;
if (!info.title.str)
- info.title = str_extract_name_from_path(finfo->path, finfo->path_len,
- finfo->base,
- &_exts[((long) match) - 1],
- NULL);
+ lms_name_from_path(&info.title, finfo->path, finfo->path_len,
+ finfo->base, _exts[((long) match) - 1].len,
+ NULL);
if (info.title.str)
lms_charset_conv(ctxt->cs_conv, &info.title.str, &info.title.len);
if (info.artist.str)
#include <lightmediascanner_plugin.h>
#include <lightmediascanner_db.h>
-#include <shared/util.h>
#include <sys/types.h>
#include <sys/stat.h>
lms_string_size_strip_and_free(&info.artist);
if (!info.title.str)
- info.title = str_extract_name_from_path(finfo->path, finfo->path_len,
- finfo->base,
- &_exts[((long) match) - 1],
- NULL);
+ lms_name_from_path(&info.title, finfo->path, finfo->path_len,
+ finfo->base, _exts[((long) match) - 1].len,
+ NULL);
if (info.title.str)
lms_charset_conv(ctxt->cs_conv, &info.title.str, &info.title.len);
#include <stddef.h>
#include <lightmediascanner_utils.h>
-#include <lightmediascanner_charset_conv.h>
#define NSEC100_PER_SEC 10000000ULL
#define MSEC_PER_SEC 1000ULL
#else
#error "Unknown byte order"
#endif
-
-
-struct lms_string_size str_extract_name_from_path(
- const char *path, unsigned int pathlen, unsigned int baselen,
- const struct lms_string_size *ext, struct lms_charset_conv *cs_conv);
-
-void reduce_gcd(unsigned int w, unsigned int h, unsigned int *dw,
- unsigned int *dh);
_parse_info(fd, &info);
if (!info.title.str)
- info.title = str_extract_name_from_path(finfo->path, finfo->path_len,
- finfo->base,
- &_exts[((long) match) - 1],
- ctxt->cs_conv);
+ lms_name_from_path(&info.title, finfo->path, finfo->path_len,
+ finfo->base, _exts[((long) match) - 1].len,
+ ctxt->cs_conv);
info.id = finfo->id;