--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*
+ * 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}},
+};
+
--- /dev/null
+/*\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