gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r23265 - in Extractor/src/plugins: . old


From: gnunet
Subject: [GNUnet-SVN] r23265 - in Extractor/src/plugins: . old
Date: Thu, 16 Aug 2012 23:50:39 +0200

Author: grothoff
Date: 2012-08-16 23:50:39 +0200 (Thu, 16 Aug 2012)
New Revision: 23265

Added:
   Extractor/src/plugins/test_thumbnailffmpeg.c
   Extractor/src/plugins/thumbnailffmpeg_extractor.c
Removed:
   Extractor/src/plugins/old/thumbnailffmpeg_extractor.c
Modified:
   Extractor/src/plugins/Makefile.am
   Extractor/src/plugins/thumbnailgtk_extractor.c
Log:
getting ffmpeg thumbnailer to compile with recent ffmpeg libs

Modified: Extractor/src/plugins/Makefile.am
===================================================================
--- Extractor/src/plugins/Makefile.am   2012-08-16 17:03:29 UTC (rev 23264)
+++ Extractor/src/plugins/Makefile.am   2012-08-16 21:50:39 UTC (rev 23265)
@@ -48,11 +48,17 @@
 TEST_MIME=test_mime
 
 if HAVE_GTK
-# Thumbnailer requires MAGIC and GTK
+# Gtk-thumbnailer requires MAGIC and GTK
 PLUGIN_GTK=libextractor_thumbnailgtk.la
 TEST_GTK=test_thumbnailgtk
 endif
+
+if HAVE_FFMPEG
+# FFmpeg-thumbnailer requires MAGIC and FFMPEG
+PLUGIN_FFMPEG=libextractor_thumbnailffmpeg.la
+TEST_FFMPEG=test_thumbnailffmpeg
 endif
+endif
 
 if HAVE_GIF
 PLUGIN_GIF=libextractor_gif.la
@@ -116,6 +122,7 @@
   libextractor_wav.la \
   libextractor_zip.la \
   $(PLUGIN_GTK) \
+  $(PLUGIN_FFMPEG) \
   $(PLUGIN_ZLIB) \
   $(PLUGIN_OGG) \
   $(PLUGIN_MIME) \
@@ -145,6 +152,7 @@
   test_nsfe \
   $(TEST_ZLIB) \
   $(TEST_GTK) \
+  $(TEST_FFMPEG) \
   $(TEST_OGG) \
   $(TEST_MIME) \
   $(TEST_TIFF) \
@@ -456,3 +464,16 @@
   test_gstreamer.c
 test_gstreamer_LDADD = \
   $(top_builddir)/src/plugins/libtest.la
+
+
+libextractor_thumbnailffmpeg_la_SOURCES = \
+  thumbnailffmpeg_extractor.c
+libextractor_thumbnailffmpeg_la_LDFLAGS = \
+  $(PLUGINFLAGS)
+libextractor_thumbnailffmpeg_la_LIBADD = \
+  -lavutil -lavformat -lavcodec -lswscale -lmagic
+
+test_thumbnailffmpeg_SOURCES = \
+  test_thumbnailffmpeg.c
+test_thumbnailffmpeg_LDADD = \
+  $(top_builddir)/src/plugins/libtest.la

