libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

commit af0be8c6b6105ace644afebcb847df61411fbb52
parent 33c16e297af5aad1bd7ee22741c4c2fc347eee5c
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu, 23 Aug 2012 21:25:55 +0000

writing plugin for mp4v2 lib, incomplete, cannot work due to issue #138 in mp4v2 lib (stat not wrapped by api)

Diffstat:
MREADME | 2++
Mconfigure.ac | 15+++++++++++++++
Msrc/plugins/Makefile.am | 14++++++++++++++
Asrc/plugins/mp4_extractor.c | 207+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 238 insertions(+), 0 deletions(-)

diff --git a/README b/README @@ -53,7 +53,9 @@ available in order for maximum coverage: * libjpeg * libmagic (file) * libmpeg2 +* libmp4v2 * librpm +* libsmf * libtidy * libtiff * libvorbis / libogg diff --git a/configure.ac b/configure.ac @@ -294,6 +294,13 @@ AC_CHECK_LIB(mpeg2, mpeg2_init, AM_CONDITIONAL(HAVE_MPEG2, false))], AM_CONDITIONAL(HAVE_MPEG2, false)) +AC_CHECK_LIB(mp4v2, MP4ReadProvider, + [AC_CHECK_HEADERS([mp4v2/mp4v2.h], + AM_CONDITIONAL(HAVE_MP4, true) + AC_DEFINE(HAVE_MP4,1,[Have libmp4v2]), + AM_CONDITIONAL(HAVE_MP4, false))], + AM_CONDITIONAL(HAVE_MP4, false)) + AC_CHECK_LIB(jpeg, jpeg_std_error, [AC_CHECK_HEADERS([jpeglib.h], AM_CONDITIONAL(HAVE_JPEG, true) @@ -427,7 +434,9 @@ fi # smf requires glib.h CFLAGS_OLD=$CFLAGS +CPPFLAGS_OLD=$CPPFLAGS export CFLAGS="$CFLAGS $GLIB_CFLAGS" +export CPPFLAGS="$CPPFLAGS $GLIB_CFLAGS" AC_CHECK_LIB(smf, smf_load_from_memory, [AC_CHECK_HEADERS([smf.h], @@ -436,6 +445,7 @@ AC_CHECK_LIB(smf, smf_load_from_memory, AM_CONDITIONAL(HAVE_SMF, false))], AM_CONDITIONAL(HAVE_SMF, false)) export CFLAGS=$CFLAGS_OLD +export CPPFLAGS=$CPPFLAGS_OLD # check for gtk >= 2.6.0 AC_MSG_CHECKING(for gtk) @@ -667,6 +677,11 @@ then AC_MSG_NOTICE([NOTICE: libmpeg2 not found, mpeg2 support disabled]) fi +if test "x$HAVE_MP4V2_TRUE" = "x#" +then + AC_MSG_NOTICE([NOTICE: libmp4v2 not found, mp4 support disabled]) +fi + if test "x$HAVE_CXX" != "xyes" then AC_MSG_NOTICE([NOTICE: no C++ compiler found (not compiling plugins that require C++)]) diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am @@ -109,6 +109,11 @@ PLUGIN_JPEG=libextractor_jpeg.la TEST_JPEG=test_jpeg endif +if HAVE_MP4 +PLUGIN_MP4=libextractor_mp4.la +TEST_MP4=test_mp4 +endif + if HAVE_MPEG2 PLUGIN_MPEG=libextractor_mpeg.la TEST_MPEG=test_mpeg @@ -167,6 +172,7 @@ plugin_LTLIBRARIES = \ $(PLUGIN_JPEG) \ $(PLUGIN_MIDI) \ $(PLUGIN_MIME) \ + $(PLUGIN_MP4) \ $(PLUGIN_MPEG) \ $(PLUGIN_OGG) \ $(PLUGIN_RPM) \ @@ -379,6 +385,14 @@ test_mime_LDADD = \ $(top_builddir)/src/plugins/libtest.la +libextractor_mp4_la_SOURCES = \ + mp4_extractor.c +libextractor_mp4_la_LDFLAGS = \ + $(PLUGINFLAGS) +libextractor_mp4_la_LIBADD = \ + -lmp4v2 + + libextractor_mpeg_la_SOURCES = \ mpeg_extractor.c libextractor_mpeg_la_LDFLAGS = \ diff --git a/src/plugins/mp4_extractor.c b/src/plugins/mp4_extractor.c @@ -0,0 +1,207 @@ +/* + This file is part of libextractor. + (C) 2012 Christian Grothoff + + libextractor is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + libextractor 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libextractor; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file plugins/mp4_extractor.c + * @brief plugin to support MP4 files + * @author Christian Grothoff + */ +#include "platform.h" +#include "extractor.h" +#include <mp4v2/mp4v2.h> + + +/** + * Callback invoked by libmp4v2 to open the file. + * We cheated and passed our extractor context as + * the filename (fingers crossed) and will simply + * return it again to make it the handle. + * + * @param name "filename" to open + * @param open mode, only reading allowed + * @return NULL if the file is not opened for reading + */ +static void* +open_cb (const char *name, + MP4FileMode mode) +{ + void *ecp; + + if (FILEMODE_READ != mode) + return NULL; + if (1 != sscanf (name, "%p", &ecp)) + return NULL; + return ecp; +} + + +/** + * Seek callback for libmp4v2. + * + * @param handle the 'struct EXTRACTOR_ExtractContext' + * @param pos target seek position (relative or absolute?) + * @return true on failure, false on success + */ +static int +seek_cb (void *handle, + int64_t pos) +{ + struct EXTRACTOR_ExtractContext *ec = handle; + + fprintf (stderr, "Seek: %lld!\n", (long long) pos); + if (-1 == + ec->seek (ec->cls, + pos, + SEEK_CUR)) + return true; /* failure */ + return false; +} + + +/** + * Read callback for libmp4v2. + * + * @param handle the 'struct EXTRACTOR_ExtractContext' + * @param buffer where to write data read + * @param size desired number of bytes to read + * @param nin where to write number of bytes read + * @param maxChunkSize some chunk size (ignored) + * @return true on failure, false on success + */ +static int +read_cb (void *handle, + void *buffer, + int64_t size, + int64_t *nin, + int64_t maxChunkSize) +{ + struct EXTRACTOR_ExtractContext *ec = handle; + void *buf; + ssize_t ret; + + fprintf (stderr, "read!\n"); + *nin = 0; + if (-1 == + (ret = ec->read (ec->cls, + &buf, + size))) + return true; /* failure */ + memcpy (buffer, buf, ret); + *nin = ret; + return false; /* success */ +} + + +/** + * Write callback for libmp4v2. + * + * @param handle the 'struct EXTRACTOR_ExtractContext' + * @param buffer data to write + * @param size desired number of bytes to write + * @param nin where to write number of bytes written + * @param maxChunkSize some chunk size (ignored) + * @return true on failure (always fails) + */ +static int +write_cb (void *handle, + const void *buffer, + int64_t size, + int64_t *nout, + int64_t maxChunkSize) +{ + fprintf (stderr, "Write!?\n"); + return true; /* failure */ +} + + +/** + * Write callback for libmp4v2. Does nothing. + * + * @param handle the 'struct EXTRACTOR_ExtractContext' + * @return false on success (always succeeds) + */ +static int +close_cb (void *handle) +{ + fprintf (stderr, "Close!\n"); + return false; /* success */ +} + + +#if 0 +/** + * Wrapper to replace 'stat64' call by libmp4v2. + */ +int +stat_cb (const char * path, + struct stat64 * buf) +{ + void *ecp; + struct EXTRACTOR_ExtractContext *ec; + + fprintf (stderr, "stat!\n"); + if (1 != sscanf (path, "%p", &ecp)) + { + errno = EINVAL; + return -1; + } + ec = ecp; + memset (buf, 0, sizeof (struct stat)); + buf->st_size = ec->get_size (ec->cls); + return 0; +} +#endif + + +/** + * Main entry method for the MP4 extraction plugin. + * + * @param ec extraction context provided to the plugin + */ +void +EXTRACTOR_mp4_extract_method (struct EXTRACTOR_ExtractContext *ec) +{ + MP4FileProvider fp; + MP4FileHandle mp4; + const MP4Tags *tags; + char ecp[128]; + void *dl; + + if (1) + return; /* plugin is known not to work yet; + see issue 138 filed against MP4v2 lib */ + snprintf (ecp, sizeof (ecp), "%p", ec); + fp.open = &open_cb; + fp.seek = &seek_cb; + fp.read = &read_cb; + fp.write = &write_cb; + fp.close = &close_cb; + if (NULL == (mp4 = MP4ReadProvider (ecp, + &fp))) + return; + tags = MP4TagsAlloc (); + if (MP4TagsFetch (tags, mp4)) + { + fprintf (stderr, "got tags!\n"); + } + MP4Close (mp4, 0); +} + +/* end of mp4_extractor.c */