[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r9826 - in Extractor: . src/include src/main src/plugins
From: |
gnunet |
Subject: |
[GNUnet-SVN] r9826 - in Extractor: . src/include src/main src/plugins |
Date: |
Sun, 20 Dec 2009 20:55:40 +0100 |
Author: grothoff
Date: 2009-12-20 20:55:40 +0100 (Sun, 20 Dec 2009)
New Revision: 9826
Modified:
Extractor/TODO
Extractor/configure.ac
Extractor/src/include/extractor.h
Extractor/src/main/extract.c
Extractor/src/main/extractor.c
Extractor/src/plugins/Makefile.am
Extractor/src/plugins/mime_extractor.c
Extractor/src/plugins/thumbnailffmpeg_extractor.c
Log:
ffmpeg and related fixes
Modified: Extractor/TODO
===================================================================
--- Extractor/TODO 2009-12-20 15:27:04 UTC (rev 9825)
+++ Extractor/TODO 2009-12-20 19:55:40 UTC (rev 9826)
@@ -10,6 +10,11 @@
* use "-" in config not to append plugin, but to remove one!
* document
* port test cases
+* document special options; we have:
+ - force-kill: plugin process committs suicide after each file
+ - oop-only: plugin is never run in-process
+ - close-stdout: stdout is closed for the (external) plugin process
+ - close-stderr: stderr is closed for the (external) plugin process
'Unclean' code:
* ASF
Modified: Extractor/configure.ac
===================================================================
--- Extractor/configure.ac 2009-12-20 15:27:04 UTC (rev 9825)
+++ Extractor/configure.ac 2009-12-20 19:55:40 UTC (rev 9826)
@@ -505,7 +505,7 @@
if test "x$gn_cv_export_symbols_regex_works" = "xyes"
then
LE_LIB_LDFLAGS="$LE_LIB_LDFLAGS -export-symbols-regex
\"EXTRACTOR_@<:@a-zA-Z0-9_@:>@*\""
- LE_PLUGIN_LDFLAGS="$LE_PLUGIN_LDFLAGS -export-symbols-regex
\"EXTRACTOR_@<:@a-zA-Z0-9_@:>@*_extract\""
+ LE_PLUGIN_LDFLAGS="$LE_PLUGIN_LDFLAGS -export-symbols-regex
\"EXTRACTOR_@<:@a-zA-Z0-9_@:>@*_.......\""
fi
AC_SUBST(LE_LIB_LDFLAGS)
AC_SUBST(LE_PLUGIN_LDFLAGS)
Modified: Extractor/src/include/extractor.h
===================================================================
--- Extractor/src/include/extractor.h 2009-12-20 15:27:04 UTC (rev 9825)
+++ Extractor/src/include/extractor.h 2009-12-20 19:55:40 UTC (rev 9826)
@@ -42,26 +42,32 @@
*/
enum EXTRACTOR_Options
{
+
/**
- * Run plugins in-process.
+ * Run plugin out-of-process, starting the process once the plugin
+ * is to be run. If a plugin crashes, automatically restart the
+ * respective process for the same file and try once more
+ * (since the crash may be caused by the previous file). If
+ * the process crashes immediately again, it is not restarted
+ * until the next file.
*/
- EXTRACTOR_OPTION_NONE = 0,
+ EXTRACTOR_OPTION_DEFAULT_POLICY = 0,
/**
* Run plugins out-of-process, starting the process
* once at the time the plugin is loaded. This will
* prevent the main process crashing if a plugin dies.
* Ignored on platforms where out-of-process starts
- * are not supported.
+ * are not supported (in-process execution will be
+ * attempted, unless the plugin itself forbids it).
*/
- EXTRACTOR_OPTION_OUT_OF_PROCESS = 1,
+ EXTRACTOR_OPTION_OUT_OF_PROCESS_NO_RESTART = 1,
/**
- * If a plugin crashes, automatically restart the respective
- * process for the next file. Implies
- * EXTRACTOR_OPTION_OUT_OF_PROCESS.
+ * Run plugins in-process. Unsafe, not recommended,
+ * can be nice for debugging.
*/
- EXTRACTOR_OPTION_AUTO_RESTART = 2,
+ EXTRACTOR_OPTION_IN_PROCESS = 2,
/**
* Internal value for plugins that have been disabled.
@@ -478,24 +484,7 @@
const char *options,
enum EXTRACTOR_Options flags);
-
/**
- * Add a library for keyword extraction at the END of the list.
- * @param prev the previous list of libraries, may be NULL
- * @param library the name of the library (full path)
- * @param options options to give to the library
- * @param flags options to use
- * @return the new list of libraries, always equal to prev
- * except if prev was NULL and no error occurs
- */
-struct EXTRACTOR_PluginList *
-EXTRACTOR_plugin_add_last(struct EXTRACTOR_PluginList *prev,
- const char *library,
- const char *options,
- enum EXTRACTOR_Options flags);
-
-
-/**
* Load multiple libraries as specified by the user.
*
* @param config a string given by the user that defines which
@@ -503,8 +492,8 @@
* "[[-]LIBRARYNAME[(options)][:[-]LIBRARYNAME[(options)]]]*".
* For example, 'mp3:ogg' loads the
* mp3 and the ogg plugins. The '-' before the LIBRARYNAME
- * indicates that the library should be added to the end
- * of the library list (addLibraryLast).
+ * indicates that the library should be removed from
+ * the library list.
* @param prev the previous list of libraries, may be NULL
* @param flags options to use
* @return the new list of libraries, equal to prev iff an error occured
Modified: Extractor/src/main/extract.c
===================================================================
--- Extractor/src/main/extract.c 2009-12-20 15:27:04 UTC (rev 9825)
+++ Extractor/src/main/extract.c 2009-12-20 19:55:40 UTC (rev 9826)
@@ -170,8 +170,6 @@
static Help help[] = {
{ 'b', "bibtex", NULL,
gettext_noop("print output in bibtex format") },
- { 'B', "binary", "LANG",
- gettext_noop("use the generic plaintext extractor for the language with
the 2-letter language code LANG") },
{ 'g', "grep-friendly", NULL,
gettext_noop("produce grep-friendly output (all results on one line per
file)") },
{ 'h', "help", NULL,
@@ -557,7 +555,6 @@
int defaultAll = YES;
int bibtex = NO;
int grepfriendly = NO;
- char * binary = NULL;
char * name;
int ret = 0;
EXTRACTOR_MetaDataProcessor processor = NULL;
@@ -574,7 +571,6 @@
while (1)
{
static struct option long_options[] = {
- {"binary", 1, 0, 'B'},
{"bibtex", 0, 0, 'b'},
{"grep-friendly", 0, 0, 'g'},
{"help", 0, 0, 'h'},
@@ -610,9 +606,6 @@
}
processor = &print_bibtex;
break;
- case 'B':
- binary = optarg;
- break;
case 'g':
grepfriendly = YES;
if (processor != NULL)
@@ -729,40 +722,27 @@
/* build list of libraries */
if (nodefault == NO)
plugins = EXTRACTOR_plugin_add_defaults (in_process
- ? EXTRACTOR_OPTION_NONE
- : EXTRACTOR_OPTION_AUTO_RESTART);
+ ? EXTRACTOR_OPTION_IN_PROCESS
+ : EXTRACTOR_OPTION_DEFAULT_POLICY);
else
plugins = NULL;
if (libraries != NULL)
plugins = EXTRACTOR_plugin_add_config (plugins,
libraries,
in_process
- ? EXTRACTOR_OPTION_NONE
- : EXTRACTOR_OPTION_AUTO_RESTART);
- if (binary != NULL)
- {
- name = malloc(strlen(binary) + strlen("printable_") + 1);
- strcpy(name, "libextractor_printable_");
- strcat(name, binary);
- plugins = EXTRACTOR_plugin_add_last(plugins,
- name,
- NULL,
- in_process
- ? EXTRACTOR_OPTION_NONE
- : EXTRACTOR_OPTION_AUTO_RESTART);
- free(name);
- }
+ ? EXTRACTOR_OPTION_IN_PROCESS
+ : EXTRACTOR_OPTION_DEFAULT_POLICY);
if (hash != NULL)
{
name = malloc(strlen(hash) + strlen("hash_") + 1);
strcpy(name, "libextractor_hash_");
strcat(name, hash);
- plugins = EXTRACTOR_plugin_add_last(plugins,
- name,
- NULL,
- in_process
- ? EXTRACTOR_OPTION_NONE
- : EXTRACTOR_OPTION_AUTO_RESTART);
+ plugins = EXTRACTOR_plugin_add(plugins,
+ name,
+ NULL,
+ in_process
+ ? EXTRACTOR_OPTION_IN_PROCESS
+ : EXTRACTOR_OPTION_DEFAULT_POLICY);
free(name);
}
Modified: Extractor/src/main/extractor.c
===================================================================
--- Extractor/src/main/extractor.c 2009-12-20 15:27:04 UTC (rev 9825)
+++ Extractor/src/main/extractor.c 2009-12-20 19:55:40 UTC (rev 9826)
@@ -105,6 +105,13 @@
char * plugin_options;
/**
+ * Special options for the plugin
+ * (as returned by the plugin's "options" method;
+ * typically NULL).
+ */
+ const char *specials;
+
+ /**
* Flags to control how the plugin is executed.
*/
enum EXTRACTOR_Options flags;
@@ -587,18 +594,22 @@
* @param lib_handle library to search for the symbol
* @param prefix prefix to add
* @param sym_name base name for the symbol
+ * @param options set to special options requested by the plugin
* @return NULL on error, otherwise pointer to the symbol
*/
static void *
get_symbol_with_prefix(void *lib_handle,
- const char *prefix)
+ const char *prefix,
+ const char **options)
{
char *name;
void *symbol;
const char *sym_name;
char *sym;
char *dot;
+ const char *(*opt_fun)(void);
+ *options = NULL;
sym_name = strstr (prefix, "_");
if (sym_name == NULL)
return NULL;
@@ -611,7 +622,6 @@
sprintf(name,
"_EXTRACTOR_%s_extract",
sym);
- free (sym);
/* try without '_' first */
symbol = lt_dlsym(lib_handle, name + 1);
if (symbol==NULL)
@@ -636,7 +646,23 @@
free(first_error);
#endif
}
+
+ if (symbol != NULL)
+ {
+ /* get special options */
+ sprintf(name,
+ "_EXTRACTOR_%s_options",
+ sym);
+ /* try without '_' first */
+ opt_fun = lt_dlsym(lib_handle, name + 1);
+ if (opt_fun == NULL)
+ opt_fun = lt_dlsym(lib_handle, name);
+ if (opt_fun != NULL)
+ *options = opt_fun ();
+ }
+ free (sym);
free(name);
+
return symbol;
}
@@ -652,8 +678,9 @@
{
lt_dladvise advise;
- plugin->libname = find_plugin (plugin->short_libname);
if (plugin->libname == NULL)
+ plugin->libname = find_plugin (plugin->short_libname);
+ if (plugin->libname == NULL)
{
#if DEBUG
fprintf (stderr,
@@ -683,7 +710,8 @@
return -1;
}
plugin->extractMethod = get_symbol_with_prefix (plugin->libraryHandle,
- plugin->libname);
+ plugin->libname,
+ &plugin->specials);
if (plugin->extractMethod == NULL)
{
#if DEBUG
@@ -738,47 +766,6 @@
/**
- * Add a library for keyword extraction at the END of the list.
- * @param prev the previous list of libraries, may be NULL
- * @param library the name of the library
- * @param options options to give to the library
- * @param flags options to use
- * @return the new list of libraries, always equal to prev
- * except if prev was NULL and no error occurs
- */
-struct EXTRACTOR_PluginList *
-EXTRACTOR_plugin_add_last(struct EXTRACTOR_PluginList *prev,
- const char *library,
- const char *options,
- enum EXTRACTOR_Options flags)
-{
- struct EXTRACTOR_PluginList *result;
- struct EXTRACTOR_PluginList *pos;
- char *libname;
-
- libname = find_plugin (library);
- if (libname == NULL)
- return prev;
- result = calloc (1, sizeof (struct EXTRACTOR_PluginList));
- result->next = prev;
- result->short_libname = strdup (library);
- result->libname = libname;
- result->flags = flags;
- if( options )
- result->plugin_options = strdup (options);
- else
- result->plugin_options = NULL;
- if (prev == NULL)
- return result;
- pos = prev;
- while (pos->next != NULL)
- pos = pos->next;
- pos->next = result;
- return prev;
-}
-
-
-/**
* Load multiple libraries as specified by the user.
*
* @param config a string given by the user that defines which
@@ -786,8 +773,8 @@
* "[[-]LIBRARYNAME[(options)][:[-]LIBRARYNAME[(options)]]]*".
* For example, 'mp3:ogg.so' loads the
* mp3 and the ogg library. The '-' before the LIBRARYNAME
- * indicates that the library should be added to the end
- * of the library list (addLibraryLast).
+ * indicates that the library should be removed from
+ * the library list.
* @param prev the previous list of libraries, may be NULL
* @param flags options to use
* @return the new list of libraries, equal to prev iff an error occured
@@ -836,10 +823,8 @@
if (cpy[last] == '-')
{
last++;
- prev = EXTRACTOR_plugin_add_last (prev,
- &cpy[last],
- (lastconf != -1) ? &cpy[lastconf] :
NULL,
- flags);
+ prev = EXTRACTOR_plugin_remove (prev,
+ &cpy[last]);
}
else
{
@@ -1049,8 +1034,6 @@
}
-
-
/**
* 'main' function of the child process.
* Reads shm-filenames from 'in' (line-by-line) and
@@ -1084,6 +1067,19 @@
#endif
return;
}
+ if ( (plugin->specials != NULL) &&
+ (NULL != strstr (plugin->specials,
+ "close-stderr")) )
+ {
+ close (2);
+ }
+ if ( (plugin->specials != NULL) &&
+ (NULL != strstr (plugin->specials,
+ "close-stdout")) )
+ {
+ close (1);
+ }
+
memset (&hdr, 0, sizeof (hdr));
fin = fdopen (in, "r");
while (NULL != fgets (fn, sizeof(fn), fin))
@@ -1109,6 +1105,14 @@
munmap (ptr, size);
if (-1 != shmid)
close (shmid);
+ if ( (plugin->specials != NULL) &&
+ (NULL != strstr (plugin->specials,
+ "force-kill")) )
+ {
+ /* we're required to die after each file since this
+ plugin only supports a single file at a time */
+ _exit (0);
+ }
}
fclose (fin);
close (out);
@@ -1195,7 +1199,7 @@
{
stop_process (plugin);
plugin->cpid = -1;
- if (plugin->flags != EXTRACTOR_OPTION_AUTO_RESTART)
+ if (plugin->flags != EXTRACTOR_OPTION_DEFAULT_POLICY)
plugin->flags = EXTRACTOR_OPTION_DISABLED;
return 0;
}
@@ -1208,7 +1212,7 @@
{
stop_process (plugin);
plugin->cpid = -1;
- if (plugin->flags != EXTRACTOR_OPTION_AUTO_RESTART)
+ if (plugin->flags != EXTRACTOR_OPTION_DEFAULT_POLICY)
plugin->flags = EXTRACTOR_OPTION_DISABLED;
return 0;
}
@@ -1221,7 +1225,7 @@
{
stop_process (plugin);
plugin->cpid = -1;
- if (plugin->flags != EXTRACTOR_OPTION_AUTO_RESTART)
+ if (plugin->flags != EXTRACTOR_OPTION_DEFAULT_POLICY)
plugin->flags = EXTRACTOR_OPTION_DISABLED;
return 0;
}
@@ -1241,7 +1245,7 @@
stop_process (plugin);
plugin->cpid = -1;
free (data);
- if (plugin->flags != EXTRACTOR_OPTION_AUTO_RESTART)
+ if (plugin->flags != EXTRACTOR_OPTION_DEFAULT_POLICY)
plugin->flags = EXTRACTOR_OPTION_DISABLED;
return 0;
}
@@ -1294,19 +1298,19 @@
{
switch (ppos->flags)
{
- case EXTRACTOR_OPTION_NONE:
- break;
- case EXTRACTOR_OPTION_OUT_OF_PROCESS:
- if (0 == ppos->cpid)
+ case EXTRACTOR_OPTION_DEFAULT_POLICY:
+ if ( (0 == ppos->cpid) ||
+ (-1 == ppos->cpid) )
start_process (ppos);
want_shm = 1;
break;
- case EXTRACTOR_OPTION_AUTO_RESTART:
- if ( (0 == ppos->cpid) ||
- (-1 == ppos->cpid) )
+ case EXTRACTOR_OPTION_OUT_OF_PROCESS_NO_RESTART:
+ if (0 == ppos->cpid)
start_process (ppos);
want_shm = 1;
break;
+ case EXTRACTOR_OPTION_IN_PROCESS:
+ break;
case EXTRACTOR_OPTION_DISABLED:
break;
}
@@ -1342,13 +1346,30 @@
{
flags = ppos->flags;
if (shmid == -1)
- flags = EXTRACTOR_OPTION_NONE;
+ flags = EXTRACTOR_OPTION_IN_PROCESS;
switch (flags)
{
- case EXTRACTOR_OPTION_NONE:
+ case EXTRACTOR_OPTION_DEFAULT_POLICY:
+ if (0 != extract_oop (ppos, fn, proc, proc_cls))
+ return;
+ if (ppos->cpid == -1)
+ {
+ start_process (ppos);
+ if (0 != extract_oop (ppos, fn, proc, proc_cls))
+ return;
+ }
+ break;
+ case EXTRACTOR_OPTION_OUT_OF_PROCESS_NO_RESTART:
+ if (0 != extract_oop (ppos, fn, proc, proc_cls))
+ return;
+ break;
+ case EXTRACTOR_OPTION_IN_PROCESS:
if (NULL == ppos->extractMethod)
plugin_load (ppos);
- if ( (NULL != ppos->extractMethod) &&
+ if ( ( (ppos->specials == NULL) ||
+ (NULL == strstr (ppos->specials,
+ "oop-only")) ) &&
+ (NULL != ppos->extractMethod) &&
(0 != ppos->extractMethod (data,
size,
proc,
@@ -1356,11 +1377,6 @@
ppos->plugin_options)) )
return;
break;
- case EXTRACTOR_OPTION_OUT_OF_PROCESS:
- case EXTRACTOR_OPTION_AUTO_RESTART:
- if (0 != extract_oop (ppos, fn, proc, proc_cls))
- return;
- break;
case EXTRACTOR_OPTION_DISABLED:
break;
}
Modified: Extractor/src/plugins/Makefile.am
===================================================================
--- Extractor/src/plugins/Makefile.am 2009-12-20 15:27:04 UTC (rev 9825)
+++ Extractor/src/plugins/Makefile.am 2009-12-20 19:55:40 UTC (rev 9826)
@@ -394,23 +394,3 @@
$(PLUGINFLAGS)
EXTRA_DIST = template_extractor.c
-
-
-install-exec-hook:
- mkdir -p $(DESTDIR)$(plugindir) &> /dev/null || true
- rm -f $(DESTDIR)$(plugindir)/libextractor_thumbnail$(LIBEXT)
- rm -f $(DESTDIR)$(plugindir)/libextractor_thumbnail.la
- if test "$(thumbgtk)" != ""; then \
- $(LN_S) $(plugindir)/libextractor_thumbnailgtk$(LIBEXT) \
- $(DESTDIR)$(plugindir)/libextractor_thumbnail$(LIBEXT);
\
- else \
- if test "$(thumbqt)" != ""; then \
- $(LN_S) $(plugindir)/libextractor_thumbnailqt$(LIBEXT) \
-
$(DESTDIR)$(plugindir)/libextractor_thumbnail$(LIBEXT); \
- else \
- if test "$(thumbffmpeg)" != ""; then \
- $(LN_S)
$(plugindir)/libextractor_thumbnailffmpeg$(LIBEXT) \
-
$(DESTDIR)$(plugindir)/libextractor_thumbnail$(LIBEXT); \
- fi \
- fi \
- fi
Modified: Extractor/src/plugins/mime_extractor.c
===================================================================
--- Extractor/src/plugins/mime_extractor.c 2009-12-20 15:27:04 UTC (rev
9825)
+++ Extractor/src/plugins/mime_extractor.c 2009-12-20 19:55:40 UTC (rev
9826)
@@ -265,7 +265,7 @@
{"moov", 4, "video/quicktime", DEFAULT},
{"mdat", 4, "video/quicktime", DEFAULT},
{"\x8aMNG", 4, "video/x-mng", DEFAULT},
- {"\x30\x26\xb2\x75\x8e\x66", 6, "video/asf", DEFAULT}, /* same as
.wmv ? */
+ {"\x30\x26\xb2\x75\x8e\x66", 6, "video/x-ms-asf", DEFAULT}, /* same
as .wmv ? */
{"FWS", 3, "application/x-shockwave-flash", DEFAULT},
{"MThd", 4, "audio/midi", DEFAULT},
{"ID3", 3, "audio/mpeg", DEFAULT},
Modified: Extractor/src/plugins/thumbnailffmpeg_extractor.c
===================================================================
--- Extractor/src/plugins/thumbnailffmpeg_extractor.c 2009-12-20 15:27:04 UTC
(rev 9825)
+++ Extractor/src/plugins/thumbnailffmpeg_extractor.c 2009-12-20 19:55:40 UTC
(rev 9826)
@@ -44,290 +44,28 @@
#define DEBUG 0
-struct StreamDescriptor
-{
- const uint8_t *data;
- size_t offset;
- size_t size;
-};
-
-
void __attribute__ ((constructor)) ffmpeg_lib_init (void)
{
-#if DEBUG
- printf ("av_register_all()\n");
-#endif
av_register_all ();
}
-static int
-stream_read (void *opaque, uint8_t * buf, int buf_size)
-{
- struct StreamDescriptor *rs = (struct StreamDescriptor *) opaque;
- size_t len;
-#if DEBUG
- printf ("read_packet: %zu\n", buf_size);
-#endif
- if (rs)
- {
- if (rs->data == NULL)
- return -1;
- if (rs->offset >= rs->size)
- return 0;
- len = buf_size;
- if (rs->offset + len > rs->size)
- len = rs->size - rs->offset;
-
- memcpy (buf, rs->data + rs->offset, len);
- rs->offset += len;
-#if DEBUG
- printf ("read_packet: len: %zu\n", len);
-#endif
- return len;
- }
- return -1;
-}
-
-static int64_t
-stream_seek (void *opaque, int64_t offset, int whence)
-{
- struct StreamDescriptor *rs = (struct StreamDescriptor *) opaque;
- int64_t off_abs;
-#if DEBUG
- printf ("my_seek: %lld %d\n", offset, whence);
-#endif
- if (rs)
- {
- if (whence == AVSEEK_SIZE)
- return (int64_t) rs->size;
- else if (whence == SEEK_CUR)
- off_abs = (int64_t) rs->offset + offset;
- else if (whence == SEEK_SET)
- off_abs = offset;
- else if (whence == SEEK_END)
- off_abs = (int64_t) rs->size + offset;
- else
- {
- printf ("whence error %d\n", whence);
- abort ();
- return AVERROR (EINVAL);
- }
- if (off_abs >= 0 && off_abs < (int64_t) rs->size)
- rs->offset = (size_t) off_abs;
- else
- off_abs = AVERROR (EINVAL);
- return off_abs;
- }
- return -1;
-}
-
-struct MimeToDecoderMapping
-{
- const char *mime_type;
- enum CodecID codec_id;
-};
-
-/* map mime image types to a decoder */
-static const struct MimeToDecoderMapping m2d_map[] = {
- {"image/x-bmp", CODEC_ID_BMP},
- {"image/gif", CODEC_ID_GIF},
- {"image/jpeg", CODEC_ID_MJPEG},
- {"image/jpeg-proprietary", CODEC_ID_MJPEG},
- {"image/png", CODEC_ID_PNG},
- {"image/x-png", CODEC_ID_PNG},
- {"image/tiff", CODEC_ID_TIFF},
- {"image/x-portable-pixmap", CODEC_ID_PPM},
-#if DOES_THIS_WORK
- { "video/mpeg", CODEC_ID_MPEG2VIDEO },
- { "video/x-flv", CODEC_ID_FLV1 },
- { "video/x-msvideo", CODEC_ID_MSVIDEO1 },
- { "video/asf", CODEC_ID_WMV1 /* or is this WMV2? */ },
-#endif
- {NULL, CODEC_ID_NONE}
-};
-
-#define PROBE_MAX (1<<20)
-#define BIOBUF_SIZE (64*1024)
#define THUMBSIZE 128 /* max dimension in pixels */
#define MAX_THUMB_SIZE (100*1024) /* in bytes */
-/* ******** mime type detection code (copied from mime_extractor)
************* */
-
-
-/**
- * Detect a file-type.
- * @param data the contents of the file
- * @param len the length of the file
- * @param arg closure...
- * @return 0 if the file does not match, 1 if it does
- **/
-typedef int (*Detector) (const char *data, size_t len, void *arg);
-
-/**
- * Detect a file-type.
- * @param data the contents of the file
- * @param len the length of the file
- * @return always 1
- **/
-static int
-defaultDetector (const char *data, size_t len, void *arg)
+const char *
+EXTRACTOR_thumbnailffmpeg_options ()
{
- return 1;
+ return "force-kill;oop-only;close-stderr";
}
-/**
- * Detect a file-type.
- * @param data the contents of the file
- * @param len the length of the file
- * @return always 0
- **/
-static int
-disableDetector (const char *data, size_t len, void *arg)
+const char *
+EXTRACTOR_thumbnail_options ()
{
- return 0;
+ return "force-kill;oop-only;close-stderr";
}
-typedef struct ExtraPattern
-{
- int pos;
- int len;
- const char *pattern;
-} ExtraPattern;
-/**
- * Define special matching rules for complicated formats...
- **/
-static ExtraPattern xpatterns[] = {
-#define AVI_XPATTERN 0
- {8, 4, "AVI "},
- {0, 0, NULL},
-#define WAVE_XPATTERN 2
- {8, 4, "WAVE"},
- {0, 0, NULL},
-#define ACON_XPATTERN 12
- {8, 4, "ACON"},
- {0, 0, NULL},
-#define CR2_PATTERN 14
- {8, 3, "CR\x02"},
- {0, 0, NULL},
-};
-
-/**
- * Detect AVI. A pattern matches if all XPatterns until the next {0,
- * 0, NULL} slot match. OR-ing patterns can be achieved using multiple
- * entries in the main table, so this "AND" (all match) semantics are
- * the only reasonable answer.
- **/
-static int
-xPatternMatcher (const char *data, size_t len, void *cls)
-{
- ExtraPattern *arg = cls;
-
- while (arg->pattern != NULL)
- {
- if (arg->pos + arg->len > len)
- return 0;
- if (0 != memcmp (&data[arg->pos], arg->pattern, arg->len))
- return 0;
- arg++;
- }
- return 1;
-}
-
-/**
- * Use this detector, if the simple header-prefix matching is
- * sufficient.
- */
-#define DEFAULT &defaultDetector, NULL
-
-/**
- * Use this detector, to disable the mime-type (effectively comment it
- * out).
- */
-#define DISABLED &disableDetector, NULL
-
-/**
- * Select an entry in xpatterns for matching
- */
-#define XPATTERN(a) &xPatternMatcher, &xpatterns[(a)]
-
-
-typedef struct Pattern
-{
- const char *pattern;
- int size;
- const char *mimetype;
- Detector detector;
- void *arg;
-} Pattern;
-
-
-static Pattern patterns[] = {
- /* FIXME: add patterns for other mime-types
- supported by ffmpeg (also add those to
- the mime extractor itself!) */
- {"\xFF\xD8", 2, "image/jpeg", DEFAULT},
- {"\211PNG\r\n\032\n", 8, "image/png", DEFAULT},
- {"/* XPM */", 9, "image/x-xpm", DEFAULT},
- {"GIF8", 4, "image/gif", DEFAULT},
- {"P1", 2, "image/x-portable-bitmap", DEFAULT},
- {"P2", 2, "image/x-portable-graymap", DEFAULT},
- {"P3", 2, "image/x-portable-pixmap", DEFAULT},
- {"P4", 2, "image/x-portable-bitmap", DEFAULT},
- {"P5", 2, "image/x-portable-graymap", DEFAULT},
- {"P6", 2, "image/x-portable-pixmap", DEFAULT},
- {"P7", 2, "image/x-portable-anymap", DEFAULT},
- {"BM", 2, "image/x-bmp", DEFAULT},
- {"\x89PNG", 4, "image/x-png", DEFAULT},
- {"hsi1", 4, "image/x-jpeg-proprietary", DEFAULT},
- {"FLV", 3, "video/x-flv", DEFAULT},
- {"\x2E\x52\x4d\x46", 4, "video/real", DEFAULT},
- {"IIN1", 4, "image/tiff", DEFAULT},
- {"MM\x00\x2a", 4, "image/tiff", DEFAULT}, /* big-endian */
- {"II\x2a\x00", 4, "image/tiff", DEFAULT}, /* little-endian */
- {"RIFF", 4, "video/x-msvideo", XPATTERN (AVI_XPATTERN)},
- {"RIFX", 4, "video/x-msvideo", XPATTERN (AVI_XPATTERN)},
- {"\x00\x00\x01\xb3", 4, "video/mpeg", DEFAULT},
- {"\x00\x00\x01\xba", 4, "video/mpeg", DEFAULT},
-
- /* FIXME: find out if ffmpeg actually makes sense for those below,
- and add those for which it does make sense to the m2d_map! */
- {"moov", 4, "video/quicktime", DEFAULT},
- {"mdat", 4, "video/quicktime", DEFAULT},
- {"\x8aMNG", 4, "video/x-mng", DEFAULT},
- {"\x30\x26\xb2\x75\x8e\x66", 6, "video/asf", DEFAULT}, /* same as .wmv ? */
- {"FWS", 3, "application/x-shockwave-flash", DEFAULT},
- {NULL, 0, NULL, DISABLED}
-};
-
-
-
-static const char *
-find_mime (const char *data,
- size_t size)
-{
- int i;
-
- i = 0;
- while (patterns[i].pattern != NULL)
- {
- if (size < patterns[i].size)
- {
- i++;
- continue;
- }
- if (0 == memcmp (patterns[i].pattern, data, patterns[i].size))
- {
- if (patterns[i].detector (data, size, patterns[i].arg))
- return patterns[i].mimetype;
- }
- i++;
- }
- return NULL;
-}
-
-
int
EXTRACTOR_thumbnailffmpeg_extract (const unsigned char *data,
size_t size,
@@ -335,210 +73,131 @@
void *proc_cls,
const char *options)
{
- int score;
- AVInputFormat *fmt;
- AVProbeData pdat;
- ByteIOContext *bio_ctx = NULL;
- uint8_t *bio_buffer;
- struct StreamDescriptor reader_state;
- AVFormatContext *format_ctx = NULL;
- AVCodecContext *codec_ctx = NULL;
+ AVProbeData pd;
AVPacket packet;
- int video_stream_index;
- AVCodec *codec;
+ AVInputFormat *m_pInputFormat;
+ ByteIOContext *bio;
+ struct AVFormatContext *fmt;
+ AVCodecContext *codec_ctx;
+ AVCodec *codec = NULL;
AVFrame *frame = NULL;
AVFrame *thumb_frame = NULL;
- int64_t ts;
-
- struct SwsContext *scaler_ctx;
+ uint8_t *encoder_output_buffer = NULL;
+ AVCodecContext *enc_codec_ctx = NULL;
+ AVCodec *enc_codec = NULL;
+ const AVFrame *tframe;
+ struct SwsContext *scaler_ctx = NULL;
+ uint8_t *thumb_buffer = NULL;
int sws_flags = SWS_BILINEAR;
- uint8_t *thumb_buffer;
- int thumb_width, thumb_height;
- int sar_num, sar_den;
-
- uint8_t *encoder_output_buffer;
+ int64_t ts;
size_t encoder_output_buffer_size;
- AVCodecContext *enc_codec_ctx;
- AVCodec *enc_codec;
-
+ int video_stream_index;
+ int thumb_width;
+ int thumb_height;
+ int sar_num;
+ int sar_den;
int i;
int err;
- int ret = 0;
int frame_finished;
+ int ret = 0;
- const char *mime;
- int is_image;
- enum CodecID image_codec_id;
-
- bio_ctx = NULL;
- bio_buffer = NULL;
- format_ctx = NULL;
- codec = NULL;
- frame = NULL;
- thumb_frame = NULL;
- thumb_buffer = NULL;
- scaler_ctx = NULL;
- encoder_output_buffer = NULL;
- enc_codec = NULL;
- enc_codec_ctx = NULL;
-
- is_image = 0;
-
- mime = find_mime ((const char*) data, size);
- if (mime == NULL)
- return 0;
- if (mime != NULL)
- {
- i = 0;
- while (m2d_map[i].mime_type != NULL)
- {
- if (!strcmp (m2d_map[i].mime_type, mime))
- {
- is_image = 1;
- image_codec_id = m2d_map[i].codec_id;
- break;
- }
- i++;
- }
- }
-
#if DEBUG
- printf ("is_image: %d codec:%d\n", is_image, image_codec_id);
+ fprintf (stderr,
+ "ffmpeg starting\n");
#endif
- if (!is_image)
+ pd.buf_size = size;
+ pd.buf = (void *) data;
+ pd.filename = "__url_prot";
+
+ if (NULL == (m_pInputFormat = av_probe_input_format(&pd, 1)))
{
- pdat.filename = NULL;
- pdat.buf = (unsigned char *) data;
- pdat.buf_size = (size > PROBE_MAX) ? PROBE_MAX : size;
-
- fmt = av_probe_input_format (&pdat, 1);
- if (fmt == NULL)
- return 0;
#if DEBUG
- printf ("format %p [%s] [%s]\n", fmt, fmt->name, fmt->long_name);
+ fprintf (stderr,
+ "Failed to probe input format\n");
#endif
- pdat.buf = (unsigned char *) data;
- pdat.buf_size = size > PROBE_MAX ? PROBE_MAX : size;
- score = fmt->read_probe (&pdat);
-#if DEBUG
- printf ("score: %d\n", score);
-#endif
- /*if (score < 50) return 0; */
+ return 0;
}
-
- if (is_image)
+ m_pInputFormat->flags |= AVFMT_NOFILE;
+ bio = NULL;
+ url_open_buf(&bio, pd.buf, pd.buf_size, URL_RDONLY);
+ bio->is_streamed = 1;
+ if ((av_open_input_stream(&fmt, bio, pd.filename, m_pInputFormat, NULL)) < 0)
{
- codec_ctx = avcodec_alloc_context ();
- codec = avcodec_find_decoder (image_codec_id);
- if (codec != NULL)
- {
- if (avcodec_open (codec_ctx, codec) != 0)
- {
-#if DEBUG
- printf ("open codec failed\n");
-#endif
- codec = NULL;
- }
- }
+ url_close_buf (bio);
+ fprintf (stderr,
+ "Failed to open input stream\n");
+ return 0;
}
- else
+ if (0 > av_find_stream_info (fmt))
{
- bio_ctx = malloc (sizeof (ByteIOContext));
- bio_buffer = malloc (BIOBUF_SIZE);
-
- reader_state.data = data;
- reader_state.offset = 0;
- reader_state.size = size;
-
- init_put_byte (bio_ctx, bio_buffer,
- BIOBUF_SIZE, 0, &reader_state,
- stream_read, NULL, stream_seek);
-
- fmt->flags |= AVFMT_NOFILE;
- err = av_open_input_stream (&format_ctx, bio_ctx, "", fmt, NULL);
- if (err < 0)
- {
-#if DEBUG
- printf ("couldn't open input stream\n");
-#endif
- goto out;
- }
-
- err = av_find_stream_info (format_ctx);
- if (err < 0)
- {
-#if DEBUG
- printf ("couldn't find codec params\n");
-#endif
- goto out;
- }
-
- for (i = 0; i < format_ctx->nb_streams; i++)
- {
- codec_ctx = format_ctx->streams[i]->codec;
- if (codec_ctx->codec_type == CODEC_TYPE_VIDEO)
- {
- video_stream_index = i;
- codec = avcodec_find_decoder (codec_ctx->codec_id);
- if (codec == NULL)
- {
-#if DEBUG
- printf ("find_decoder failed\n");
-#endif
- break;
- }
- err = avcodec_open (codec_ctx, codec);
- if (err != 0)
- {
-#if DEBUG
- printf ("failed to open codec\n");
-#endif
- codec = NULL;
- }
- break;
- }
- }
+ av_close_input_stream (fmt);
+ url_close_buf (bio);
+ fprintf (stderr,
+ "Failed to read stream info\n");
+ return 0;
}
- if (codec_ctx == NULL || codec == NULL)
+ codec_ctx = NULL;
+ for (i=0; i<fmt->nb_streams; i++)
{
-#if DEBUG
- printf ("failed to open codec");
-#endif
- goto out;
+ codec_ctx = fmt->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 ( (codec_ctx == NULL) ||
+ (codec == NULL) ||
+ (codec_ctx->width == 0) ||
+ (codec_ctx->height == 0) )
+ {
+ if (codec_ctx != NULL)
+ avcodec_close (codec_ctx);
+ av_close_input_stream (fmt);
+ url_close_buf (bio);
+ fprintf (stderr,
+ "No video codec found\n");
+ return 0;
}
+
frame = avcodec_alloc_frame ();
if (frame == NULL)
{
-#if DEBUG
- printf ("failed to alloc frame");
-#endif
- goto out;
+ if (codec != NULL)
+ avcodec_close (codec_ctx);
+ av_close_input_stream (fmt);
+ url_close_buf (bio);
+ fprintf (stderr,
+ "Failed to allocate frame\n");
+ return 0;
}
-
- if (!is_image)
- {
#if DEBUG
- printf ("duration: %lld\n", format_ctx->duration);
- if (format_ctx->duration == AV_NOPTS_VALUE)
- printf ("duration unknown\n");
+ if (fmt->duration == AV_NOPTS_VALUE)
+ fprintf (stderr,
+ "duration unknown\n");
+ else
+ fprintf (stderr,
+ "duration: %lld\n",
+ fmt->duration);
#endif
- /* TODO: if duration is known seek to to some better place(?) */
- ts = 10; // s
- ts = ts * AV_TIME_BASE;
- err = av_seek_frame (format_ctx, -1, ts, 0);
- if (err >= 0)
- {
- avcodec_flush_buffers (codec_ctx);
- }
-#if DEBUG
- else
- printf ("seeking failed %d\n", err);
-#endif
- }
-
+ /* TODO: if duration is known seek to to some better place(?) */
+ ts = 10; /* s */
+ ts = ts * AV_TIME_BASE;
+ err = av_seek_frame (fmt, -1, ts, 0);
+ if (err >= 0)
+ avcodec_flush_buffers (codec_ctx);
frame_finished = 0;
- if (is_image)
+
+ if (0 /* is_image */)
{
avcodec_decode_video (codec_ctx, frame, &frame_finished, data, size);
}
@@ -546,7 +205,7 @@
{
while (1)
{
- err = av_read_frame (format_ctx, &packet);
+ err = av_read_frame (fmt, &packet);
if (err < 0)
break;
if (packet.stream_index == video_stream_index)
@@ -564,10 +223,17 @@
av_free_packet (&packet);
}
}
+ if (!frame_finished)
+ {
+ if (frame != NULL)
+ av_free (frame);
+ av_close_input_stream (fmt);
+ free (bio);
+ fprintf (stderr,
+ "Failed to seek to frame\n");
+ return 0;
+ }
- if (!frame_finished || codec_ctx->width == 0 || codec_ctx->height == 0)
- goto out;
-
sar_num = codec_ctx->sample_aspect_ratio.num;
sar_den = codec_ctx->sample_aspect_ratio.den;
if (sar_num <= 0 || sar_den <= 0)
@@ -575,61 +241,83 @@
sar_num = 1;
sar_den = 1;
}
- if ((codec_ctx->width * sar_num) / sar_den > codec_ctx->height)
+ if ( (codec_ctx->width < THUMBSIZE) &&
+ (codec_ctx->height < THUMBSIZE) )
{
- thumb_width = THUMBSIZE;
- thumb_height = (thumb_width * codec_ctx->height) /
- ((codec_ctx->width * sar_num) / sar_den);
+ /* no resize */
+ thumb_width = codec_ctx->width;
+ thumb_height = codec_ctx->height;
+ tframe = frame;
}
else
{
- thumb_height = THUMBSIZE;
- thumb_width = (thumb_height *
- ((codec_ctx->width * sar_num) / sar_den)) /
- codec_ctx->height;
- }
- if (thumb_width < 8)
- thumb_width = 8;
- if (thumb_height < 1)
- thumb_height = 1;
+ /* need resize */
+ if ((codec_ctx->width * sar_num) / sar_den > codec_ctx->height)
+ {
+ thumb_width = THUMBSIZE;
+ thumb_height = (thumb_width * codec_ctx->height) /
+ ((codec_ctx->width * sar_num) / sar_den);
+ }
+ else
+ {
+ thumb_height = THUMBSIZE;
+ thumb_width = (thumb_height *
+ ((codec_ctx->width * sar_num) / sar_den)) /
+ codec_ctx->height;
+ }
+ if (thumb_width < 8)
+ thumb_width = 8;
+ if (thumb_height < 1)
+ thumb_height = 1;
#if DEBUG
- printf ("thumb dim: %d %d\n", thumb_width, thumb_height);
+ fprintf (stderr,
+ "thumb dim: %d %d\n",
+ thumb_width,
+ thumb_height);
#endif
- scaler_ctx =
- sws_getContext (codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt,
- thumb_width, thumb_height, PIX_FMT_RGB24, sws_flags, NULL,
- NULL, NULL);
- if (scaler_ctx == NULL)
- {
+ scaler_ctx =
+ sws_getContext (codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt,
+ thumb_width, thumb_height, PIX_FMT_RGB24, sws_flags,
NULL,
+ NULL, NULL);
+ if (scaler_ctx == NULL)
+ {
#if DEBUG
- printf ("failed to alloc scaler\n");
+ fprintf (stderr,
+ "failed to alloc scaler\n");
#endif
- goto out;
- }
- thumb_frame = avcodec_alloc_frame ();
- thumb_buffer =
- av_malloc (avpicture_get_size (PIX_FMT_RGB24, thumb_width, thumb_height));
- if (thumb_frame == NULL || thumb_buffer == NULL)
- {
+ goto out;
+ }
+ thumb_frame = avcodec_alloc_frame ();
+ thumb_buffer =
+ av_malloc (avpicture_get_size (PIX_FMT_RGB24, thumb_width,
thumb_height));
+ if (thumb_frame == NULL || thumb_buffer == NULL)
+ {
#if DEBUG
- printf ("failed to alloc thumb frame\n");
+ fprintf (stderr,
+ "failed to alloc thumb frame\n");
#endif
- goto out;
+ goto out;
+ }
+ avpicture_fill ((AVPicture *) thumb_frame, thumb_buffer,
+ PIX_FMT_RGB24, thumb_width, thumb_height);
+
+ sws_scale (scaler_ctx,
+ frame->data,
+ frame->linesize,
+ 0, codec_ctx->height,
+ thumb_frame->data,
+ thumb_frame->linesize);
+ tframe = thumb_frame;
}
- avpicture_fill ((AVPicture *) thumb_frame, thumb_buffer,
- PIX_FMT_RGB24, thumb_width, thumb_height);
- sws_scale (scaler_ctx,
- frame->data, frame->linesize,
- 0, codec_ctx->height, thumb_frame->data, thumb_frame->linesize);
-
encoder_output_buffer_size = MAX_THUMB_SIZE;
encoder_output_buffer = av_malloc (encoder_output_buffer_size);
if (encoder_output_buffer == NULL)
{
#if DEBUG
- printf ("couldn't alloc encoder output buf\n");
+ fprintf (stderr,
+ "couldn't alloc encoder output buf\n");
#endif
goto out;
}
@@ -638,7 +326,8 @@
if (enc_codec == NULL)
{
#if DEBUG
- printf ("couldn't find encoder\n");
+ fprintf (stderr,
+ "couldn't find encoder\n");
#endif
goto out;
}
@@ -650,7 +339,8 @@
if (avcodec_open (enc_codec_ctx, enc_codec) < 0)
{
#if DEBUG
- printf ("couldn't open encoder\n");
+ fprintf (stderr,
+ "couldn't open encoder\n");
#endif
enc_codec = NULL;
goto out;
@@ -658,7 +348,7 @@
err = avcodec_encode_video (enc_codec_ctx,
encoder_output_buffer,
- encoder_output_buffer_size, thumb_frame);
+ encoder_output_buffer_size, tframe);
if (err > 0)
ret = proc (proc_cls,
"thumbnailffmpeg",
@@ -676,21 +366,18 @@
av_free (encoder_output_buffer);
if (scaler_ctx != NULL)
sws_freeContext(scaler_ctx);
- if (codec != NULL)
+ if (codec_ctx != NULL)
avcodec_close (codec_ctx);
- if (format_ctx != NULL)
- av_close_input_file (format_ctx);
+ if (fmt != NULL)
+ av_close_input_stream (fmt);
if (frame != NULL)
av_free (frame);
if (thumb_buffer != NULL)
av_free (thumb_buffer);
if (thumb_frame != NULL)
av_free (thumb_frame);
- if (bio_ctx != NULL)
- free (bio_ctx);
- if (bio_buffer != NULL)
- free (bio_buffer);
-
+ if (bio != NULL)
+ url_close_buf (bio);
return ret;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r9826 - in Extractor: . src/include src/main src/plugins,
gnunet <=