OSDN Git Service

r224をそのままインポート.
authoryuki <yuki@c066991c-cf13-ec4a-a49a-846e61667af5>
Sat, 2 May 2009 08:38:51 +0000 (08:38 +0000)
committeryuki <yuki@c066991c-cf13-ec4a-a49a-846e61667af5>
Sat, 2 May 2009 08:38:51 +0000 (08:38 +0000)
git-svn-id: http://192.168.11.7/svn/saccubus/trunk@3 c066991c-cf13-ec4a-a49a-846e61667af5

libavfilter/avtool.c [new file with mode: 0644]
libavfilter/avtool.h [new file with mode: 0644]
libavfilter/common/framehook_ext.h [new file with mode: 0644]
libavfilter/vf_expand.c [new file with mode: 0644]
libavfilter/vf_vhext.c [new file with mode: 0644]

diff --git a/libavfilter/avtool.c b/libavfilter/avtool.c
new file mode 100644 (file)
index 0000000..0751fae
--- /dev/null
@@ -0,0 +1,32 @@
+/*\r
+ * avtool\r
+ * copyright (c) 2008 \83Õ\81i\83v\83T\83C\81j\r
+ *\r
+ * \82³\82«\82ã\82Î\82·\97p\82É\8ag\92£\82³\82ê\82½Vhook\83\89\83C\83u\83\89\83\8a\82©\82ç\r
+ * \8eg\82í\82ê\82é\83\89\83C\83u\83\89\83\8a\82Å\82·\81B\r
+ *\r
+ * \82±\82Ì\83t\83@\83C\83\8b\82Í\81u\82³\82«\82ã\82Î\82·\81v\82Ì\88ê\95\94\82Å\82 \82è\81A\r
+ * \82±\82Ì\83\\81[\83X\83R\81[\83h\82ÍGPL\83\89\83C\83Z\83\93\83X\82Å\94z\95z\82³\82ê\82Ü\82·\82Å\82·\81B\r
+ */\r
+#include <stdio.h>\r
+#include "common/framehook_ext.h"\r
+#include "avtool.h"\r
+\r
+static toolbox Box = {\r
+       .version = TOOLBOX_VERSION,\r
+       .video_length = 0.0f\r
+};\r
+\r
+/* \82±\82¿\82ç\82Íffmpeg\91¤\82©\82ç\8cÄ\82Î\82ê\82é\8aÖ\90\94 */\r
+\r
+int tool_registerInfo(AVFormatContext *in_file,int64_t rec_time){\r
+       if(in_file->duration > rec_time && rec_time > 0){\r
+               Box.video_length = ((double)rec_time) / AV_TIME_BASE;\r
+       }\r
+       Box.video_length = ((double)in_file->duration)/AV_TIME_BASE;\r
+       return 0;\r
+}\r
+\r
+const toolbox* tool_getToolBox(){\r
+       return &Box;\r
+}\r
diff --git a/libavfilter/avtool.h b/libavfilter/avtool.h
new file mode 100644 (file)
index 0000000..cb645c4
--- /dev/null
@@ -0,0 +1,19 @@
+/*\r
+ * avtool\r
+ * copyright (c) 2008 \83Õ\81i\83v\83T\83C\81j\r
+ *\r
+ * \82³\82«\82ã\82Î\82·\97p\82É\8ag\92£\82³\82ê\82½FFmpeg\82©\82ç\r
+ * \8eg\82í\82ê\82é\83\89\83C\83u\83\89\83\8a\82Å\82·\81B\r
+ *\r
+ * \82±\82Ì\83t\83@\83C\83\8b\82Í\81u\82³\82«\82ã\82Î\82·\81v\82Ì\88ê\95\94\82Å\82 \82è\81A\r
+ * \82±\82Ì\83\\81[\83X\83R\81[\83h\82ÍGPL\83\89\83C\83Z\83\93\83X\82Å\94z\95z\82³\82ê\82Ü\82·\82Å\82·\81B\r
+ */\r
+#ifndef SACCUBUS_AVINFO_H\r
+#define SACCUBUS_AVINFO_H\r
+#include "common/framehook_ext.h"\r
+#include <libavformat/avformat.h>\r
+\r
+int tool_registerInfo(AVFormatContext *in_file,int64_t rec_time);\r
+const toolbox* tool_getToolBox();\r
+\r
+#endif /* SACCUBUS_AVINFO_H */\r
diff --git a/libavfilter/common/framehook_ext.h b/libavfilter/common/framehook_ext.h
new file mode 100644 (file)
index 0000000..ca55b5a
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+ * \8ag\92£Vhook\83t\83B\83\8b\83^\r
+ * copyright (c) 2008 \83Õ\81i\83v\83T\83C\81j\r
+ *\r
+ * \82³\82«\82ã\82Î\82·\97p\82É\8ag\92£\82³\82ê\82½Vhook\83\89\83C\83u\83\89\83\8a\82ð\r
+ * \83r\83\8b\83h\82·\82é\82½\82ß\82Ì\83w\83b\83_\82Å\82·\81B\r
+ *\r
+ * \82±\82Ì\83t\83@\83C\83\8b\82Í\81u\82³\82«\82ã\82Î\82·\81v\82Ì\88ê\95\94\82Å\82 \82è\81A\r
+ * \82±\82Ì\83\\81[\83X\83R\81[\83h\82ÍGPL\83\89\83C\83Z\83\93\83X\82Å\94z\95z\82³\82ê\82Ü\82·\82Å\82·\81B\r
+ */\r
+#ifndef SACCUBUS_VF_VHEXT_H\r
+#define SACCUBUS_VF_VHEXT_H\r
+/*\r
+ * \83c\81[\83\8b\83{\83b\83N\83X\82Ì\83o\81[\83W\83\87\83\93\r
+ * DLL\82Ì\92\86\82Å\8am\94F\82µ\82Æ\82¢\82½\95û\82ª\82¢\82¢\81B\r
+ */\r
+#define TOOLBOX_VERSION 2\r
+\r
+/*\r
+ * \8cÄ\82Î\82ê\82é\82Æ\82«\82É\88ê\8f\8f\82É\82Â\82¢\82Ä\82­\82étoolbox.\r
+ * \82±\82±\82©\82ç\93®\89æ\82Ì\8fî\95ñ\82È\82ñ\82©\82à\8eæ\93¾\82Å\82«\82é\81B\r
+ */\r
+typedef struct toolbox{\r
+       //\83o\81[\83W\83\87\83\93\r
+       int version;\r
+       double video_length;\r
+} toolbox;\r
+\r
+typedef struct vhext_frame{\r
+       void *data;\r
+       int linesize;\r
+       int w;\r
+       int h;\r
+       double pts;\r
+} vhext_frame;\r
+\r
+\r
+/*\r
+ * \8ag\92£vhook\83\89\83C\83u\83\89\83\8a\97p\8aÖ\90\94\8cQ\92è\8b`\r
+ */\r
+\r
+//configure\97p\r
+typedef int (FrameHookExtConfigure)(void **ctxp,const toolbox *tbox, int argc, char *argv[]);\r
+typedef FrameHookExtConfigure *FrameHookExtConfigureFn;\r
+extern FrameHookExtConfigure ExtConfigure;\r
+\r
+//\83t\83\8c\81[\83\80\97p\r
+typedef void (FrameHookExtProcess)(void *ctx,const toolbox *tbox,vhext_frame *pict);\r
+typedef FrameHookExtProcess *FrameHookExtProcessFn;\r
+extern FrameHookExtProcess ExtProcess;\r
+\r
+//\8fI\97¹\8e\9e\82É\8cÄ\82Ô\r
+typedef void (FrameHookExtRelease)(void *ctx,const toolbox *tbox);\r
+typedef FrameHookExtRelease *FrameHookExtReleaseFn;\r
+extern FrameHookExtRelease ExtRelease;\r
+\r
+#endif /* SACCUBUS_VF_VHEXT_H */\r
diff --git a/libavfilter/vf_expand.c b/libavfilter/vf_expand.c
new file mode 100644 (file)
index 0000000..3239ff0
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * video expand filter (alternative to pad syntax)
+ * copyright (c) 2008 Ryo Hirafuji <http://ledyba.ddo.jp/>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+
+#include "avfilter.h"
+#define INDEX_X 0
+#define INDEX_Y 1
+#define INDEX_MAX 2
+
+typedef struct{
+       int size[INDEX_MAX];
+       int offset[INDEX_MAX];
+    int shift[INDEX_MAX];
+
+    int osd; ///< checked, but not used in this version.
+    double aspect;
+    int round;
+
+    int bpp;                ///< bytes per pixel
+    int is_yuv;
+} ExpandContext;
+
+static int init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+    ExpandContext *expand = ctx->priv;
+    int i;
+
+    /* default parameters */
+       for(i=0;i<INDEX_MAX;i++){
+           expand->offset[i] =  -1;
+           expand->size[i] = -1;
+           expand->shift[i] = 0;
+       }
+    expand->osd = 0;
+    expand->aspect = 0.0f;
+    expand->round = 0;
+
+    expand->bpp = 0;
+    expand->is_yuv = 0;
+
+    if(args){
+        int length = strlen(args);
+        char* osd_tmp = av_malloc(length);
+        char* aspect_tmp = av_malloc(length);
+        if(!osd_tmp || !aspect_tmp){
+               av_log(ctx, AV_LOG_ERROR, "Failed to malloc.\n");
+        }
+
+        sscanf(args,"%d:%d:%d:%d:%255[^:]:%255[^:]:%d",
+                       &expand->size[INDEX_X],&expand->size[INDEX_Y],&expand->offset[INDEX_X],&expand->offset[INDEX_Y],
+                       osd_tmp,aspect_tmp,&expand->round
+               );
+
+        if(osd_tmp && strlen(osd_tmp) > 0){ //checked, but not used in this version.
+            if(!strncmp(osd_tmp,"true",4)){
+                expand->osd = 1;
+            }else{
+                expand->osd = atoi(osd_tmp);
+            }
+        }
+
+        if(aspect_tmp && strlen(aspect_tmp) > 0){
+            char* cp = strchr(aspect_tmp, '/');
+            if(cp){ // rational
+                AVRational rat;
+                char* cpp;
+                rat.num = strtol(aspect_tmp, &cpp, 10);
+                if(cpp != aspect_tmp || cpp == cp){
+                    rat.den = strtol(cp+1, &cpp, 10);
+                }else{
+                    rat.num = 0;
+                }
+                if(rat.num && rat.den){
+                    double eval = ((double)rat.num) / rat.den;
+                    if(eval > 0.0f){
+                        expand->aspect = eval;
+                    }
+                }
+            }else{ // double
+                double eval = strtod(aspect_tmp, 0);
+                if(eval > 0.0f){
+                    expand->aspect = eval;
+                }
+            }
+        }
+
+        av_log(ctx, AV_LOG_INFO, "Expand: %dx%d , (%d,%d) , osd: %d, aspect: %lf, round: %d\n",
+        expand->size[INDEX_X], expand->size[INDEX_Y], expand->offset[INDEX_X], expand->offset[INDEX_Y], expand->osd, expand->aspect, expand->round);
+
+        av_free(osd_tmp);
+        av_free(aspect_tmp);
+    }
+
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx){
+    avfilter_set_common_formats(ctx,avfilter_make_format_list(30, // out of 38
+         PIX_FMT_YUV420P,
+         PIX_FMT_YUV422P,
+         PIX_FMT_YUV444P,
+         PIX_FMT_YUV410P,
+         PIX_FMT_YUV411P,
+         PIX_FMT_YUV440P,
+         PIX_FMT_YUVJ420P,
+         PIX_FMT_YUVJ422P,
+         PIX_FMT_YUVJ444P,
+         PIX_FMT_YUVJ440P,
+         PIX_FMT_YUVA420P,
+         PIX_FMT_NV12,
+         PIX_FMT_NV21,
+         PIX_FMT_RGB24,
+         PIX_FMT_BGR24,
+         PIX_FMT_RGB32,
+         PIX_FMT_BGR32,
+         PIX_FMT_RGB32_1,
+         PIX_FMT_BGR32_1,
+         PIX_FMT_GRAY16BE,
+         PIX_FMT_GRAY16LE,
+         PIX_FMT_BGR555,
+         PIX_FMT_BGR565,
+         PIX_FMT_RGB555,
+         PIX_FMT_RGB565,
+         //PIX_FMT_YUYV422, // not supported.
+         //PIX_FMT_UYVY422, // not supported.
+         //PIX_FMT_UYYVYY411, // not supported.
+         PIX_FMT_RGB8,
+         PIX_FMT_BGR8,
+         PIX_FMT_RGB4_BYTE,
+         PIX_FMT_BGR4_BYTE,
+         PIX_FMT_GRAY8
+         //PIX_FMT_RGB4, //not supported
+         //PIX_FMT_BGR4, //not supported
+         //PIX_FMT_MONOWHITE, // not supported
+         //PIX_FMT_MONOBLACK, // not supported
+         //PIX_FMT_PAL8, // not supported
+    ));
+    return 0;
+}
+
+
+static int config_input(AVFilterLink *link)
+{
+    ExpandContext *expand = link->dst->priv;
+    int i;
+    int size[INDEX_MAX];
+
+    size[INDEX_X] = link->w;
+    size[INDEX_Y] = link->h;
+
+       for(i=0;i<INDEX_MAX;i++){
+           if (expand->size[i] == -1){
+               expand->size[i]=size[i];
+           } else if (expand->size[i] < -1){
+               expand->size[i]=size[i] - expand->size[i];
+           } else if (expand->size[INDEX_X] < size[i]){
+               expand->size[i]=size[i];
+           }
+       }
+
+    if (expand->aspect > 0.0f) {
+        if (expand->size[INDEX_Y] < (expand->size[INDEX_X] / expand->aspect)) {
+            expand->size[INDEX_Y] = (expand->size[INDEX_X] / expand->aspect) + 0.5;
+        } else {
+            expand->size[INDEX_X] = (expand->size[INDEX_Y] * expand->aspect) + 0.5;
+        }
+    }
+
+       for(i=0;i<INDEX_MAX;i++){
+           if (expand->round > 1) {
+               expand->size[i] = (1+(expand->size[i]-1)/expand->round)*expand->round;
+           }
+           if(expand->offset[i] < 0 || (expand->offset[i]+size[i]) > expand->size[i]){
+               expand->offset[i] = (expand->size[INDEX_X] - size[i])>>1;
+           }
+       }
+
+    avcodec_get_chroma_sub_sample(link->format, &expand->shift[INDEX_X], &expand->shift[INDEX_Y]);
+    for(i=0;i<INDEX_MAX;i++){
+           expand->offset[i] &= ~((1 << expand->shift[i]) - 1);
+           expand->size[i] &= ~((1 << expand->shift[i]) - 1);
+    }
+
+    switch(link->format) {
+        case PIX_FMT_YUV420P:
+        case PIX_FMT_YUV422P:
+        case PIX_FMT_YUV444P:
+        case PIX_FMT_YUV410P:
+        case PIX_FMT_YUV411P:
+        case PIX_FMT_YUV440P:
+        case PIX_FMT_YUVJ420P:
+        case PIX_FMT_YUVJ422P:
+        case PIX_FMT_YUVJ444P:
+        case PIX_FMT_YUVJ440P:
+        case PIX_FMT_YUVA420P:
+        case PIX_FMT_NV12:
+        case PIX_FMT_NV21:
+            expand->is_yuv = 1;
+        case PIX_FMT_RGB8:
+        case PIX_FMT_BGR8:
+        case PIX_FMT_RGB4_BYTE:
+        case PIX_FMT_BGR4_BYTE:
+        case PIX_FMT_GRAY8:
+            expand->bpp = 1;
+            break;
+        case PIX_FMT_RGB24:
+        case PIX_FMT_BGR24:
+            expand->bpp = 3;
+            break;
+        case PIX_FMT_RGB32:
+        case PIX_FMT_BGR32:
+        case PIX_FMT_RGB32_1:
+        case PIX_FMT_BGR32_1:
+            expand->bpp = 4;
+            break;
+        case PIX_FMT_GRAY16BE:
+        case PIX_FMT_GRAY16LE:
+        case PIX_FMT_BGR555:
+        case PIX_FMT_BGR565:
+        case PIX_FMT_RGB555:
+        case PIX_FMT_RGB565:
+            expand->bpp = 2;
+            break;
+        // not supported.
+        //case PIX_FMT_YUYV422:
+        //case PIX_FMT_UYVY422:
+        //case PIX_FMT_UYYVYY411:
+        //case PIX_FMT_RGB4:
+        //case PIX_FMT_BGR4:
+        //case PIX_FMT_MONOWHITE:
+        //case PIX_FMT_MONOBLACK:
+        //case PIX_FMT_PAL8:
+        default: // invalid or not supported format
+            return -1;
+    }
+
+    return 0;
+}
+
+static int config_output(AVFilterLink *link)
+{
+    ExpandContext *expand = link->src->priv;
+
+    link->w = expand->size[INDEX_X];
+    link->h = expand->size[INDEX_Y];
+
+    return 0;
+}
+
+static void start_frame(AVFilterLink *link, AVFilterPicRef *picref)
+{
+    AVFilterLink *out = link->dst->outputs[0];
+    out->outpic       = avfilter_get_video_buffer(out, AV_PERM_WRITE);
+    out->outpic->pts  = picref->pts;
+    avfilter_start_frame(out, avfilter_ref_pic(out->outpic, ~0));
+}
+
+static void draw_slice(AVFilterLink *link, int y, int h)
+{
+    ExpandContext *expand = link->dst->priv;
+    AVFilterPicRef *outpic = link->dst->outputs[0]->outpic;
+    AVFilterPicRef *inpic = link->cur_pic;
+    int i;
+    int is_first = (y <= 0);
+    int is_end = (y+h >= inpic->h);
+
+    for(i=0;i<4;i++) {
+        if(outpic->data[i]) {
+            int j;
+            char* out_buff = outpic->data[i];
+            const char* in_buff  = inpic->data[i];
+
+            int copy_length;
+            int y_add;
+            int padcolor;
+            int x_shift,y_shift;
+
+            if(!expand->is_yuv || i == 3){ // not YUV, or alpha channel of YUVA
+                padcolor = 0;
+                x_shift = y_shift = 0;
+            }else{
+                padcolor = (i == 0) ? 16 : 128;
+                x_shift = (i == 0) ? 0 : expand->shift[INDEX_X];
+                y_shift = (i == 0) ? 0 : expand->shift[INDEX_Y];
+            }
+
+            copy_length = (inpic->w >> x_shift) * expand->bpp;
+            y_add = 1<<y_shift;
+
+            if(is_first){
+                int size = (expand->offset[INDEX_Y] >> y_shift) * outpic->linesize[i];
+                memset(out_buff,padcolor,size);
+                out_buff += size;
+            }else{
+                int y_skip = expand->offset[INDEX_Y] >> y_shift;
+                out_buff += outpic->linesize[i] * y_skip;
+                in_buff += inpic->linesize[i] * y_skip;
+            }
+
+            for(j=0;j<h;j+=y_add){
+                int size,total_size = 0;
+                size = (expand->offset[INDEX_X] >> x_shift) * expand->bpp;
+                memset(out_buff,padcolor,size);
+                out_buff += size;
+                total_size += size;
+
+                memcpy(out_buff,in_buff,copy_length);
+                out_buff += copy_length;
+                total_size += copy_length;
+
+                size = outpic->linesize[i]-total_size;
+                memset(out_buff,padcolor,size);
+                out_buff += size;
+
+                in_buff += inpic->linesize[i];
+            }
+
+            if(is_end){
+                memset(out_buff,padcolor,((outpic->h-expand->offset[INDEX_Y]-inpic->h) >> y_shift) * outpic->linesize[i]);
+            }
+
+        }
+    }
+    if(is_first && is_end){
+        avfilter_draw_slice(link->dst->outputs[0], 0, outpic->h);
+    }else if(is_first){
+        avfilter_draw_slice(link->dst->outputs[0], 0, expand->offset[INDEX_Y] + h);
+    }else if(is_end){
+        avfilter_draw_slice(link->dst->outputs[0], expand->offset[INDEX_Y] + y, outpic->h - expand->offset[INDEX_Y] - y);
+    }else{
+        avfilter_draw_slice(link->dst->outputs[0], expand->offset[INDEX_Y] + y, h);
+    }
+}
+
+AVFilter avfilter_vf_expand = {
+    .name      = "expand",
+    .priv_size = sizeof(ExpandContext),
+
+    .init      = init,
+    .query_formats   = query_formats,
+
+    .inputs    = (AVFilterPad[]) {{ .name            = "default",
+                                    .type            = CODEC_TYPE_VIDEO,
+                                    .start_frame     = start_frame,
+                                    .draw_slice      = draw_slice,
+                                    .config_props    = config_input, },
+                                  { .name = NULL}},
+    .outputs   = (AVFilterPad[]) {{ .name            = "default",
+                                    .type            = CODEC_TYPE_VIDEO,
+                                    .config_props    = config_output, },
+                                  { .name = NULL}},
+};
+
diff --git a/libavfilter/vf_vhext.c b/libavfilter/vf_vhext.c
new file mode 100644 (file)
index 0000000..317d0d7
--- /dev/null
@@ -0,0 +1,255 @@
+/*\r
+ * \8ag\92£Vhook\83t\83B\83\8b\83^\r
+ * copyright (c) 2008 \83Õ\81i\83v\83T\83C\81j\r
+ *\r
+ * \82³\82«\82ã\82Î\82·\97p\82É\8ag\92£\82³\82ê\82½Vhook\83\89\83C\83u\83\89\83\8a\82ð\r
+ * \8bì\93®\82³\82¹\82é\82½\82ß\82Ì\83t\83B\83\8b\83^\82Å\82·\81B\r
+ *\r
+ * \82±\82Ì\83t\83@\83C\83\8b\82Í\81u\82³\82«\82ã\82Î\82·\81v\82Ì\88ê\95\94\82Å\82 \82è\81A\r
+ * \82±\82Ì\83\\81[\83X\83R\81[\83h\82ÍGPL\83\89\83C\83Z\83\93\83X\82Å\94z\95z\82³\82ê\82Ü\82·\82Å\82·\81B\r
+ */\r
+#include "avfilter.h"\r
+#include "common/framehook_ext.h"\r
+#include "avtool.h"\r
+#include <string.h>\r
+#include <stdio.h>\r
+#include <ctype.h>\r
+\r
+#ifdef HAVE_DLFCN_H\r
+#include <dlfcn.h>\r
+#else\r
+//dlfcn.h\82Ì\96³\82¢Windows Mingw\8aÂ\8b«\97p\r
+#define dlopen(a) ((void*)LoadLibrary(a))\r
+#define dlsym(a,b) ((void*)GetProcAddress((HMODULE)(a),(b)))\r
+#define dlclose(a) FreeLibrary((HMODULE)(a));\r
+#endif\r
+\r
+//\83f\83\8a\83~\83^\81BMEncoder\91¤\82Æ\82Í\93¯\82\82É\82µ\82Æ\82¢\82½\95û\82ª\82æ\82³\82»\82¤\81B\r
+#define VHEXT_DELIM '|'\r
+\r
+typedef struct{\r
+       //\88ø\90\94\82Í\82 \82Æ\82 \82Æ\8eg\82¤\82Ì\82Å\8am\95Û\81B\r
+       char* args;\r
+       char** argv;\r
+       int argc;\r
+       //\83c\81[\83\8b\83{\83b\83N\83X\r
+       const toolbox* Box;\r
+       //\83_\83C\83i\83~\83b\83N\83\89\83C\83u\83\89\83\8a\82Ö\82Ì\83|\83C\83\93\83^\r
+       void* Dynamic;\r
+       //\8aÖ\90\94\82Ö\82Ì\83|\83C\83\93\83^\r
+       FrameHookExtConfigureFn ExtConfigure;\r
+       FrameHookExtProcessFn ExtProcess;\r
+       FrameHookExtReleaseFn ExtRelease;\r
+       //FrameHook\82Ì\8eg\82¤\83|\83C\83\93\83^\r
+       void* Context;\r
+} Context;\r
+\r
+/*\r
+ * \82±\82Ì\92\86\82Å\82¾\82¯\8eg\82¤\8aÖ\90\94\92è\8b`\r
+ */\r
+\r
+char** split(char* str,int str_len,int* argc,char delim);\r
+int decode(char* s,int len);\r
+\r
+/*\r
+ *  AVFilter\8d\\91¢\91Ì\82É\8ai\94[\82³\82ê\82é\8aÖ\90\94\8cQ\r
+ */\r
+\r
+static int init(AVFilterContext *ctx, const char *args, void *opaque){\r
+       //Context\82ð\82Æ\82è\82 \82¦\82¸\8am\95Û\r
+    Context *context= ctx->priv;\r
+    av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]called with args = %s.\n",args);\r
+\r
+       //\88ø\90\94\82ªNULL\82È\82Ì\82Í\82¨\82©\82µ\82¢\r
+    if(!args) {\r
+        av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Invalid arguments.\n");\r
+        return -1;\r
+    }\r
+    int arg_len = strlen(args);\r
+    //\88ø\90\94\82Ì\83R\83s\81[\r
+    context->args = (char*)av_malloc(arg_len+1);\r
+    if(!context->args){\r
+        av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to malloc memory for args.\n");\r
+       return -1;\r
+    }\r
+    memcpy(context->args,args,arg_len);\r
+    context->args[arg_len]='\0';//NULL\82Å\8dÅ\8cã\82ð\96\84\82ß\82é\81B\r
+\r
+       //\83f\83R\81[\83h\r
+       decode(context->args,arg_len);\r
+       //\88ø\90\94\82Ì\93W\8aJ\r
+       context->argv = split(context->args,arg_len,&context->argc,VHEXT_DELIM);\r
+       if(!context->argv){\r
+        av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to split args.\n");\r
+       return -1;\r
+       }\r
+\r
+       //\83c\81[\83\8b\83{\83b\83N\83X\82ð\8eæ\93¾\r
+       context->Box = tool_getToolBox();\r
+       if(!context->Box){\r
+        av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to get ToolBox.\n");\r
+        return -1;\r
+       }\r
+\r
+       //DLL\93Ç\82Ý\8d\9e\82Ý\r
+    context->Dynamic = dlopen(context->argv[0], RTLD_NOW);\r
+    if (!context->Dynamic) {\r
+        av_log(NULL, AV_LOG_ERROR, "[libavfilter/VhookExt Filter][Lib:%s]Failed to open lib: %s\nMSG:%s\n",context->argv[0],context->argv[0], dlerror());\r
+        return -1;\r
+    }\r
+       //\8ae\8aÖ\90\94\82ð\8eæ\93¾\r
+       context->ExtConfigure = dlsym(context->Dynamic, "ExtConfigure");\r
+       context->ExtProcess = dlsym(context->Dynamic, "ExtProcess");\r
+       context->ExtRelease = dlsym(context->Dynamic, "ExtRelease");\r
+       if(!context->ExtConfigure){\r
+        av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to get ExtConfigure.\n");\r
+        return -1;\r
+       }\r
+       if(!context->ExtProcess){\r
+        av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to get ExtProcess.\n");\r
+        return -1;\r
+       }\r
+       if(!context->ExtRelease){\r
+        av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to get ExtRelease.\n");\r
+        return -1;\r
+       }\r
+\r
+       //Configure\82ð\8cÄ\82Ñ\8fo\82·\r
+       int code;\r
+       if((code = context->ExtConfigure(&context->Context,context->Box,context->argc,context->argv))){\r
+        av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to configure.Code:%d\n",code);\r
+        return -1;\r
+       }\r
+    return 0;\r
+}\r
+\r
+static void uninit(AVFilterContext *ctx){\r
+       //Context\82ð\82Æ\82è\82 \82¦\82¸\8am\95Û\r
+    Context *context= ctx->priv;\r
+    //\8aJ\95ú\82·\82é\81B\r
+       context->ExtRelease(context->Context,context->Box);\r
+    //\88ø\90\94\82à\8aJ\95ú\82·\82é\81B\r
+    if(!context->args){\r
+       av_free(context->args);\r
+    }\r
+    if(!context->argv){\r
+       av_free(context->argv);\r
+    }\r
+    //DLL\82à\95Â\82\82é\r
+    dlclose(context->Dynamic);\r
+}\r
+\r
+static int query_formats(AVFilterContext *ctx){\r
+       //SDL\82Å\8eg\82¢\82â\82·\82­\82·\82é\82½\82ß\82ÉRGB24\83t\83H\81[\83}\83b\83g\82ð\97v\8b\81\82·\82é\81B\r
+    avfilter_set_common_formats(ctx,avfilter_make_format_list(1,PIX_FMT_RGB24));\r
+    return 0;\r
+}\r
+\r
+/*\r
+ * AVFilterPad\82ÌInput\91¤\82É\8cÄ\82Î\82ê\82é\8aÖ\90\94\r
+ */\r
+\r
+static void start_frame(AVFilterLink *link, AVFilterPicRef *picref){\r
+       //\82¨\82Ü\82\82È\82¢\r
+    avfilter_start_frame(link->dst->outputs[0], picref);\r
+}\r
+\r
+static void end_frame(AVFilterLink *link){\r
+       //\83|\83C\83\93\83^\82Í\8aî\96{\r
+    Context *context = link->dst->priv;\r
+    //\82æ\82­\82í\82©\82ç\82È\82¢\82¯\82Ç\82Æ\82è\82 \82¦\82¸\82¨\82Ü\82\82È\82¢\81i\82¦\81[\r
+    AVFilterLink* output = link->dst->outputs[0];\r
+    AVFilterPicRef *pic = link->cur_pic;\r
+    //\93Æ\8e©\8d\\91¢\91Ì\82É\91ã\93ü\r
+    vhext_frame frame;\r
+    frame.data = pic->data[0];\r
+    frame.linesize = pic->linesize[0];\r
+    frame.w = pic->w;\r
+    frame.h = pic->h;\r
+    frame.pts = ((double)pic->pts) / AV_TIME_BASE;\r
+       //\83\89\83C\83u\83\89\83\8a\82ð\8cÄ\82Ñ\8fo\82·\81B\r
+       context->ExtProcess(context->Context,context->Box,&frame);\r
+\r
+    //\82¨\82È\82\82­\82¨\82È\82\82Ü\82¢\81i\82¦\82¦\82¦\r
+    avfilter_draw_slice(output, 0, pic->h);\r
+    avfilter_end_frame(output);\r
+}\r
+\r
+AVFilter avfilter_vf_vhext=\r
+{\r
+    .name      = "vhext",\r
+\r
+    .priv_size = sizeof(Context),\r
+\r
+    .init      = init,\r
+    .uninit    = uninit,\r
+\r
+    .query_formats   = query_formats,\r
+    .inputs    = (AVFilterPad[]) {{ .name            = "default",\r
+                                    .type            = CODEC_TYPE_VIDEO,\r
+                                    .start_frame     = start_frame,\r
+                                    .end_frame       = end_frame,\r
+                                    .min_perms       = AV_PERM_WRITE |\r
+                                                       AV_PERM_READ,\r
+                                    .rej_perms       = AV_PERM_REUSE |\r
+                                                       AV_PERM_REUSE2},\r
+                                  { .name = NULL}},\r
+    .outputs   = (AVFilterPad[]) {{ .name            = "default",\r
+                                    .type            = CODEC_TYPE_VIDEO, },\r
+                                  { .name = NULL}},\r
+};\r
+\r
+/*\r
+ * \82±\82Ì\92\86\82Å\82Ì\82Ý\8eg\82í\82ê\82é\8aÖ\90\94\r
+ */\r
+\r
+//\95\8e\9a\97ñ\82ð\93Á\92è\82Ì\95\8e\9a\82É\82æ\82Á\82Ä\95ª\82¯\82Ü\82·\81B\r
+char** split(char* str,int str_len,int* argc,char delim){\r
+       //\83`\83F\83b\83N\r
+       if(!str || delim=='\0' || str_len < 0){\r
+               return 0;\r
+       }\r
+       //\8am\95Û\r
+       char** argv = av_malloc(sizeof(char*));\r
+       if(!argv){\r
+               return 0;\r
+       }\r
+       //\83\8b\81[\83v\8aJ\8en\r
+       int last = 0;\r
+       int i;\r
+       int arg_cnt = 0;\r
+       for(i=0;i<str_len;i++){\r
+               if(str[i] == delim){//\83f\83\8a\83~\83^\82É\92B\82µ\82½\r
+                       str[i] = '\0';\r
+                       argv[arg_cnt] = &str[last];\r
+                       arg_cnt++;\r
+                       last = i+1;\r
+                       argv = av_realloc(argv,sizeof(char*) * (arg_cnt+1));\r
+               }\r
+       }\r
+       argv[arg_cnt] = &str[last];\r
+       *argc = arg_cnt + 1;\r
+       return argv;\r
+}\r
+\r
+//UR\83G\83\93\83R\81[\83h\8bL\96@\82ª\8eg\82¦\82Ü\82·\81B\r
+int decode(char* s,int len){\r
+        int i,j;\r
+        char buf,*s1;\r
+        if(len==0)return(-1);\r
+        s1=(char*)av_malloc(len);\r
+        for(i=0,j=0;i<len;i++,j++)\r
+        {\r
+                if(s[i]=='+'){s1[j]=' ';continue;}\r
+                if(s[i]!='%') {s1[j]=s[i];continue;}\r
+                buf=((s[++i]>='A') ? s[i]-'A'+10 : s[i]-'0');\r
+                buf*=16;\r
+                buf+=((s[++i]>='A') ? s[i]-'A'+10 : s[i]-'0');\r
+                s1[j]=buf;\r
+        }\r
+        for(i=0;i<j;i++) s[i]=s1[i];\r
+        s[i]='\0';\r
+        av_free(s1);\r
+        return(0);\r
+}\r
+\r