Deleted: Extractor/src/plugins/old/thumbnailffmpeg_extractor.c
===================================================================
--- Extractor/src/plugins/old/thumbnailffmpeg_extractor.c       2012-08-16 
17:03:29 UTC (rev 23264)
+++ Extractor/src/plugins/old/thumbnailffmpeg_extractor.c       2012-08-16 
21:50:39 UTC (rev 23265)
@@ -1,655 +0,0 @@
-/*
-     This file is part of libextractor.
-     Copyright (C) 2008 Heikki Lindholm
-
-     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 2, 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 thumbnailffmpeg_extractor.c
- * @author Heikki Lindholm
- * @brief this extractor produces a binary encoded
- * thumbnail of images and videos using the ffmpeg libs.
- */
-
-/* This is a thumbnail extractor using the ffmpeg libraries that will 
eventually
-   support extracting thumbnails from both image and video files. 
-
-   Note that ffmpeg has a few issues:
-   (1) there are no recent official releases of the ffmpeg libs
-   (2) ffmpeg has a history of having security issues (parser is not robust)
-
-   So this plugin cannot be recommended for system with high security
-   requirements. 
-*/
-
-#include "platform.h"
-#include "extractor.h"
-#if HAVE_LIBAVUTIL_AVUTIL_H
-#include <libavutil/avutil.h>
-#elif HAVE_FFMPEG_AVUTIL_H
-#include <ffmpeg/avutil.h>
-#endif
-#if HAVE_LIBAVFORMAT_AVFORMAT_H
-#include <libavformat/avformat.h>
-#elif HAVE_FFMPEG_AVFORMAT_H
-#include <ffmpeg/avformat.h>
-#endif
-#if HAVE_LIBAVCODEC_AVCODEC_H
-#include <libavcodec/avcodec.h>
-#elif HAVE_FFMPEG_AVCODEC_H
-#include <ffmpeg/avcodec.h>
-#endif
-#if HAVE_LIBSWSCALE_SWSCALE_H
-#include <libswscale/swscale.h>
-#elif HAVE_FFMPEG_SWSCALE_H
-#include <ffmpeg/swscale.h>
-#endif
-
-#include "mime_extractor.c" /* TODO: do this cleaner */
-
-#define DEBUG 0
-
-static void thumbnailffmpeg_av_log_callback(void* ptr, 
-                                            int level,
-                                            const char *format,
-                                            va_list ap)
-{
-#if DEBUG
-  vfprintf(stderr, format, ap);
-#endif
-}
-
-void __attribute__ ((constructor)) ffmpeg_lib_init (void)
-{
-  av_log_set_callback (thumbnailffmpeg_av_log_callback);
-  av_register_all ();
-}
-
-#define MAX_THUMB_DIMENSION 128         /* max dimension in pixels */
-#define MAX_THUMB_BYTES (100*1024)
-
-/*
- * Rescale and encode a PNG thumbnail
- * on success, fills in output_data and returns the number of bytes used
- */
-static size_t create_thumbnail(
-  int src_width, int src_height, int src_stride[],
-  enum PixelFormat src_pixfmt, const uint8_t * const src_data[],
-  int dst_width, int dst_height,
-  uint8_t **output_data, size_t output_max_size)
-{
-  AVCodecContext *encoder_codec_ctx = NULL;
-  AVCodec *encoder_codec = NULL;
-  struct SwsContext *scaler_ctx = NULL;
-  int sws_flags = SWS_BILINEAR;
-  AVFrame *dst_frame = NULL;
-  uint8_t *dst_buffer = NULL;
-  uint8_t *encoder_output_buffer = NULL;
-  size_t encoder_output_buffer_size;
-  int err;
-
-  encoder_codec = avcodec_find_encoder_by_name ("png");
-  if (encoder_codec == NULL)
-    {
-#if DEBUG
-      fprintf (stderr,
-              "Couldn't find a PNG encoder\n");
-#endif
-      return 0;
-    }
-
-  /* NOTE: the scaler will be used even if the src and dst image dimensions
-   * match, because the scaler will also perform colour space conversion */
-  scaler_ctx =
-    sws_getContext (src_width, src_height, src_pixfmt,
-                    dst_width, dst_height, PIX_FMT_RGB24, 
-                    sws_flags, NULL, NULL, NULL);
-  if (scaler_ctx == NULL)
-    {
-#if DEBUG
-      fprintf (stderr,
-               "Failed to get a scaler context\n");
-#endif
-      return 0;
-    }
-
-  dst_frame = avcodec_alloc_frame ();
-  if (dst_frame == NULL)
-    {
-#if DEBUG
-      fprintf (stderr,
-               "Failed to allocate the destination image frame\n");
-#endif
-      sws_freeContext(scaler_ctx);
-      return 0;
-    }
-  dst_buffer =
-    av_malloc (avpicture_get_size (PIX_FMT_RGB24, dst_width, dst_height));
-  if (dst_buffer == NULL)
-    {
-#if DEBUG
-      fprintf (stderr,
-               "Failed to allocate the destination image buffer\n");
-#endif
-      av_free (dst_frame);
-      sws_freeContext(scaler_ctx);
-      return 0;
-    }
-  avpicture_fill ((AVPicture *) dst_frame, dst_buffer,
-                  PIX_FMT_RGB24, dst_width, dst_height);
-      
-  sws_scale (scaler_ctx,
-             src_data, 
-             src_stride,
-             0, src_height, 
-             dst_frame->data, 
-             dst_frame->linesize);
-
-  encoder_output_buffer_size = output_max_size;
-  encoder_output_buffer = av_malloc (encoder_output_buffer_size);
-  if (encoder_output_buffer == NULL)
-    {
-#if DEBUG
-      fprintf (stderr,
-               "Failed to allocate the encoder output buffer\n");
-#endif
-      av_free (dst_buffer);
-      av_free (dst_frame);
-      sws_freeContext(scaler_ctx);
-      return 0;
-    }
-
-  encoder_codec_ctx = avcodec_alloc_context ();
-  if (encoder_codec_ctx == NULL)
-    {
-#if DEBUG
-      fprintf (stderr,
-               "Failed to allocate the encoder codec context\n");
-#endif
-      av_free (encoder_output_buffer);
-      av_free (dst_buffer);
-      av_free (dst_frame);
-      sws_freeContext(scaler_ctx);
-      return 0;
-    }
-  encoder_codec_ctx->width = dst_width;
-  encoder_codec_ctx->height = dst_height;
-  encoder_codec_ctx->pix_fmt = PIX_FMT_RGB24;
-
-  if (avcodec_open (encoder_codec_ctx, encoder_codec) < 0)
-    {
-#if DEBUG
-      fprintf (stderr,
-               "Failed to open the encoder\n");
-#endif
-      av_free (encoder_codec_ctx);
-      av_free (encoder_output_buffer);
-      av_free (dst_buffer);
-      av_free (dst_frame);
-      sws_freeContext(scaler_ctx);
-      return 0;
-    }
-
-  err = avcodec_encode_video (encoder_codec_ctx,
-                              encoder_output_buffer,
-                              encoder_output_buffer_size, dst_frame);
-
-  avcodec_close (encoder_codec_ctx);
-  av_free (encoder_codec_ctx);
-  av_free (dst_buffer);
-  av_free (dst_frame);
-  sws_freeContext(scaler_ctx);
-
-  *output_data = encoder_output_buffer;
-
-  return err < 0 ? 0 : err;
-}
-
-struct MIMEToDecoderMapping
-{
- const char *mime_type;
- enum CodecID codec_id;
-};
-
-/* map MIME image types to an ffmpeg decoder */
-static const struct MIMEToDecoderMapping m2d_map[] = {
-  {"image/x-bmp", CODEC_ID_BMP},
-  {"image/gif", CODEC_ID_GIF},
-  {"image/jpeg", CODEC_ID_MJPEG},
-  {"image/png", CODEC_ID_PNG},
-  {"image/x-png", CODEC_ID_PNG},
-  {"image/x-portable-pixmap", CODEC_ID_PPM},
-  {NULL, CODEC_ID_NONE}
-};
-
-static char *mime_type;
-
-static int
-mime_processor (void *cls,
-                        const char *plugin_name,
-                        enum EXTRACTOR_MetaType type,
-                        enum EXTRACTOR_MetaFormat format,
-                        const char *data_mime_type,
-                        const char *data,
-                        size_t data_len)
-{ 
-  switch (format)
-    {
-    case EXTRACTOR_METAFORMAT_UTF8:
-      mime_type = strdup(data);
-      break;
-    default:
-      break;
-    }
-  return 0;
-}
-
-/* calculate the thumbnail dimensions, taking pixel aspect into account */
-static void calculate_thumbnail_dimensions(int src_width,
-                                           int src_height,
-                                           int src_sar_num,
-                                           int src_sar_den,
-                                           int *dst_width,
-                                           int *dst_height)
-{
-  if (src_sar_num <= 0 || src_sar_den <= 0)
-    {
-      src_sar_num = 1;
-      src_sar_den = 1;
-    }
-  if ((src_width * src_sar_num) / src_sar_den > src_height)
-    {
-      *dst_width = MAX_THUMB_DIMENSION;
-      *dst_height = (*dst_width * src_height) /
-                     ((src_width * src_sar_num) / src_sar_den);
-    }
-  else
-    {
-      *dst_height = MAX_THUMB_DIMENSION;
-      *dst_width = (*dst_height *
-                    ((src_width * src_sar_num) / src_sar_den)) /
-                    src_height;
-    }
-  if (*dst_width < 8)
-    *dst_width = 8;
-  if (*dst_height < 1)
-    *dst_height = 1;
-#if DEBUG
-  fprintf (stderr,
-           "Thumbnail dimensions: %d %d\n", 
-           *dst_width, *dst_height);
-#endif
-}
-
-static int 
-extract_image (enum CodecID image_codec_id,
-               const unsigned char *data,
-               size_t size,
-               EXTRACTOR_MetaDataProcessor proc,
-               void *proc_cls,
-               const char *options)
-{
-  AVCodecContext *codec_ctx;
-  AVCodec *codec = NULL;
-  AVFrame *frame = NULL;
-  uint8_t *encoded_thumbnail;
-  int thumb_width;
-  int thumb_height;
-  int err;
-  int frame_finished;
-  int ret = 0;
-
-  codec_ctx = avcodec_alloc_context ();
-  if (codec_ctx == NULL)
-    {
-#if DEBUG
-      fprintf (stderr,
-               "Failed to allocate codec context\n");
-#endif
-      return 0;
-    }
-
-  codec = avcodec_find_decoder (image_codec_id);
-  if (codec != NULL)
-    {
-      if (avcodec_open (codec_ctx, codec) != 0)
-        {
-#if DEBUG
-          fprintf (stderr,
-                   "Failed to open image codec\n");
-#endif
-          av_free (codec_ctx);
-          return 0;
-        }
-    }
-  else
-    {
-#if DEBUG
-      fprintf (stderr,
-               "No suitable codec found\n");
-#endif
-      av_free (codec_ctx);
-      return 0;
-    }
-
-  frame = avcodec_alloc_frame ();
-  if (frame == NULL)
-    {
-#if DEBUG
-      fprintf (stderr,
-               "Failed to allocate frame\n");
-#endif
-      avcodec_close (codec_ctx);
-      av_free (codec_ctx);
-      return 0;
-    }
-
-  avcodec_decode_video (codec_ctx, frame, &frame_finished, data, size);
-
-  if (!frame_finished)
-    {
-      fprintf (stderr,
-              "Failed to decode a complete frame\n");
-      av_free (frame);
-      avcodec_close (codec_ctx);
-      av_free (codec_ctx);
-      return 0;
-    }
-
-  calculate_thumbnail_dimensions (codec_ctx->width, codec_ctx->height,
-                                  codec_ctx->sample_aspect_ratio.num,
-                                  codec_ctx->sample_aspect_ratio.den,
-                                  &thumb_width, &thumb_height);
-
-  err = create_thumbnail (codec_ctx->width, codec_ctx->height,
-                          frame->linesize, codec_ctx->pix_fmt, 
-                         (const uint8_t * const*) frame->data,
-                          thumb_width, thumb_height,
-                          &encoded_thumbnail, MAX_THUMB_BYTES);
-
-  if (err > 0)
-    {
-      ret = proc (proc_cls,
-                  "thumbnailffmpeg",
-                  EXTRACTOR_METATYPE_THUMBNAIL,
-                  EXTRACTOR_METAFORMAT_BINARY,
-                  "image/png",
-                  (const char*) encoded_thumbnail,
-                  err);
-      av_free (encoded_thumbnail);
-    }
-
-  av_free (frame);
-  avcodec_close (codec_ctx);
-  av_free (codec_ctx);
-  return ret;
-}
-
-static int 
-extract_video (const unsigned char *data,
-               size_t size,
-               EXTRACTOR_MetaDataProcessor proc,
-               void *proc_cls,
-               const char *options)
-{
-  AVProbeData pd; 
-  AVPacket packet;
-  AVInputFormat *input_format;
-  int input_format_nofileflag;
-  ByteIOContext *bio_ctx;
-  struct AVFormatContext *format_ctx;
-  AVCodecContext *codec_ctx;
-  AVCodec *codec = NULL;
-  AVFrame *frame = NULL;
-  uint8_t *encoded_thumbnail;
-  int video_stream_index = -1;
-  int thumb_width;
-  int thumb_height;
-  int i;
-  int err;
-  int frame_finished;
-  int ret = 0;
-
-#if DEBUG
-  fprintf (stderr,
-          "ffmpeg starting\n");
-#endif
-  /* probe format
-   * initial try with a smaller probe size for efficiency */
-  pd.filename = "";
-  pd.buf = (void *) data; 
-  pd.buf_size = 128*1024 > size ? size : 128*1024;
-RETRY_PROBE: 
-  if (NULL == (input_format = av_probe_input_format(&pd, 1))) 
-    {
-#if DEBUG
-      fprintf (stderr,
-               "Failed to probe input format\n");
-#endif
-      if (pd.buf_size != size) /* retry probe once with full data size */
-        {
-          pd.buf_size = size;
-          goto RETRY_PROBE;
-        }
-      return 0;
-    }
-  input_format_nofileflag = input_format->flags & AVFMT_NOFILE;
-  input_format->flags |= AVFMT_NOFILE;
-  bio_ctx = NULL; 
-  pd.buf_size = size;
-  url_open_buf(&bio_ctx, pd.buf, pd.buf_size, URL_RDONLY);
-  bio_ctx->is_streamed = 1;  
-  if ((av_open_input_stream(&format_ctx, bio_ctx, pd.filename, input_format, 
NULL)) < 0)
-    {
- #if DEBUG
-      fprintf (stderr,
-               "Failed to open input stream\n");
-#endif
-      url_close_buf (bio_ctx);
-      if (!input_format_nofileflag)
-        input_format->flags ^= AVFMT_NOFILE;
-      return 0;
-    }
-  if (0 > av_find_stream_info (format_ctx))
-    {
- #if DEBUG
-      fprintf (stderr,
-               "Failed to read stream info\n");
-#endif
-      av_close_input_stream (format_ctx);
-      url_close_buf (bio_ctx);
-      if (!input_format_nofileflag)
-        input_format->flags ^= AVFMT_NOFILE;
-      return 0;
-    }
-
-  codec_ctx = NULL;
-  for (i=0; i<format_ctx->nb_streams; i++)
-    {
-      codec_ctx = format_ctx->streams[i]->codec;
-      if (codec_ctx->codec_type != CODEC_TYPE_VIDEO)
-        continue;
-      codec = avcodec_find_decoder (codec_ctx->codec_id);
-      if (codec == NULL)
-        continue;
-      err = avcodec_open (codec_ctx, codec);
-      if (err != 0)
-        {
-          codec = NULL;
-          continue;
-        }
-      video_stream_index = i;
-      break;
-    }
-
-  if ( (video_stream_index == -1) ||
-       (codec_ctx->width == 0) || 
-       (codec_ctx->height == 0) )
-    {
-#if DEBUG
-      fprintf (stderr,
-               "No video streams or no suitable codec found\n");
-#endif
-      if (codec != NULL)
-        avcodec_close (codec_ctx);
-      av_close_input_stream (format_ctx);
-      url_close_buf (bio_ctx);
-      if (!input_format_nofileflag)
-        input_format->flags ^= AVFMT_NOFILE;
-      return 0;
-    }
-
-  frame = avcodec_alloc_frame ();
-  if (frame == NULL)
-    {
-#if DEBUG
-      fprintf (stderr,
-               "Failed to allocate frame\n");
-#endif
-      avcodec_close (codec_ctx);
-      av_close_input_stream (format_ctx);
-      url_close_buf (bio_ctx);
-      if (!input_format_nofileflag)
-        input_format->flags ^= AVFMT_NOFILE;
-      return 0;
-    }
-#if DEBUG
-  if (format_ctx->duration == AV_NOPTS_VALUE)
-    fprintf (stderr,
-            "Duration unknown\n");
-  else
-    fprintf (stderr,
-            "Duration: %lld\n", 
-            format_ctx->duration);      
-#endif
-  /* TODO: if duration is known, seek to some better place,
-   * but use 10 sec into stream for now */
-  err = av_seek_frame (format_ctx, -1, 10 * AV_TIME_BASE, 0);
-  if (err >= 0)        
-    avcodec_flush_buffers (codec_ctx);        
-  frame_finished = 0;
-
-  while (1)
-    {
-      err = av_read_frame (format_ctx, &packet);
-      if (err < 0)
-        break;
-      if (packet.stream_index == video_stream_index)
-        {
-          avcodec_decode_video (codec_ctx,
-                                frame,
-                                &frame_finished,
-                                packet.data, packet.size);
-          if (frame_finished && frame->key_frame)
-            {
-              av_free_packet (&packet);
-              break;
-            }
-        }
-      av_free_packet (&packet);
-    }
-  if (!frame_finished)
-    {
-      fprintf (stderr,
-              "Failed to decode a complete frame\n");
-      av_free (frame);
-      avcodec_close (codec_ctx);
-      av_close_input_stream (format_ctx);
-      url_close_buf (bio_ctx);
-      if (!input_format_nofileflag)
-        input_format->flags ^= AVFMT_NOFILE;
-      return 0;
-    }
-
-  calculate_thumbnail_dimensions (codec_ctx->width, codec_ctx->height,
-                                  codec_ctx->sample_aspect_ratio.num,
-                                  codec_ctx->sample_aspect_ratio.den,
-                                  &thumb_width, &thumb_height);
-
-  err = create_thumbnail (codec_ctx->width, codec_ctx->height,
-                          frame->linesize, codec_ctx->pix_fmt,
-                         (const uint8_t* const *) frame->data,
-                          thumb_width, thumb_height,
-                          &encoded_thumbnail, MAX_THUMB_BYTES);
-
-  if (err > 0)
-    {
-      ret = proc (proc_cls,
-                  "thumbnailffmpeg",
-                  EXTRACTOR_METATYPE_THUMBNAIL,
-                  EXTRACTOR_METAFORMAT_BINARY,
-                  "image/png",
-                  (const char*) encoded_thumbnail,
-                  err);
-      av_free (encoded_thumbnail);
-    }
-
-  av_free (frame);
-  avcodec_close (codec_ctx);
-  av_close_input_stream (format_ctx);
-  url_close_buf (bio_ctx);
-  if (!input_format_nofileflag)
-    input_format->flags ^= AVFMT_NOFILE;
-  return ret;
-}
-
-int 
-EXTRACTOR_thumbnailffmpeg_extract (const unsigned char *data,
-                                  size_t size,
-                                  EXTRACTOR_MetaDataProcessor proc,
-                                  void *proc_cls,
-                                  const char *options)
-{
-  enum CodecID image_codec_id;
-  int is_image = 0;
-  int i;
-
-  mime_type = NULL;
-  EXTRACTOR_mime_extract((const char*) data, size, mime_processor, NULL, NULL);
-  if (mime_type != NULL) 
-    {
-      i = 0;
-      while (m2d_map[i].mime_type != NULL)
-        {
-          if (!strcmp (m2d_map[i].mime_type, mime_type))
-            {
-              is_image = 1;
-              image_codec_id = m2d_map[i].codec_id;
-              break;
-            }
-          i++;
-        }
-      free(mime_type);
-    }
-
-  if (is_image)
-    return extract_image (image_codec_id, data, size, proc, proc_cls, options);
-  else
-    return extract_video (data, size, proc, proc_cls, options);
-}
-
-int 
-EXTRACTOR_thumbnail_extract (const unsigned char *data,
-                            size_t size,
-                            EXTRACTOR_MetaDataProcessor proc,
-                            void *proc_cls,
-                            const char *options)
-{
-  return EXTRACTOR_thumbnailffmpeg_extract (data, size, proc, proc_cls, 
options);
-}
-
-/* end of thumbnailffmpeg_extractor.c */

