libextractor

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

mp4_extractor.c (4856B)


      1 /*
      2      This file is part of libextractor.
      3      Copyright (C) 2012 Christian Grothoff
      4 
      5      libextractor is free software; you can redistribute it and/or modify
      6      it under the terms of the GNU General Public License as published
      7      by the Free Software Foundation; either version 3, or (at your
      8      option) any later version.
      9 
     10      libextractor is distributed in the hope that it will be useful, but
     11      WITHOUT ANY WARRANTY; without even the implied warranty of
     12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13      General Public License for more details.
     14 
     15      You should have received a copy of the GNU General Public License
     16      along with libextractor; see the file COPYING.  If not, write to the
     17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18      Boston, MA 02110-1301, USA.
     19  */
     20 
     21 /**
     22  * @file plugins/mp4_extractor.c
     23  * @brief plugin to support MP4 files
     24  * @author Christian Grothoff
     25  */
     26 #include "platform.h"
     27 #include "extractor.h"
     28 #include <mp4v2/mp4v2.h>
     29 
     30 
     31 /**
     32  * Callback invoked by libmp4v2 to open the file.
     33  * We cheated and passed our extractor context as
     34  * the filename (fingers crossed) and will simply
     35  * return it again to make it the handle.
     36  *
     37  * @param name "filename" to open
     38  * @param open mode, only reading allowed
     39  * @return NULL if the file is not opened for reading
     40  */
     41 static void*
     42 open_cb (const char *name,
     43          MP4FileMode mode)
     44 {
     45   void *ecp;
     46 
     47   if (FILEMODE_READ != mode)
     48     return NULL;
     49   if (1 != sscanf (name, "%p", &ecp))
     50     return NULL;
     51   return ecp;
     52 }
     53 
     54 
     55 /**
     56  * Seek callback for libmp4v2.
     57  *
     58  * @param handle the 'struct EXTRACTOR_ExtractContext'
     59  * @param pos target seek position (relative or absolute?)
     60  * @return true on failure, false on success
     61  */
     62 static int
     63 seek_cb (void *handle,
     64          int64_t pos)
     65 {
     66   struct EXTRACTOR_ExtractContext *ec = handle;
     67 
     68   fprintf (stderr, "Seek: %lld!\n", (long long) pos);
     69   if (-1 ==
     70       ec->seek (ec->cls,
     71                 pos,
     72                 SEEK_CUR))
     73     return true; /* failure */
     74   return false;
     75 }
     76 
     77 
     78 /**
     79  * Read callback for libmp4v2.
     80  *
     81  * @param handle the 'struct EXTRACTOR_ExtractContext'
     82  * @param buffer where to write data read
     83  * @param size desired number of bytes to read
     84  * @param nin where to write number of bytes read
     85  * @param maxChunkSize some chunk size (ignored)
     86  * @return true on failure, false on success
     87  */
     88 static int
     89 read_cb (void *handle,
     90          void *buffer,
     91          int64_t size,
     92          int64_t *nin,
     93          int64_t maxChunkSize)
     94 {
     95   struct EXTRACTOR_ExtractContext *ec = handle;
     96   void *buf;
     97   ssize_t ret;
     98 
     99   fprintf (stderr, "read!\n");
    100   *nin = 0;
    101   if (-1 ==
    102       (ret = ec->read (ec->cls,
    103                        &buf,
    104                        size)))
    105     return true; /* failure */
    106   memcpy (buffer, buf, ret);
    107   *nin = ret;
    108   return false; /* success */
    109 }
    110 
    111 
    112 /**
    113  * Write callback for libmp4v2.
    114  *
    115  * @param handle the 'struct EXTRACTOR_ExtractContext'
    116  * @param buffer data to write
    117  * @param size desired number of bytes to write
    118  * @param nin where to write number of bytes written
    119  * @param maxChunkSize some chunk size (ignored)
    120  * @return true on failure (always fails)
    121  */
    122 static int
    123 write_cb (void *handle,
    124           const void *buffer,
    125           int64_t size,
    126           int64_t *nout,
    127           int64_t maxChunkSize)
    128 {
    129   fprintf (stderr, "Write!?\n");
    130   return true; /* failure  */
    131 }
    132 
    133 
    134 /**
    135  * Write callback for libmp4v2.  Does nothing.
    136  *
    137  * @param handle the 'struct EXTRACTOR_ExtractContext'
    138  * @return false on success (always succeeds)
    139  */
    140 static int
    141 close_cb (void *handle)
    142 {
    143   fprintf (stderr, "Close!\n");
    144   return false; /* success */
    145 }
    146 
    147 
    148 #if 0
    149 /**
    150  * Wrapper to replace 'stat64' call by libmp4v2.
    151  */
    152 int
    153 stat_cb (const char *path,
    154          struct stat64 *buf)
    155 {
    156   void *ecp;
    157   struct EXTRACTOR_ExtractContext *ec;
    158 
    159   fprintf (stderr, "stat!\n");
    160   if (1 != sscanf (path, "%p", &ecp))
    161   {
    162     errno = EINVAL;
    163     return -1;
    164   }
    165   ec = ecp;
    166   memset (buf, 0, sizeof (struct stat));
    167   buf->st_size = ec->get_size (ec->cls);
    168   return 0;
    169 }
    170 
    171 
    172 #endif
    173 
    174 
    175 /**
    176  * Main entry method for the MP4 extraction plugin.
    177  *
    178  * @param ec extraction context provided to the plugin
    179  */
    180 void
    181 EXTRACTOR_mp4_extract_method (struct EXTRACTOR_ExtractContext *ec)
    182 {
    183   MP4FileProvider fp;
    184   MP4FileHandle mp4;
    185   const MP4Tags *tags;
    186   char ecp[128];
    187 
    188   if (1)
    189     return; /* plugin is known not to work yet;
    190          see issue 138 filed against MP4v2 lib */
    191   snprintf (ecp, sizeof (ecp), "%p", ec);
    192   fp.open = &open_cb;
    193   fp.seek = &seek_cb;
    194   fp.read = &read_cb;
    195   fp.write = &write_cb;
    196   fp.close = &close_cb;
    197   if (NULL == (mp4 = MP4ReadProvider (ecp,
    198                                       &fp)))
    199     return;
    200   tags = MP4TagsAlloc ();
    201   if (MP4TagsFetch (tags, mp4))
    202   {
    203     fprintf (stderr, "got tags!\n");
    204   }
    205   MP4Close (mp4, 0);
    206 }
    207 
    208 
    209 /* end of mp4_extractor.c */