OSDN Git Service

ffmpegオプションパネルのイベント処理
[coroid/inqubus.git] / ffmpeg_extension / libavfilter / vf_vhext.c
1 /*\r
2  * \8ag\92£Vhook\83t\83B\83\8b\83^\r
3  * copyright (c) 2008 \83Õ\81i\83v\83T\83C\81j\r
4  *\r
5  * \82³\82«\82ã\82Î\82·\97p\82É\8ag\92£\82³\82ê\82½Vhook\83\89\83C\83u\83\89\83\8a\82ð\r
6  * \8bì\93®\82³\82¹\82é\82½\82ß\82Ì\83t\83B\83\8b\83^\82Å\82·\81B\r
7  *\r
8  * \82±\82Ì\83t\83@\83C\83\8b\82Í\81u\82³\82«\82ã\82Î\82·\81v\82Ì\88ê\95\94\82Å\82 \82è\81A\r
9  * \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
10  */\r
11 #include "avfilter.h"\r
12 #include "common/framehook_ext.h"\r
13 #include "avtool.h"\r
14 #include <string.h>\r
15 #include <stdio.h>\r
16 #include <ctype.h>\r
17 \r
18 #ifdef HAVE_DLFCN_H\r
19 #include <dlfcn.h>\r
20 #else\r
21 //dlfcn.h\82Ì\96³\82¢Windows Mingw\8aÂ\8b«\97p\r
22 #define dlopen(a) ((void*)LoadLibrary(a))\r
23 #define dlsym(a,b) ((void*)GetProcAddress((HMODULE)(a),(b)))\r
24 #define dlclose(a) FreeLibrary((HMODULE)(a));\r
25 #endif\r
26 \r
27 //\83f\83\8a\83~\83^\81BMEncoder\91¤\82Æ\82Í\93¯\82\82É\82µ\82Æ\82¢\82½\95û\82ª\82æ\82³\82»\82¤\81B\r
28 #define VHEXT_DELIM '|'\r
29 \r
30 typedef struct{\r
31         //\88ø\90\94\82Í\82 \82Æ\82 \82Æ\8eg\82¤\82Ì\82Å\8am\95Û\81B\r
32         char* args;\r
33         char** argv;\r
34         int argc;\r
35         //\83c\81[\83\8b\83{\83b\83N\83X\r
36         const toolbox* Box;\r
37         //\83_\83C\83i\83~\83b\83N\83\89\83C\83u\83\89\83\8a\82Ö\82Ì\83|\83C\83\93\83^\r
38         void* Dynamic;\r
39         //\8aÖ\90\94\82Ö\82Ì\83|\83C\83\93\83^\r
40         FrameHookExtConfigureFn ExtConfigure;\r
41         FrameHookExtProcessFn ExtProcess;\r
42         FrameHookExtReleaseFn ExtRelease;\r
43         //FrameHook\82Ì\8eg\82¤\83|\83C\83\93\83^\r
44         void* Context;\r
45 } Context;\r
46 \r
47 /*\r
48  * \82±\82Ì\92\86\82Å\82¾\82¯\8eg\82¤\8aÖ\90\94\92è\8b`\r
49  */\r
50 \r
51 char** split(char* str,int str_len,int* argc,char delim);\r
52 int decode(char* s,int len);\r
53 \r
54 /*\r
55  *  AVFilter\8d\\91¢\91Ì\82É\8ai\94[\82³\82ê\82é\8aÖ\90\94\8cQ\r
56  */\r
57 \r
58 static int init(AVFilterContext *ctx, const char *args, void *opaque){\r
59         //Context\82ð\82Æ\82è\82 \82¦\82¸\8am\95Û\r
60     Context *context= ctx->priv;\r
61     av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]called with args = %s.\n",args);\r
62 \r
63         //\88ø\90\94\82ªNULL\82È\82Ì\82Í\82¨\82©\82µ\82¢\r
64     if(!args) {\r
65         av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Invalid arguments.\n");\r
66         return -1;\r
67     }\r
68     int arg_len = strlen(args);\r
69     //\88ø\90\94\82Ì\83R\83s\81[\r
70     context->args = (char*)av_malloc(arg_len+1);\r
71     if(!context->args){\r
72         av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to malloc memory for args.\n");\r
73         return -1;\r
74     }\r
75     memcpy(context->args,args,arg_len);\r
76     context->args[arg_len]='\0';//NULL\82Å\8dÅ\8cã\82ð\96\84\82ß\82é\81B\r
77 \r
78         //\83f\83R\81[\83h\r
79         decode(context->args,arg_len);\r
80         //\88ø\90\94\82Ì\93W\8aJ\r
81         context->argv = split(context->args,arg_len,&context->argc,VHEXT_DELIM);\r
82         if(!context->argv){\r
83         av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to split args.\n");\r
84         return -1;\r
85         }\r
86 \r
87         //\83c\81[\83\8b\83{\83b\83N\83X\82ð\8eæ\93¾\r
88         context->Box = tool_getToolBox();\r
89         if(!context->Box){\r
90         av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to get ToolBox.\n");\r
91         return -1;\r
92         }\r
93 \r
94         //DLL\93Ç\82Ý\8d\9e\82Ý\r
95     context->Dynamic = dlopen(context->argv[0], RTLD_NOW);\r
96     if (!context->Dynamic) {\r
97         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
98         return -1;\r
99     }\r
100         //\8ae\8aÖ\90\94\82ð\8eæ\93¾\r
101         context->ExtConfigure = dlsym(context->Dynamic, "ExtConfigure");\r
102         context->ExtProcess = dlsym(context->Dynamic, "ExtProcess");\r
103         context->ExtRelease = dlsym(context->Dynamic, "ExtRelease");\r
104         if(!context->ExtConfigure){\r
105         av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to get ExtConfigure.\n");\r
106         return -1;\r
107         }\r
108         if(!context->ExtProcess){\r
109         av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to get ExtProcess.\n");\r
110         return -1;\r
111         }\r
112         if(!context->ExtRelease){\r
113         av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to get ExtRelease.\n");\r
114         return -1;\r
115         }\r
116 \r
117         //Configure\82ð\8cÄ\82Ñ\8fo\82·\r
118         int code;\r
119         if((code = context->ExtConfigure(&context->Context,context->Box,context->argc,context->argv))){\r
120         av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to configure.Code:%d\n",code);\r
121         return -1;\r
122         }\r
123     return 0;\r
124 }\r
125 \r
126 static void uninit(AVFilterContext *ctx){\r
127         //Context\82ð\82Æ\82è\82 \82¦\82¸\8am\95Û\r
128     Context *context= ctx->priv;\r
129     //\8aJ\95ú\82·\82é\81B\r
130         context->ExtRelease(context->Context,context->Box);\r
131     //\88ø\90\94\82à\8aJ\95ú\82·\82é\81B\r
132     if(!context->args){\r
133         av_free(context->args);\r
134     }\r
135     if(!context->argv){\r
136         av_free(context->argv);\r
137     }\r
138     //DLL\82à\95Â\82\82é\r
139     dlclose(context->Dynamic);\r
140 }\r
141 \r
142 static int query_formats(AVFilterContext *ctx){\r
143         //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
144     avfilter_set_common_formats(ctx,avfilter_make_format_list(1,PIX_FMT_RGB24));\r
145     return 0;\r
146 }\r
147 \r
148 /*\r
149  * AVFilterPad\82ÌInput\91¤\82É\8cÄ\82Î\82ê\82é\8aÖ\90\94\r
150  */\r
151 \r
152 static void start_frame(AVFilterLink *link, AVFilterPicRef *picref){\r
153         //\82¨\82Ü\82\82È\82¢\r
154     avfilter_start_frame(link->dst->outputs[0], picref);\r
155 }\r
156 \r
157 static void end_frame(AVFilterLink *link){\r
158         //\83|\83C\83\93\83^\82Í\8aî\96{\r
159     Context *context = link->dst->priv;\r
160     //\82æ\82­\82í\82©\82ç\82È\82¢\82¯\82Ç\82Æ\82è\82 \82¦\82¸\82¨\82Ü\82\82È\82¢\81i\82¦\81[\r
161     AVFilterLink* output = link->dst->outputs[0];\r
162     AVFilterPicRef *pic = link->cur_pic;\r
163     //\93Æ\8e©\8d\\91¢\91Ì\82É\91ã\93ü\r
164     vhext_frame frame;\r
165     frame.data = pic->data[0];\r
166     frame.linesize = pic->linesize[0];\r
167     frame.w = pic->w;\r
168     frame.h = pic->h;\r
169     frame.pts = ((double)pic->pts) / AV_TIME_BASE;\r
170         //\83\89\83C\83u\83\89\83\8a\82ð\8cÄ\82Ñ\8fo\82·\81B\r
171         context->ExtProcess(context->Context,context->Box,&frame);\r
172 \r
173     //\82¨\82È\82\82­\82¨\82È\82\82Ü\82¢\81i\82¦\82¦\82¦\r
174     avfilter_draw_slice(output, 0, pic->h);\r
175     avfilter_end_frame(output);\r
176 }\r
177 \r
178 AVFilter avfilter_vf_vhext=\r
179 {\r
180     .name      = "vhext",\r
181 \r
182     .priv_size = sizeof(Context),\r
183 \r
184     .init      = init,\r
185     .uninit    = uninit,\r
186 \r
187     .query_formats   = query_formats,\r
188     .inputs    = (AVFilterPad[]) {{ .name            = "default",\r
189                                     .type            = CODEC_TYPE_VIDEO,\r
190                                     .start_frame     = start_frame,\r
191                                     .end_frame       = end_frame,\r
192                                     .min_perms       = AV_PERM_WRITE |\r
193                                                        AV_PERM_READ,\r
194                                     .rej_perms       = AV_PERM_REUSE |\r
195                                                        AV_PERM_REUSE2},\r
196                                   { .name = NULL}},\r
197     .outputs   = (AVFilterPad[]) {{ .name            = "default",\r
198                                     .type            = CODEC_TYPE_VIDEO, },\r
199                                   { .name = NULL}},\r
200 };\r
201 \r
202 /*\r
203  * \82±\82Ì\92\86\82Å\82Ì\82Ý\8eg\82í\82ê\82é\8aÖ\90\94\r
204  */\r
205 \r
206 //\95\8e\9a\97ñ\82ð\93Á\92è\82Ì\95\8e\9a\82É\82æ\82Á\82Ä\95ª\82¯\82Ü\82·\81B\r
207 char** split(char* str,int str_len,int* argc,char delim){\r
208         //\83`\83F\83b\83N\r
209         if(!str || delim=='\0' || str_len < 0){\r
210                 return 0;\r
211         }\r
212         //\8am\95Û\r
213         char** argv = av_malloc(sizeof(char*));\r
214         if(!argv){\r
215                 return 0;\r
216         }\r
217         //\83\8b\81[\83v\8aJ\8en\r
218         int last = 0;\r
219         int i;\r
220         int arg_cnt = 0;\r
221         for(i=0;i<str_len;i++){\r
222                 if(str[i] == delim){//\83f\83\8a\83~\83^\82É\92B\82µ\82½\r
223                         str[i] = '\0';\r
224                         argv[arg_cnt] = &str[last];\r
225                         arg_cnt++;\r
226                         last = i+1;\r
227                         argv = av_realloc(argv,sizeof(char*) * (arg_cnt+1));\r
228                 }\r
229         }\r
230         argv[arg_cnt] = &str[last];\r
231         *argc = arg_cnt + 1;\r
232         return argv;\r
233 }\r
234 \r
235 //UR\83G\83\93\83R\81[\83h\8bL\96@\82ª\8eg\82¦\82Ü\82·\81B\r
236 int decode(char* s,int len){\r
237         int i,j;\r
238         char buf,*s1;\r
239         if(len==0)return(-1);\r
240         s1=(char*)av_malloc(len);\r
241         for(i=0,j=0;i<len;i++,j++)\r
242         {\r
243                 if(s[i]=='+'){s1[j]=' ';continue;}\r
244                 if(s[i]!='%') {s1[j]=s[i];continue;}\r
245                 buf=((s[++i]>='A') ? s[i]-'A'+10 : s[i]-'0');\r
246                 buf*=16;\r
247                 buf+=((s[++i]>='A') ? s[i]-'A'+10 : s[i]-'0');\r
248                 s1[j]=buf;\r
249         }\r
250         for(i=0;i<j;i++) s[i]=s1[i];\r
251         s[i]='\0';\r
252         av_free(s1);\r
253         return(0);\r
254 }\r
255 \r