Added: Extractor/src/plugins/test_thumbnailffmpeg.c
===================================================================
--- Extractor/src/plugins/test_thumbnailffmpeg.c                                
(rev 0)
+++ Extractor/src/plugins/test_thumbnailffmpeg.c        2012-08-16 21:50:39 UTC 
(rev 23265)
@@ -0,0 +1,53 @@
+/*
+     This file is part of libextractor.
+     (C) 2012 Vidyut Samanta and 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/test_thumbnailffmpeg.c
+ * @brief testcase for thumbnailffmpeg plugin
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "test_lib.h"
+
+
+
+/**
+ * Main function for the THUMBNAILFFMPEG testcase.
+ *
+ * @param argc number of arguments (ignored)
+ * @param argv arguments (ignored)
+ * @return 0 on success
+ */
+int
+main (int argc, char *argv[])
+{
+  struct SolutionData thumbnailffmpeg_video_sol[] =
+    {
+      { 0, 0, NULL, NULL, 0, -1 }
+    };
+  struct ProblemSet ps[] =
+    {
+      { "testdata/thumbnailffmpeg_video.mov",
+       thumbnailffmpeg_video_sol },
+      { NULL, NULL }
+    };
+  return ET_main ("thumbnailffmpeg", ps);
+}
+
+/* end of test_thumbnailffmpeg.c */

