libextractor

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

commit cbddde4ceb2d04349bc84e6542d2480e71f3ab69
parent 26f7618e82c6d758404251c5f175e0e910d4e47f
Author: Bruno Cabral <brataoufba@gmail.com>
Date:   Sat, 21 Dec 2013 02:52:06 +0000


Diffstat:
Mconfigure.ac | 8+++++---
Msrc/main/extractor.c | 17++++++++++++++---
Msrc/main/extractor_ipc_gnu.c | 2+-
Msrc/main/extractor_ipc_w32.c | 16+++++++++++++++-
Msrc/main/extractor_logging.h | 2+-
Msrc/main/extractor_plugin_main.c | 30+++++++++++++++++++++++++++++-
Msrc/main/extractor_plugins.c | 43+++++++++++++++++++++++++++++++++++++++++++
Msrc/plugins/gstreamer_extractor.c | 20++++++++++++++++++++
Msrc/plugins/previewopus_extractor.c | 30+++++++++---------------------
Msrc/plugins/thumbnailffmpeg_extractor.c | 50+++++++++++++++++++++++++++++++++++++++++++++-----
10 files changed, 182 insertions(+), 36 deletions(-)

diff --git a/configure.ac b/configure.ac @@ -672,11 +672,13 @@ if test x$ffmpeg_enabled = x1 then ffmpeg_enabled=0 new_ffmpeg=0 - AC_CHECK_HEADERS([libavutil/frame.h],new_ffmpeg=1) + AC_CHECK_HEADERS([libavutil/frame.h], + AC_CHECK_HEADERS([libavresample/avresample.h],new_ffmpeg=1)) + AC_CHECK_LIB(swscale, sws_getContext, AC_CHECK_LIB(avcodec, avcodec_alloc_context3, ffmpeg_enabled=1)) - AC_CHECK_HEADERS([libavutil/avutil.h ffmpeg/avutil.h libavformat/avformat.h ffmpeg/avformat.h libavcodec/avcodec.h ffmpeg/avcodec.h libswscale/swscale.h ffmpeg/swscale.h libavresample/avresample.h ffmpeg/avresample.h]) + AC_CHECK_HEADERS([libavutil/avutil.h ffmpeg/avutil.h libavformat/avformat.h ffmpeg/avformat.h libavcodec/avcodec.h ffmpeg/avcodec.h libswscale/swscale.h ffmpeg/swscale.h]) fi AM_CONDITIONAL(HAVE_FFMPEG, test x$ffmpeg_enabled != x0) AM_CONDITIONAL(HAVE_FFMPEG_NEW, test x$new_ffmpeg != x0) @@ -805,7 +807,7 @@ fi if test "x$new_ffmpeg" = "x0" then - AC_MSG_NOTICE([NOTICE: FFmpeg/opus audio preview plugin disabled]) + AC_MSG_NOTICE([NOTICE: FFmpeg/opus audio preview plugin disabled, It needs libav > 10, or a FFmpeg with --enable-libavresample]) fi if test "x$without_gtk" = "xtrue" diff --git a/src/main/extractor.c b/src/main/extractor.c @@ -35,7 +35,7 @@ /** * Size used for the shared memory segment. */ -#define DEFAULT_SHM_SIZE (16 * 1024) +#define DEFAULT_SHM_SIZE (160 * 1024) /** @@ -382,6 +382,8 @@ do_extract (struct EXTRACTOR_PluginList *plugins, ssize_t ready; int done; int have_in_memory; + + LOG ("Stating !\n"); plugin_count = 0; for (pos = plugins; NULL != pos; pos = pos->next) @@ -401,6 +403,7 @@ do_extract (struct EXTRACTOR_PluginList *plugins, start.reserved2 = 0; start.shm_ready_bytes = (uint32_t) ready; start.file_size = EXTRACTOR_datasource_get_size_ (ds, 0); + LOG ("Have %d\ !\n",plugin_count); for (pos = plugins; NULL != pos; pos = pos->next) { if (EXTRACTOR_OPTION_IN_PROCESS == pos->flags) @@ -424,6 +427,7 @@ do_extract (struct EXTRACTOR_PluginList *plugins, done = 0; while (! done) { + //LOG ("In !done while\n"); struct EXTRACTOR_Channel *channels[plugin_count]; /* calculate current 'channels' array */ @@ -433,15 +437,18 @@ do_extract (struct EXTRACTOR_PluginList *plugins, if (-1 == pos->seek_request) { /* channel is not seeking, must be running or done */ + //LOG ("No seeking, done\n"); channels[plugin_off] = pos->channel; } else { /* not running this round, seeking! */ + //LOG ("Nor running, seeking\n"); channels[plugin_off] = NULL; } plugin_off++; } + //LOG ("Will call EXTRACTOR_IPC_channel_recv_\n"); /* give plugins chance to send us meta data, seek or finished messages */ if (-1 == EXTRACTOR_IPC_channel_recv_ (channels, @@ -450,7 +457,7 @@ do_extract (struct EXTRACTOR_PluginList *plugins, &prp)) { /* serious problem in IPC; reset *all* channels */ - LOG ("Failed to receive message from channels; full reset\n"); + //LOG ("Failed to receive message from channels; full reset\n"); abort_all_channels (plugins); break; } @@ -463,10 +470,14 @@ do_extract (struct EXTRACTOR_PluginList *plugins, { plugin_off++; if ( (1 == pos->round_finished) || - (NULL == pos->channel) ) + (NULL == pos->channel) ){ + //LOG ("Inative plugin\n"); continue; /* inactive plugin */ + + } if (-1 == pos->seek_request) { + //LOG ("pos->seek_request\n"); /* possibly more meta data at current position, at least this plugin is still working on it... */ done = 0; diff --git a/src/main/extractor_ipc_gnu.c b/src/main/extractor_ipc_gnu.c @@ -464,7 +464,7 @@ EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, return 1; /* nothing left to do! */ } tv.tv_sec = 0; - tv.tv_usec = 500000; /* 500 ms */ + tv.tv_usec = 5000000; /* 500 ms */ if (0 >= select (max + 1, &to_check, NULL, NULL, &tv)) { /* an error or timeout -> something's wrong or all plugins hung up */ diff --git a/src/main/extractor_ipc_w32.c b/src/main/extractor_ipc_w32.c @@ -725,12 +725,17 @@ EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, if (c == 0) return 1; /* nothing left to do! */ - ms = 10000; + ms = 1000000; first_ready = WaitForMultipleObjects (c, events, FALSE, ms); if (first_ready == WAIT_TIMEOUT || first_ready == WAIT_FAILED) { /* an error or timeout -> something's wrong or all plugins hung up */ LOG_STRERROR ("WaitForMultipleObjects"); + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "WaitForMultipleObjects \n"); + fclose(f); + return -1; } @@ -749,6 +754,10 @@ EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, if (MAX_META_DATA == channels[i]->mdata_size) { LOG ("Inbound message from channel too large, aborting\n"); + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "Inbound message from channel too large, aborting \n"); + fclose(f); EXTRACTOR_IPC_channel_destroy_ (channels[i]); channels[i] = NULL; } @@ -761,6 +770,11 @@ EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, LOG_STRERROR ("realloc"); EXTRACTOR_IPC_channel_destroy_ (channels[i]); channels[i] = NULL; + + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "Realloc \n"); + fclose(f); } channels[i]->mdata = ndata; } diff --git a/src/main/extractor_logging.h b/src/main/extractor_logging.h @@ -25,7 +25,7 @@ #ifndef EXTRACTOR_LOGGING_H #define EXTRACTOR_LOGGING_H -#define DEBUG 0 +#define DEBUG 1 #if DEBUG diff --git a/src/main/extractor_plugin_main.c b/src/main/extractor_plugin_main.c @@ -460,6 +460,7 @@ handle_start_message (struct ProcessingContext *pc) LOG ("Failed to read 'start' message\n"); return -1; } + fprintf (stderr, "Got start msg\n"); pc->shm_ready_bytes = start.shm_ready_bytes; pc->file_size = start.file_size; pc->read_position = 0; @@ -475,6 +476,10 @@ handle_start_message (struct ProcessingContext *pc) if (-1 == EXTRACTOR_write_all_ (pc->out, &done, sizeof (done))) { LOG ("Failed to write 'done' message\n"); + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "Failed to write 'done' message' \n"); + fclose(f); return -1; } if ( (NULL != pc->plugin->specials) && @@ -524,18 +529,33 @@ process_requests (struct ProcessingContext *pc) if (0 != handle_start_message (pc)) { LOG ("Failure to handle START\n"); + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "Failure to handle START' \n"); + fclose(f); return; } break; - case MESSAGE_UPDATED_SHM: + case MESSAGE_UPDATED_SHM:{ LOG ("Illegal message\n"); /* not allowed here, we're not waiting for SHM to move! */ + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "Illegal message' \n"); + fclose(f); + return; + } case MESSAGE_DISCARD_STATE: /* odd, we're already in the start state... */ continue; default: LOG ("Received invalid messag %d\n", (int) code); + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "Received invalid messag' \n"); + fclose(f); + /* error, unexpected message */ return; } @@ -625,6 +645,14 @@ EXTRACTOR_plugin_main_ (struct EXTRACTOR_PluginList *plugin, process_requests (&pc); LOG ("IPC error; plugin `%s' terminates!\n", plugin->short_libname); + + + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "IPC error; plugin `%s' terminates!\n", + plugin->short_libname); + fclose(f); + #if WINDOWS if (NULL != pc.shm) UnmapViewOfFile (pc.shm); diff --git a/src/main/extractor_plugins.c b/src/main/extractor_plugins.c @@ -120,6 +120,14 @@ get_symbol_with_prefix (void *lib_handle, int EXTRACTOR_plugin_load_ (struct EXTRACTOR_PluginList *plugin) { + +LOG ("In EXTRACTOR_plugin_load_"); + + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "EXTRACTOR_plugin_load_\n"); + fclose(f); + #if WINDOWS wchar_t wlibname[4097]; char llibname[4097]; @@ -137,6 +145,11 @@ EXTRACTOR_plugin_load_ (struct EXTRACTOR_PluginList *plugin) plugin->flags = EXTRACTOR_OPTION_DISABLED; return -1; } + + LOG ("Loading plugin `%s' \n", plugin->short_libname); + lt_dlclose (plugin->libraryHandle); + + lt_dladvise_init (&advise); lt_dladvise_ext (&advise); lt_dladvise_local (&advise); @@ -151,6 +164,11 @@ EXTRACTOR_plugin_load_ (struct EXTRACTOR_PluginList *plugin) LOG ("Loading `%s' plugin failed: %s\n", plugin->short_libname, "can't convert plugin name to local encoding"); + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "Loading `%s' plugin failed!\n", + plugin->short_libname); + fclose(f); free (plugin->libname); plugin->libname = NULL; plugin->flags = EXTRACTOR_OPTION_DISABLED; @@ -189,6 +207,15 @@ EXTRACTOR_plugin_load_ (struct EXTRACTOR_PluginList *plugin) plugin->flags = EXTRACTOR_OPTION_DISABLED; return -1; } + + LOG ("Loaded plugin `%s' \n", plugin->short_libname); + + + f = fopen("debug.txt", "a+"); + fprintf(f, "Loaded plugin `%s' \n", plugin->short_libname); + fclose(f); + + return 0; } @@ -211,6 +238,12 @@ EXTRACTOR_plugin_add (struct EXTRACTOR_PluginList *prev, struct EXTRACTOR_PluginList *plugin; struct EXTRACTOR_PluginList *pos; char *libname; + + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "EXTRACTOR_plugin_add\n"); + fclose(f); + for (pos = prev; NULL != pos; pos = pos->next) if (0 == strcmp (pos->short_libname, library)) @@ -344,6 +377,9 @@ EXTRACTOR_plugin_remove (struct EXTRACTOR_PluginList *prev, struct EXTRACTOR_PluginList *pos; struct EXTRACTOR_PluginList *first; + + + pos = prev; first = prev; while ( (NULL != pos) && @@ -358,6 +394,13 @@ EXTRACTOR_plugin_remove (struct EXTRACTOR_PluginList *prev, library); return first; } + + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "Closoing %s\n",pos->short_libname); + fclose(f); + + /* found, close library */ if (first == pos) first = pos->next; diff --git a/src/plugins/gstreamer_extractor.c b/src/plugins/gstreamer_extractor.c @@ -1127,6 +1127,11 @@ send_audio_info (GstDiscovererAudioInfo *info, const gchar *ctmp; guint u; + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "send_audio_info\n"); + fclose(f); + ctmp = gst_discoverer_audio_info_get_language (info); if (ctmp) if ((ps->time_to_leave = ps->ec->proc (ps->ec->cls, "gstreamer", @@ -2048,6 +2053,11 @@ EXTRACTOR_gstreamer_extract_method (struct EXTRACTOR_ExtractContext *ec) memset (&ps, 0, sizeof (ps)); ps.dc = gst_discoverer_new (8 * GST_SECOND, &err); + FPRINTF(stderr,"gstreamer_init \n"); + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "EXTRACTOR_gstreamer_extract_method\n"); + fclose(f); if (NULL == ps.dc) { if (NULL != err) @@ -2076,6 +2086,10 @@ EXTRACTOR_gstreamer_extract_method (struct EXTRACTOR_ExtractContext *ec) gst_discoverer_stop (ps.dc); g_object_unref (ps.dc); g_main_loop_unref (ps.loop); + + f = fopen("debug.txt", "a+"); + fprintf(f, "EXTRACTOR_gstreamer_extract_method end\n"); + fclose(f); } @@ -2085,6 +2099,12 @@ EXTRACTOR_gstreamer_extract_method (struct EXTRACTOR_ExtractContext *ec) void __attribute__ ((constructor)) gstreamer_init () { +FPRINTF(stderr,"gstreamer_init \n"); + FILE *f; + f = fopen("debug.txt", "a+"); + fprintf(f, "gstreamer_init\n"); + fclose(f); + gst_init (NULL, NULL); g_log_set_default_handler (&log_handler, NULL); g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, diff --git a/src/plugins/previewopus_extractor.c b/src/plugins/previewopus_extractor.c @@ -66,11 +66,10 @@ #endif //TODO: Check for ffmpeg -#if HAVE_LIBAVRESAMPLE_AVRESAMPLE_H #include <libavresample/avresample.h> -#elif HAVE_FFMPEG_AVRESAMPLE_H -#include <ffmpeg/avresample.h> -#endif + + + @@ -202,19 +201,16 @@ static int open_output_file( AVFormatContext **output_format_context, AVCodecContext **output_codec_context) { - AVIOContext *output_io_context = NULL; AVStream *stream = NULL; AVCodec *output_codec = NULL; AVIOContext *io_ctx; int error; - - - AVDictionary *options; + unsigned char *iob; if (NULL == (iob = av_malloc (16 * 1024))) - return; + return AVERROR_EXIT; if (NULL == (io_ctx = avio_alloc_context (iob, 16 * 1024, AVIO_FLAG_WRITE, NULL, NULL, @@ -222,12 +218,12 @@ static int open_output_file( NULL))) { av_free (iob); - return; + return AVERROR_EXIT; } if (NULL == ((*output_format_context) = avformat_alloc_context ())) { av_free (io_ctx); - return; + return AVERROR_EXIT; } (*output_format_context)->pb = io_ctx; @@ -825,7 +821,6 @@ static int write_output_file_trailer(AVFormatContext *output_format_context) static void extract_audio (struct EXTRACTOR_ExtractContext *ec) { - AVPacket packet; AVIOContext *io_ctx; struct AVFormatContext *format_ctx; AVCodecContext *codec_ctx; @@ -833,23 +828,18 @@ extract_audio (struct EXTRACTOR_ExtractContext *ec) AVCodec *codec; AVDictionary *options; AVFrame *frame; - AVCodecContext* output_codec_context = NULL; - - AVAudioResampleContext *resample_context = NULL; AVAudioFifo *fifo = NULL; int audio_stream_index; - int thumb_width; - int thumb_height; int i; int err; - int frame_finished; int duration; unsigned char *iob; - + + totalSize =0; if (NULL == (iob = av_malloc (16 * 1024))) @@ -982,7 +972,6 @@ extract_audio (struct EXTRACTOR_ExtractContext *ec) if (err >= 0) avcodec_flush_buffers (codec_ctx); - frame_finished = 0; /** @@ -1120,7 +1109,6 @@ extract_audio (struct EXTRACTOR_ExtractContext *ec) void EXTRACTOR_previewopus_extract_method (struct EXTRACTOR_ExtractContext *ec) { - unsigned int i; ssize_t iret; void *data; diff --git a/src/plugins/thumbnailffmpeg_extractor.c b/src/plugins/thumbnailffmpeg_extractor.c @@ -137,6 +137,29 @@ seek_cb (void *opaque, /** + * Encode just a frame, borrowed from libavcodec. + * + */ + #if LIBAVCODEC_BUILD >= AV_VERSION_INT(54,25,0) +static int encode_frame(AVCodecContext *c, AVFrame *frame) +{ + AVPacket pkt = { 0 }; + int ret, got_output; + + av_init_packet(&pkt); + av_init_packet(&pkt); + ret = avcodec_encode_video2(c, &pkt, frame, &got_output); + if (ret < 0) + return ret; + + ret = pkt.size; + av_free_packet(&pkt); + return ret; +} +#endif + + +/** * Rescale and encode a PNG thumbnail. * * @param src_width source image width @@ -264,9 +287,15 @@ create_thumbnail (int src_width, int src_height, sws_freeContext (scaler_ctx); return 0; } +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(54,25,0) + err = encode_frame (encoder_codec_ctx, dst_frame); +#else err = avcodec_encode_video (encoder_codec_ctx, encoder_output_buffer, encoder_output_buffer_size, dst_frame); + +#endif + av_dict_free (&opts); avcodec_close (encoder_codec_ctx); av_free (encoder_codec_ctx); @@ -327,13 +356,12 @@ calculate_thumbnail_dimensions (int src_width, #endif } -#if AV_VERSION_INT(54,25,0) > LIBAVUTIL_VERSION_INT -#define ENUM_CODEC_ID enum CodecID +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(54,25,0) + #define ENUM_CODEC_ID enum AVCodecID #else -#define ENUM_CODEC_ID enum AvCodecID + #define ENUM_CODEC_ID enum CodecID #endif - /** * Perform thumbnailing when the input is an image. * @@ -646,13 +674,25 @@ struct MIMEToDecoderMapping */ static const struct MIMEToDecoderMapping m2d_map[] = { - { "image/x-bmp", CODEC_ID_BMP }, + +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(54,25,0) + { "image/x-bmp", AV_CODEC_ID_BMP }, + { "image/gif", AV_CODEC_ID_GIF }, + { "image/jpeg", AV_CODEC_ID_MJPEG }, + { "image/png", AV_CODEC_ID_PNG }, + { "image/x-png", AV_CODEC_ID_PNG }, + { "image/x-portable-pixmap", AV_CODEC_ID_PPM }, + { NULL, AV_CODEC_ID_NONE } +#else + { "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 } +#endif + };