2 *
\8ag
\92£Vhook
\83t
\83B
\83\8b\83^
\r
3 * copyright (c) 2008
\83Õ
\81i
\83v
\83T
\83C
\81j
\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
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
11 #include "avfilter.h"
\r
12 #include "common/framehook_ext.h"
\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
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
31 //
\88ø
\90\94\82Í
\82 \82Æ
\82 \82Æ
\8eg
\82¤
\82Ì
\82Å
\8am
\95Û
\81B
\r
35 //
\83c
\81[
\83\8b\83{
\83b
\83N
\83X
\r
37 //
\83_
\83C
\83i
\83~
\83b
\83N
\83\89\83C
\83u
\83\89\83\8a\82Ö
\82Ì
\83|
\83C
\83\93\83^
\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
48 *
\82±
\82Ì
\92\86\82Å
\82¾
\82¯
\8eg
\82¤
\8aÖ
\90\94\92è
\8b`
\r
51 char** split(char* str,int str_len,int* argc,char delim);
\r
52 int decode(char* s,int len);
\r
55 * AVFilter
\8d\
\91¢
\91Ì
\82É
\8ai
\94[
\82³
\82ê
\82é
\8aÖ
\90\94\8cQ
\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
63 //
\88ø
\90\94\82ªNULL
\82È
\82Ì
\82Í
\82¨
\82©
\82µ
\82¢
\r
65 av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Invalid arguments.\n");
\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
72 av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to malloc memory for args.\n");
\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
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
83 av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to split args.\n");
\r
87 //
\83c
\81[
\83\8b\83{
\83b
\83N
\83X
\82ð
\8eæ
\93¾
\r
88 context->Box = tool_getToolBox();
\r
90 av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to get ToolBox.\n");
\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
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
108 if(!context->ExtProcess){
\r
109 av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to get ExtProcess.\n");
\r
112 if(!context->ExtRelease){
\r
113 av_log(ctx, AV_LOG_ERROR, "[libavfilter/VhookExt Filter]Failed to get ExtRelease.\n");
\r
117 //Configure
\82ð
\8cÄ
\82Ñ
\8fo
\82·
\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
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
135 if(!context->argv){
\r
136 av_free(context->argv);
\r
138 //DLL
\82à
\95Â
\82¶
\82é
\r
139 dlclose(context->Dynamic);
\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
149 * AVFilterPad
\82ÌInput
\91¤
\82É
\8cÄ
\82Î
\82ê
\82é
\8aÖ
\90\94\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
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
165 frame.data = pic->data[0];
\r
166 frame.linesize = pic->linesize[0];
\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
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
178 AVFilter avfilter_vf_vhext=
\r
182 .priv_size = sizeof(Context),
\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
194 .rej_perms = AV_PERM_REUSE |
\r
197 .outputs = (AVFilterPad[]) {{ .name = "default",
\r
198 .type = CODEC_TYPE_VIDEO, },
\r
203 *
\82±
\82Ì
\92\86\82Å
\82Ì
\82Ý
\8eg
\82í
\82ê
\82é
\8aÖ
\90\94\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
209 if(!str || delim=='\0' || str_len < 0){
\r
213 char** argv = av_malloc(sizeof(char*));
\r
217 //
\83\8b\81[
\83v
\8aJ
\8en
\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
224 argv[arg_cnt] = &str[last];
\r
227 argv = av_realloc(argv,sizeof(char*) * (arg_cnt+1));
\r
230 argv[arg_cnt] = &str[last];
\r
231 *argc = arg_cnt + 1;
\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
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
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
247 buf+=((s[++i]>='A') ? s[i]-'A'+10 : s[i]-'0');
\r
250 for(i=0;i<j;i++) s[i]=s1[i];
\r