Added: Extractor/src/plugins/thumbnailffmpeg_extractor.c
===================================================================
--- Extractor/src/plugins/thumbnailffmpeg_extractor.c                           
(rev 0)
+++ Extractor/src/plugins/thumbnailffmpeg_extractor.c   2012-08-16 21:50:39 UTC 
(rev 23265)
@@ -0,0 +1,729 @@
+/*
+     This file is part of libextractor.
+     Copyright (C) 2008, 2012 Heikki Lindholm and 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 thumbnailffmpeg_extractor.c
+ * @author Heikki Lindholm
+ * @author Christian Grothoff
+ * @brief this extractor produces a binary encoded
+ * thumbnail of images and videos using the ffmpeg libs.
+ *
+ * This is a thumbnail extractor using the ffmpeg libraries that will 
eventually
+ * support extracting thumbnails from both image and video files. 
+ *
+ * Note that ffmpeg has a few issues:
+ * (1) there are no recent official releases of the ffmpeg libs
+ * (2) ffmpeg has a history of having security issues (parser is not robust)
+ *
+ *  So this plugin cannot be recommended for system with high security
+ *requirements. 
+ */
+#include "platform.h"
+#include "extractor.h"
+#include <magic.h>
+
+#if HAVE_LIBAVUTIL_AVUTIL_H
+#include <libavutil/avutil.h>
+#elif HAVE_FFMPEG_AVUTIL_H
+#include <ffmpeg/avutil.h>
+#endif
+#if HAVE_LIBAVFORMAT_AVFORMAT_H
+#include <libavformat/avformat.h>
+#elif HAVE_FFMPEG_AVFORMAT_H
+#include <ffmpeg/avformat.h>
+#endif
+#if HAVE_LIBAVCODEC_AVCODEC_H
+#include <libavcodec/avcodec.h>
+#elif HAVE_FFMPEG_AVCODEC_H
+#include <ffmpeg/avcodec.h>
+#endif
+#if HAVE_LIBSWSCALE_SWSCALE_H
+#include <libswscale/swscale.h>
+#elif HAVE_FFMPEG_SWSCALE_H
+#include <ffmpeg/swscale.h>
+#endif
+
+/**
+ * Set to 1 to enable debug output.
+ */ 
+#define DEBUG 1
+
+/**
+ * max dimension in pixels for the thumbnail.
+ */
+#define MAX_THUMB_DIMENSION 128         
+
+/**
+ * Maximum size in bytes for the thumbnail.
+ */
+#define MAX_THUMB_BYTES (100*1024)
+
+/**
+ * Global handle to MAGIC data.
+ */
+static magic_t magic;
+
+
+/**
+ * Read callback.
+ *
+ * @param opaque the 'struct EXTRACTOR_ExtractContext'
+ * @param buf where to write data
+ * @param buf_size how many bytes to read
+ * @return -1 on error (or for unknown file size)
+ */
+static int
+read_cb (void *opaque,
+        uint8_t *buf,
+        int buf_size)
+{
+  struct EXTRACTOR_ExtractContext *ec = opaque;
+  void *data;
+  ssize_t ret;
+
+  ret = ec->read (ec->cls, &data, buf_size);
+  if (ret <= 0)
+    return ret;
+  memcpy (buf, data, ret);
+  return ret;
+}
+
+
+/**
+ * Seek callback.
+ *
+ * @param opaque the 'struct EXTRACTOR_ExtractContext'
+ * @param offset where to seek
+ * @param whence how to seek; AVSEEK_SIZE to return file size without seeking
+ * @return -1 on error (or for unknown file size)
+ */
+static int64_t
+seek_cb (void *opaque,
+        int64_t offset,
+        int whence)
+{
+  struct EXTRACTOR_ExtractContext *ec = opaque;
+
+  if (AVSEEK_SIZE == whence)
+    return ec->get_size (ec->cls);
+  return ec->seek (ec->cls, offset, whence);
+}
+
+
+/**
+ * Rescale and encode a PNG thumbnail.
+ *
+ * @param src_width source image width
+ * @param src_height source image height
+ * @param src_stride 
+ * @param src_pixfmt
+ * @param src_data source data
+ * @param dst_width desired thumbnail width
+ * @param dst_height desired thumbnail height
+ * @param output_data where to store the resulting PNG data
+ * @param output_max_size maximum size of result that is allowed
+ * @return the number of bytes used, 0 on error
+ */
+static size_t 
+create_thumbnail (int src_width, int src_height, 
+                 int src_stride[],
+                 enum PixelFormat src_pixfmt, 
+                 const uint8_t * const src_data[],
+                 int dst_width, int dst_height,
+                 uint8_t **output_data, 
+                 size_t output_max_size)
+{
+  AVCodecContext *encoder_codec_ctx;
+  AVDictionary *opts;
+  AVCodec *encoder_codec;
+  struct SwsContext *scaler_ctx;
+  AVFrame *dst_frame;
+  uint8_t *dst_buffer;
+  uint8_t *encoder_output_buffer;
+  size_t encoder_output_buffer_size;
+  int err;
+
+  if (NULL == (encoder_codec = avcodec_find_encoder_by_name ("png")))
+    {
+#if DEBUG
+      fprintf (stderr,
+              "Couldn't find a PNG encoder\n");
+#endif
+      return 0;
+    }
+
+  /* NOTE: the scaler will be used even if the src and dst image dimensions
+   * match, because the scaler will also perform colour space conversion */
+  if (NULL == 
+      (scaler_ctx =
+       sws_getContext (src_width, src_height, src_pixfmt,
+                      dst_width, dst_height, PIX_FMT_RGB24, 
+                      SWS_BILINEAR, NULL, NULL, NULL)))
+    {
+#if DEBUG
+      fprintf (stderr,
+               "Failed to get a scaler context\n");
+#endif
+      return 0;
+    }
+
+  if (NULL == (dst_frame = avcodec_alloc_frame ()))
+    {
+#if DEBUG
+      fprintf (stderr,
+               "Failed to allocate the destination image frame\n");
+#endif
+      sws_freeContext (scaler_ctx);
+      return 0;
+    }
+  if (NULL == (dst_buffer =
+              av_malloc (avpicture_get_size (PIX_FMT_RGB24, dst_width, 
dst_height))))
+    {
+#if DEBUG
+      fprintf (stderr,
+               "Failed to allocate the destination image buffer\n");
+#endif
+      av_free (dst_frame);
+      sws_freeContext (scaler_ctx);
+      return 0;
+    }
+  avpicture_fill ((AVPicture *) dst_frame, dst_buffer,
+                  PIX_FMT_RGB24, dst_width, dst_height);
+  sws_scale (scaler_ctx,
+             src_data, 
+             src_stride,
+             0, src_height, 
+             dst_frame->data, 
+             dst_frame->linesize);
+
+  encoder_output_buffer_size = output_max_size;
+  if (NULL == (encoder_output_buffer = av_malloc (encoder_output_buffer_size)))
+    {
+#if DEBUG
+      fprintf (stderr,
+               "Failed to allocate the encoder output buffer\n");
+#endif
+      av_free (dst_buffer);
+      av_free (dst_frame);
+      sws_freeContext (scaler_ctx);
+      return 0;
+    }
+
+  if (NULL == (encoder_codec_ctx = avcodec_alloc_context3 (encoder_codec)))
+    {
+#if DEBUG
+      fprintf (stderr,
+               "Failed to allocate the encoder codec context\n");
+#endif
+      av_free (encoder_output_buffer);
+      av_free (dst_buffer);
+      av_free (dst_frame);
+      sws_freeContext (scaler_ctx);
+      return 0;
+    }
+  encoder_codec_ctx->width = dst_width;
+  encoder_codec_ctx->height = dst_height;
+  encoder_codec_ctx->pix_fmt = PIX_FMT_RGB24;
+  opts = NULL;
+  if (avcodec_open2 (encoder_codec_ctx, encoder_codec, &opts) < 0)
+    {
+#if DEBUG
+      fprintf (stderr,
+               "Failed to open the encoder\n");
+#endif
+      av_free (encoder_codec_ctx);
+      av_free (encoder_output_buffer);
+      av_free (dst_buffer);
+      av_free (dst_frame);
+      sws_freeContext  (scaler_ctx);
+      return 0;
+    }
+  err = avcodec_encode_video (encoder_codec_ctx,
+                              encoder_output_buffer,
+                              encoder_output_buffer_size, dst_frame);
+  av_dict_free (&opts);
+  avcodec_close (encoder_codec_ctx);
+  av_free (encoder_codec_ctx);
+  av_free (dst_buffer);
+  av_free (dst_frame);
+  sws_freeContext (scaler_ctx);
+  *output_data = encoder_output_buffer;
+
+  return err < 0 ? 0 : err;
+}
+
+
+
+/**
+ * calculate the thumbnail dimensions, taking pixel aspect into account 
+ *
+ * @param src_width source image width
+ * @param src_height source image height
+ * @param src_sar_num
+ * @param src_sar_den
+ * @param dst_width desired thumbnail width (set)
+ * @param dst_height desired thumbnail height (set)
+  */
+static void 
+calculate_thumbnail_dimensions (int src_width,
+                               int src_height,
+                               int src_sar_num,
+                               int src_sar_den,
+                               int *dst_width,
+                               int *dst_height)
+{
+  if ( (src_sar_num <= 0) || (src_sar_den <= 0) )
+    {
+      src_sar_num = 1;
+      src_sar_den = 1;
+    }
+  if ((src_width * src_sar_num) / src_sar_den > src_height)
+    {
+      *dst_width = MAX_THUMB_DIMENSION;
+      *dst_height = (*dst_width * src_height) /
+                     ((src_width * src_sar_num) / src_sar_den);
+    }
+  else
+    {
+      *dst_height = MAX_THUMB_DIMENSION;
+      *dst_width = (*dst_height *
+                    ((src_width * src_sar_num) / src_sar_den)) /
+                    src_height;
+    }
+  if (*dst_width < 8)
+    *dst_width = 8;
+  if (*dst_height < 1)
+    *dst_height = 1;
+#if DEBUG
+  fprintf (stderr,
+           "Thumbnail dimensions: %d %d\n", 
+           *dst_width, *dst_height);
+#endif
+}
+
+
+/**
+ * Perform thumbnailing when the input is an image.
+ *
+ * @param image_codec_id ffmpeg codec for the image format
+ * @param ec extraction context to use
+ */
+static void
+extract_image (enum CodecID image_codec_id,
+               struct EXTRACTOR_ExtractContext *ec)
+{
+  AVDictionary *opts;
+  AVCodecContext *codec_ctx;
+  AVCodec *codec;
+  AVPacket avpkt;
+  AVFrame *frame;
+  uint8_t *encoded_thumbnail;
+  int thumb_width;
+  int thumb_height;
+  int err;
+  int frame_finished;
+  ssize_t iret;
+  void *data;
+
+  if (NULL == (codec = avcodec_find_decoder (image_codec_id)))
+    {
+#if DEBUG
+      fprintf (stderr,
+               "No suitable codec found\n");
+#endif
+      return;
+    }
+  if (NULL == (codec_ctx = avcodec_alloc_context3 (codec)))
+    {
+#if DEBUG
+      fprintf (stderr,
+               "Failed to allocate codec context\n");
+#endif
+      return;
+    }
+  opts = NULL;
+  if (0 != avcodec_open2 (codec_ctx, codec, &opts))
+    {
+#if DEBUG
+      fprintf (stderr,
+              "Failed to open image codec\n");
+#endif
+      av_free (codec_ctx);
+      return;
+    }
+  av_dict_free (&opts);
+  if (NULL == (frame = avcodec_alloc_frame ()))
+    {
+#if DEBUG
+      fprintf (stderr,
+               "Failed to allocate frame\n");
+#endif
+      avcodec_close (codec_ctx);
+      av_free (codec_ctx);
+      return;
+    }
+
+  frame_finished = 0;
+  while (! frame_finished)
+    {
+      if (0 >= (iret = ec->read (ec->cls,
+                                &data,
+                                32 * 1024)))
+       break;      
+      av_init_packet (&avpkt);
+      avpkt.data = data;
+      avpkt.size = iret;
+      avcodec_decode_video2 (codec_ctx, frame, &frame_finished, &avpkt);
+    }
+  if (! frame_finished)
+    {
+#if DEBUG
+      fprintf (stderr,
+              "Failed to decode a complete frame\n");
+#endif
+      av_free (frame);
+      avcodec_close (codec_ctx);
+      av_free (codec_ctx);
+      return;
+    }
+  calculate_thumbnail_dimensions (codec_ctx->width, codec_ctx->height,
+                                  codec_ctx->sample_aspect_ratio.num,
+                                  codec_ctx->sample_aspect_ratio.den,
+                                  &thumb_width, &thumb_height);
+
+  err = create_thumbnail (codec_ctx->width, codec_ctx->height,
+                          frame->linesize, codec_ctx->pix_fmt, 
+                         (const uint8_t * const*) frame->data,
+                          thumb_width, thumb_height,
+                          &encoded_thumbnail, MAX_THUMB_BYTES);
+  if (err > 0)
+    {
+      ec->proc (ec->cls,
+               "thumbnailffmpeg",
+               EXTRACTOR_METATYPE_THUMBNAIL,
+               EXTRACTOR_METAFORMAT_BINARY,
+               "image/png",
+               (const char*) encoded_thumbnail,
+               err);
+      av_free (encoded_thumbnail);
+    }
+  av_free (frame);
+  avcodec_close (codec_ctx);
+  av_free (codec_ctx);
+}
+
+
+/**
+ * Perform thumbnailing when the input is a video
+ *
+ * @param ec extraction context to use
+ */
+static void
+extract_video (struct EXTRACTOR_ExtractContext *ec)
+{
+  AVPacket packet;
+  AVIOContext *io_ctx;
+  struct AVFormatContext *format_ctx;
+  AVCodecContext *codec_ctx;
+  AVCodec *codec;
+  AVDictionary *options;
+  AVFrame *frame;
+  uint8_t *encoded_thumbnail;
+  int video_stream_index;
+  int thumb_width;
+  int thumb_height;
+  int i;
+  int err;
+  int frame_finished;
+  unsigned char *iob;
+
+  if (NULL == (iob = av_malloc (16 * 1024)))
+    return;
+  if (NULL == (io_ctx = avio_alloc_context (iob, 16 * 1024,
+                                           0, ec, 
+                                           &read_cb,
+                                           NULL /* no writing */,
+                                           &seek_cb)))
+    {
+      av_free (iob);
+      return;
+    }
+  if (NULL == (format_ctx = avformat_alloc_context ()))
+    {
+      av_free (io_ctx);
+      return;
+    }
+  format_ctx->pb = io_ctx;
+  options = NULL;
+  if (0 != avformat_open_input (&format_ctx, "<no file>", NULL, &options))
+    return;
+  av_dict_free (&options);  
+  options = NULL;
+  if (0 > avformat_find_stream_info (format_ctx, &options))
+    {
+ #if DEBUG
+      fprintf (stderr,
+               "Failed to read stream info\n");
+#endif
+      avformat_close_input (&format_ctx);
+      return;
+    }
+  av_dict_free (&options);  
+
+  codec = NULL;
+  codec_ctx = NULL;
+  video_stream_index = -1;
+  for (i=0; i<format_ctx->nb_streams; i++)
+    {
+      codec_ctx = format_ctx->streams[i]->codec;
+      if (AVMEDIA_TYPE_VIDEO != codec_ctx->codec_type)
+        continue;
+      if (NULL == (codec = avcodec_find_decoder (codec_ctx->codec_id)))
+        continue;
+      options = NULL;
+      if (0 != (err = avcodec_open2 (codec_ctx, codec, &options)))
+        {
+          codec = NULL;
+          continue;
+        }
+      av_dict_free (&options); 
+      video_stream_index = i;
+      break;
+    }
+  if ( (-1 == video_stream_index) ||
+       (0 == codec_ctx->width) || 
+       (0 == codec_ctx->height) )
+    {
+#if DEBUG
+      fprintf (stderr,
+               "No video streams or no suitable codec found\n");
+#endif
+      if (NULL != codec)
+        avcodec_close (codec_ctx);
+      avformat_close_input (&format_ctx);
+      return;
+    }
+
+  if (NULL == (frame = avcodec_alloc_frame ()))
+    {
+#if DEBUG
+      fprintf (stderr,
+               "Failed to allocate frame\n");
+#endif
+      avcodec_close (codec_ctx);
+      avformat_close_input (&format_ctx);
+      return;
+    }
+#if DEBUG
+  if (format_ctx->duration == AV_NOPTS_VALUE)
+    fprintf (stderr,
+            "Duration unknown\n");
+  else
+    fprintf (stderr,
+            "Duration: %lld\n", 
+            format_ctx->duration);      
+#endif
+  /* TODO: if duration is known, seek to some better place,
+   * but use 10 sec into stream for now */
+  err = av_seek_frame (format_ctx, -1, 10 * AV_TIME_BASE, 0);
+  if (err >= 0)        
+    avcodec_flush_buffers (codec_ctx);        
+  frame_finished = 0;
+
+  while (1)
+    {
+      err = av_read_frame (format_ctx, &packet);
+      if (err < 0)
+        break;
+      if (packet.stream_index == video_stream_index)
+        {
+          avcodec_decode_video2 (codec_ctx,
+                                frame,
+                                &frame_finished,
+                                &packet);
+          if (frame_finished && frame->key_frame)
+            {
+              av_free_packet (&packet);
+              break;
+            }
+        }
+      av_free_packet (&packet);
+    }
+
+  if (! frame_finished)
+    {
+      fprintf (stderr,
+              "Failed to decode a complete frame\n");
+      av_free (frame);
+      avcodec_close (codec_ctx);
+      avformat_close_input (&format_ctx);
+      return;
+    }
+  calculate_thumbnail_dimensions (codec_ctx->width, codec_ctx->height,
+                                  codec_ctx->sample_aspect_ratio.num,
+                                  codec_ctx->sample_aspect_ratio.den,
+                                  &thumb_width, &thumb_height);
+  err = create_thumbnail (codec_ctx->width, codec_ctx->height,
+                          frame->linesize, codec_ctx->pix_fmt,
+                         (const uint8_t* const *) frame->data,
+                          thumb_width, thumb_height,
+                          &encoded_thumbnail, MAX_THUMB_BYTES);
+  if (err > 0)
+    {
+      ec->proc (ec->cls,
+               "thumbnailffmpeg",
+               EXTRACTOR_METATYPE_THUMBNAIL,
+               EXTRACTOR_METAFORMAT_BINARY,
+               "image/png",
+               (const char*) encoded_thumbnail,
+               err);
+      av_free (encoded_thumbnail);
+    }
+  av_free (frame);
+  avcodec_close (codec_ctx);
+  avformat_close_input (&format_ctx);
+}
+
+
+/**
+ * Pair of mime type and ffmpeg decoder ID.
+ */
+struct MIMEToDecoderMapping
+{
+  /**
+   * String for a mime type.
+   */
+  const char *mime_type;
+
+  /**
+   * Corresponding ffmpeg decoder ID.
+   */
+  enum CodecID codec_id;
+};
+
+
+/**
+ * map MIME image types to an ffmpeg decoder 
+ */
+static const struct MIMEToDecoderMapping m2d_map[] = 
+  {
+    { "image/x-bmp", CODEC_ID_BMP },
+    { "image/gif", CODEC_ID_GIF },
+    { "image/jpeg", CODEC_ID_MJPEG },
+    { "image/png", CODEC_ID_PNG },
+    { "image/x-png", CODEC_ID_PNG },
+    { "image/x-portable-pixmap", CODEC_ID_PPM },
+    { NULL, CODEC_ID_NONE }
+  };
+
+
+/**
+ * Main method for the ffmpeg-thumbnailer plugin.
+ *
+ * @param ec extraction context
+ */
+void 
+EXTRACTOR_thumbnailffmpeg_extract_method (struct EXTRACTOR_ExtractContext *ec)
+{
+  unsigned int i;
+  ssize_t iret;
+  void *data;
+  const char *mime;
+
+  if (-1 == (iret = ec->read (ec->cls,
+                             &data,
+                             16 * 1024)))
+    return;
+  if (NULL == (mime = magic_buffer (magic, data, iret)))
+    return;
+  if (0 != ec->seek (ec->cls, 0, SEEK_SET))
+    return;
+  for (i = 0; NULL != m2d_map[i].mime_type; i++)
+    if (0 == strcmp (m2d_map[i].mime_type, mime))
+      {
+       extract_image (m2d_map[i].codec_id, ec);
+       return;
+      }
+  extract_video (ec);
+}
+
+
+/**
+ * This plugin sometimes is installed under the alias 'thumbnail'.
+ * So we need to provide a second entry method.
+ *
+ * @param ec extraction context
+ */
+void 
+EXTRACTOR_thumbnail_extract_method (struct EXTRACTOR_ExtractContext *ec)
+{
+  EXTRACTOR_thumbnailffmpeg_extract_method (ec);
+}
+
+
+/**
+ * Log callback.  Does nothing.
+ *
+ * @param ptr NULL
+ * @param level log level
+ * @param format format string
+ * @param ap arguments for format
+ */
+static void 
+thumbnailffmpeg_av_log_callback (void* ptr, 
+                                int level,
+                                const char *format,
+                                va_list ap)
+{
+#if DEBUG
+  vfprintf(stderr, format, ap);
+#endif
+}
+
+
+/**
+ * Initialize av-libs and load magic file.
+ */
+void __attribute__ ((constructor)) 
+thumbnailffmpeg_lib_init (void)
+{
+  av_log_set_callback (&thumbnailffmpeg_av_log_callback);
+  av_register_all ();
+  magic = magic_open (MAGIC_MIME_TYPE);
+  if (0 != magic_load (magic, NULL))
+    {
+      /* FIXME: how to deal with errors? */
+    }
+}
+
+/**
+ * Destructor for the library, cleans up.
+ */
+void __attribute__ ((destructor)) 
+thumbnailffmpeg_ltdl_fini () 
+{
+  if (NULL != magic)
+    {
+      magic_close (magic);
+      magic = NULL;
+    }
+}
+
+
+/* end of thumbnailffmpeg_extractor.c */

Modified: Extractor/src/plugins/thumbnailgtk_extractor.c
===================================================================
--- Extractor/src/plugins/thumbnailgtk_extractor.c      2012-08-16 17:03:29 UTC 
(rev 23264)
+++ Extractor/src/plugins/thumbnailgtk_extractor.c      2012-08-16 21:50:39 UTC 
(rev 23265)
@@ -52,7 +52,7 @@
 
 
 /**
- * Main method for the thumbnailer plugin.
+ * Main method for the gtk-thumbnailer plugin.
  *
  * @param ec extraction context
  */
@@ -209,7 +209,7 @@
  * Initialize glib and load magic file.
  */
 void __attribute__ ((constructor)) 
-ole_gobject_init ()
+thumbnailgtk_gobject_init ()
 {
   g_type_init ();
   magic = magic_open (MAGIC_MIME_TYPE);
@@ -224,7 +224,7 @@
  * Destructor for the library, cleans up.
  */
 void __attribute__ ((destructor)) 
-mime_ltdl_fini () 
+thumbnailgtk_ltdl_fini () 
 {
   if (NULL != magic)
     {




reply via email to

[Prev in Thread] Current Thread [Next in Thread]