1 /***************************************************************************
2 avsfilter.cpp - description
3 -------------------
4 begin : 28-04-2008
5 copyright : (C) 2008-2013 by fahr
6 email : fahr at inbox dot ru
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17 #include <string>
18 #ifndef AVS_WINE_BINARY_PATH
19 #error "AVS_WINE_BINARY_PATH not set!!!"
20 #endif
21
22 #include "ADM_default.h"
23 #include "ADM_coreVideoFilter.h"
24 #include "ADM_files.h"
25 #include "DIA_factory.h"
26 #include "errno.h"
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <time.h>
36 #include <signal.h>
37 #include <pthread.h>
38
39 #include "strnew.h"
40 #include "avspipecomm.h"
41 #include "avsfilterparam.h"
42 #include "avsfilterparam_desc.cpp"
43 #include "avsfilter.h"
44 #include "cdebug.h"
45
46 #define AVSFILTER_VERSION_INFO "AvsFilter, ver 0.12"
47 #define NOCOMPILE26
48
49 bool use_adv_protocol_avsfilter_to_pipesource = false;
50 bool use_adv_protocol_avsloader_to_avsfilter = false;
51
52 static WINE_LOADER *first_loader = NULL;
53 static AVSTerminate term;
54
55 #define MAXPATHLEN 512
56
57 /**
58 * several functions for realize link of objects
59 */
find_object(int order,const char * avs_loader,const char * avs_script,time_t script_ctime,time_t script_mtime,FilterInfo * input_info,bool * full)60 WINE_LOADER *find_object(int order,
61 const char *avs_loader, const char *avs_script,
62 time_t script_ctime, time_t script_mtime,
63 FilterInfo *input_info,
64 bool *full)
65 {
66 WINE_LOADER *res = first_loader;
67
68 while (res != NULL)
69 {
70 // check order first
71 if (res->order == order)
72 {
73 // after we check other params
74 if (!strcmp((char*)res->param.avs_loader.c_str(), avs_loader) &&
75 (!avs_script ||
76 !strcmp((char*)res->param.avs_script.c_str(), avs_script)) &&
77 res->input_info.width == input_info->width &&
78 res->input_info.height == input_info->height &&
79 res->param.script_ctime == script_ctime &&
80 res->param.script_mtime == script_mtime &&
81 res->input_info.frameIncrement == input_info->frameIncrement &&
82 res->input_info.totalDuration == input_info->totalDuration)
83 {
84 /* DEBUG_PRINTF("find_object : find %s %s\n",
85 (char*)res->_param.avs_loader,
86 (char*)res->_param.avs_script);*/
87 if (full) *full = true;
88 }
89 else
90 {
91 /* DEBUG_PRINTF("find_object fail: %s %s %dx%d [%d - %d] ftime %X:%X != %s %s %dx%d [%d - %d] ftime %lX:%lX\n",
92 (char*)res->_param.avs_loader,
93 (char*)res->_param.avs_script,
94 res->input_info.width,
95 res->input_info.height,
96 res->input_info.orgFrame, res->input_info.orgFrame + res->input_info.nb_frames,
97 res->_param.script_ctime, res->_param.script_mtime,
98 avs_loader, avs_script, input_info->width, input_info->height,
99 input_info->orgFrame, input_info->orgFrame + input_info->nb_frames,
100 script_ctime, script_mtime);*/
101 if (full) *full = false;
102 }
103 break;
104 }
105 res = (WINE_LOADER *)res->next_wine_loader;
106 }
107 return res;
108 }
109
print_objects(void)110 void print_objects(void)
111 {
112 WINE_LOADER *res = first_loader;
113
114 while (res != NULL)
115 {
116 /* DEBUG_PRINTF("print_objects : %s %s %dx%d [%d - %d]\n",
117 (char*)res->_param.avs_loader,
118 (char*)res->_param.avs_script,
119 res->input_info.width,
120 res->input_info.height,
121 res->input_info.orgFrame, res->input_info.orgFrame + res->input_info.nb_frames);*/
122 res = (WINE_LOADER *)res->next_wine_loader;
123 }
124 return;
125 }
126
delete_object(WINE_LOADER * obj)127 void delete_object(WINE_LOADER *obj)
128 {
129 WINE_LOADER *res = first_loader;
130
131 if (res == obj)
132 {
133 first_loader = (WINE_LOADER *) obj->next_wine_loader;
134 return;
135 }
136
137 while (res != NULL)
138 {
139 if (res->next_wine_loader == obj)
140 {
141 res->next_wine_loader = obj->next_wine_loader;
142 break;
143 }
144 res = (WINE_LOADER *)res->next_wine_loader;
145 }
146 }
147
add_object(WINE_LOADER * obj)148 void add_object(WINE_LOADER *obj)
149 {
150 WINE_LOADER *res = first_loader;
151 DEBUG_PRINTF("avsfilter : add_object start, res = %X\n", res);
152 if (!res)
153 {
154 first_loader = obj;
155 obj->next_wine_loader = NULL;
156 return;
157 }
158
159 while (res != NULL)
160 {
161 if (res->next_wine_loader == NULL)
162 {
163 res->next_wine_loader = obj;
164 obj->next_wine_loader = NULL;
165 break;
166 }
167 res = (WINE_LOADER *) res->next_wine_loader;
168 }
169 DEBUG_PRINTF("avsfilter : add_object end\n");
170 }
171
172 //********************************************
173
deinit_pipe(AVS_PIPES * avsp)174 void deinit_pipe(AVS_PIPES *avsp)
175 {
176 if (avsp->hpipe != -1)
177 {
178 close(avsp->hpipe);
179 avsp->hpipe = -1;
180 }
181
182 // if both link to pipename and pipename string exist
183 DEBUG_PRINTF("avsfilter : deinit_pipe %X\n", avsp->pipename);
184 DEBUG_PRINTF("avsfilter : deinit_pipe %s\n", avsp->pipename);
185 remove(avsp->pipename);
186 if (avsp->pipename && *avsp->pipename)
187 {
188 void *ptr = avsp->pipename;
189 avsp->pipename = NULL;
190 ADM_dealloc (ptr);
191 }
192 }
193
deinit_pipes(AVS_PIPES * avsp,int num)194 void deinit_pipes(AVS_PIPES *avsp, int num)
195 {
196 int i;
197 for (i = 0; i < num; i++) deinit_pipe(&avsp[i]);
198 }
199
200 #define MAX_PATH 1024
201
init_pipes(AVS_PIPES * avsp,int num,FILE * pfile)202 bool init_pipes (AVS_PIPES *avsp, int num, FILE *pfile)
203 {
204 int i;
205 for (i = 0; i < num; i++)
206 {
207 char sname[MAX_PATH];
208
209 if (fscanf(pfile, "%s\n", sname) != 1) DEBUG_PRINTF_RED("fscanf error\n");
210 else if (!(avsp[i].pipename = strnew(sname))) DEBUG_PRINTF_RED("strnew error\n");
211 else if (remove(avsp[i].pipename)) DEBUG_PRINTF_RED("error remove file\n");
212 else if (mkfifo(avsp[i].pipename, 0600))
213 DEBUG_PRINTF_RED("mkfifo error create fifo file %s, errno %d\n",
214 avsp[i].pipename, errno);
215 else continue;
216
217 deinit_pipes(avsp, i);
218 return false;
219 }
220
221 return true;
222 }
223
open_pipes(AVS_PIPES * avsp,int num)224 bool open_pipes(AVS_PIPES *avsp, int num)
225 {
226 int i;
227 for (i = 0; i < num; i++)
228 {
229 DEBUG_PRINTF("avsfilter : try to open %s fifo\n", avsp[i].pipename);
230 if ((avsp[i].hpipe = open(avsp[i].pipename, avsp[i].flags)) == -1)
231 {
232 DEBUG_PRINTF_RED("avsfilter : failed open errno %d\n", errno);
233 deinit_pipe(&avsp[i]);
234 deinit_pipes(avsp, i);
235 return false;
236 }
237 }
238
239 DEBUG_PRINTF("all pipes open ok\n");
240
241 return true;
242 }
243
pipe_test_filter(int hr,int hw)244 bool pipe_test_filter(int hr, int hw)
245 {
246
247 uint32_t test_send = (uint32_t) time(NULL);
248 uint32_t test_r1 = 0;
249
250 int sz1;
251
252 DEBUG_PRINTF("avsfilter : pipe_test_filter prewrite\n");
253
254 sz1 = write(hw, &test_send, sizeof(uint32_t));
255
256 if (sz1 != sizeof(uint32_t)) return false;
257
258 DEBUG_PRINTF("avsfilter : pipe_test_filter preread\n");
259
260 sz1 = read(hr, &test_r1, sizeof(uint32_t));
261
262 if (sz1 != sizeof(uint32_t) || (test_r1 != test_send)) return false;
263
264 return true;
265 }
266
267 bool open_pipes_ok, wine_loader_down = false;
268
~AVSTerminate()269 AVSTerminate::~AVSTerminate()
270 {
271 WINE_LOADER *cur_loader = first_loader;
272 int i = 0;
273 DEBUG_PRINTF("Call terminate!!!\n");
274
275 if (cur_loader)
276 do {
277 DEBUG_PRINTF("Count %d\n", i++);
278
279 if (cur_loader->avs_pipes[PIPE_LOADER_WRITE].hpipe != -1)
280 {
281 send_cmd(cur_loader->avs_pipes[PIPE_LOADER_WRITE].hpipe,
282 UNLOAD_AVS_SCRIPT, NULL, 0);
283 DEBUG_PRINTF("UNLOAD_AVS_SCRIPT try\n");
284 }
285
286 if (cur_loader->avs_pipes[PIPE_LOADER_WRITE].hpipe != -1)
287 {
288 send_cmd(cur_loader->avs_pipes[PIPE_LOADER_WRITE].hpipe,
289 UNLOAD_AVS_LOADER, NULL, 0);
290 DEBUG_PRINTF("UNLOAD_AVS_LOADER try\n");
291 }
292
293 deinit_pipes(cur_loader->avs_pipes, CMD_PIPE_NUM);
294 } while((cur_loader = (WINE_LOADER*)cur_loader->next_wine_loader) != NULL);
295 }
296
parse_wine_stdout(void * arg)297 void *parse_wine_stdout(void *arg)
298 {
299 char sname[MAX_PATH];
300 TPARSER *tp = (TPARSER *)arg;
301 FILE *pfile = tp->pfile;
302 AVS_PIPES copy_pipes [CMD_PIPE_NUM];
303 int i;
304 for (i = 0; i < CMD_PIPE_NUM; i++)
305 {
306 memcpy (©_pipes[i], &tp->avs_pipes[i], sizeof(AVS_PIPES));
307 if ((copy_pipes[i].flags & O_ACCMODE) == O_RDONLY)
308 copy_pipes[i].flags = (copy_pipes[i].flags & ~O_ACCMODE) | O_WRONLY;
309 else
310 if ((copy_pipes[i].flags & O_ACCMODE) == O_WRONLY)
311 copy_pipes[i].flags = (copy_pipes[i].flags & ~O_ACCMODE) | O_RDONLY;
312
313 DEBUG_PRINTF("avsfilter : new.flags %X, old.flags %X\n",
314 copy_pipes[i].flags, tp->avs_pipes[i].flags);
315 }
316
317 wine_loader_down = false;
318
319 if (pfile)
320 {
321 time_t t = time(NULL);
322 DEBUG_PRINTF("avsfilter : pthread time %s\n",
323 ctime(&t));
324 DEBUG_PRINTF("pthread start ok\n");
325 while(fgets(sname, MAX_PATH, pfile) != NULL)
326 #ifdef DEBUGMSG
327 printf("%s", sname);
328 #else
329 ;
330 #endif
331 DEBUG_PRINTF("End parse\n");
332 pclose(pfile);
333
334 wine_loader_down = true;
335
336 // if pipes not open completely, then simple open from thread for close
337 if (!open_pipes_ok)
338 {
339 DEBUG_PRINTF("avsfilter : loader down, try to close waiting (for open) main thread\n");
340 if (open_pipes((AVS_PIPES*)©_pipes, CMD_PIPE_NUM))
341 {
342 DEBUG_PRINTF("avsfilter : open ok, try to deinit\n");
343 //deinit_pipes((AVS_PIPES*)©_pipes, CMD_PIPE_NUM);
344 DEBUG_PRINTF("avsfilter : deinit done\n");
345 }
346 }
347
348 }
349 return NULL;
350 }
351
wine_start(const char * wine_app,const char * avsloader,AVS_PIPES * avs_pipes,int pipe_timeout)352 bool wine_start(const char *wine_app, const char *avsloader, AVS_PIPES *avs_pipes, int pipe_timeout)
353 {
354 char sname[MAX_PATH];
355 struct stat st;
356 sprintf(sname, "%s %s %d", wine_app, avsloader, pipe_timeout);
357
358 FILE *pfile = popen(sname, "r");
359 if (!pfile)
360 {
361 DEBUG_PRINTF_RED("avsfilter : popen failed, errno %d, failed start app is : [%s]\n", errno, sname);
362 return false;
363 }
364
365 if (fscanf(pfile, "%s\n", sname) != 1 ||
366 stat(sname, &st) ||
367 !S_ISDIR(st.st_mode))
368 {
369 DEBUG_PRINTF_RED("avsfilter : tmpdirname [%s] failed, errno %d[stat %d isdir %d]\n", sname, errno, stat(sname, &st), S_ISDIR(st.st_mode));
370 pclose(pfile);
371 return false;
372 }
373
374 DEBUG_PRINTF("avsfilter : good tmpdirname %s\n", sname);
375
376 if (!init_pipes(avs_pipes, CMD_PIPE_NUM, pfile))
377 {
378 DEBUG_PRINTF_RED("init_pipes failed\n");
379 pclose(pfile);
380 return false;
381 }
382
383 time_t t = time(NULL);
384 DEBUG_PRINTF("avsfilter : precreate thread time %s\n",
385 ctime(&t));
386 pthread_t thread;
387 TPARSER tp = { avs_pipes, pfile };
388
389 open_pipes_ok = false;
390
391 if (pthread_create(&thread, NULL, parse_wine_stdout, &tp))
392 {
393 DEBUG_PRINTF_RED("Cannot pthread started...Errno %d\n",errno);
394 deinit_pipes(avs_pipes, CMD_PIPE_NUM);
395 return false;
396 }
397
398 t = time(NULL);
399 DEBUG_PRINTF("avsfilter : preopen time %s\n",
400 ctime(&t));
401
402 if (!open_pipes(avs_pipes, CMD_PIPE_NUM) || wine_loader_down)
403 {
404 open_pipes_ok = true;
405 DEBUG_PRINTF_RED("open_pipes failed\n");
406 deinit_pipes(avs_pipes, CMD_PIPE_NUM);
407 return false;
408 }
409
410 open_pipes_ok = true;
411
412 if (pipe_test_filter (avs_pipes[PIPE_LOADER_READ].hpipe,
413 avs_pipes[PIPE_FILTER_WRITE].hpipe))
414 {
415 DEBUG_PRINTF("avsfilter : test pipe to filter ok\n");
416
417 if (pipe_test_filter (avs_pipes[PIPE_LOADER_READ].hpipe,
418 avs_pipes[PIPE_LOADER_WRITE].hpipe))
419 {
420 DEBUG_PRINTF("avsfilter : test pipe to loader ok\n");
421 }
422 else
423 goto error_pipe_test;
424 }
425 else
426 {
427 error_pipe_test:
428 DEBUG_PRINTF_RED("Error test read/write pipes\n");
429 deinit_pipes(avs_pipes, CMD_PIPE_NUM);
430 return false;
431 }
432
433 DEBUG_PRINTF("wine start is ok\n");
434 return true;
435 }
436
avs_start(FilterInfo * info,FilterInfo * avisynth_info,const char * fname,AVS_PIPES * avs_pipes,PITCH_DATA * pd_pipe_source,PITCH_DATA * pd_avsloader)437 bool avs_start(FilterInfo *info, FilterInfo *avisynth_info,
438 const char *fname, AVS_PIPES *avs_pipes, PITCH_DATA *pd_pipe_source, PITCH_DATA *pd_avsloader)
439 {
440 DEBUG_PRINTF("avsfilter : avs_start()\n");
441 DEBUG_PRINTF("avsfilter : %X %X %s %X\n",
442 avs_pipes[PIPE_LOADER_WRITE].hpipe,
443 avs_pipes[PIPE_FILTER_WRITE].hpipe,
444 fname, info);
445 DEBUG_PRINTF("avsfilter : avs_start info : frameIncrement %lu totalDuration %llu\n",
446 info->frameIncrement, info->totalDuration);
447
448 ADV_Info aii, aio;
449 aii.width = info->width;
450 aii.height = info->height;
451 aii.nb_frames = info->totalDuration / info->frameIncrement;
452 aii.encoding = MAGIC_ADV_PROTOCOL_VAL;
453 aii.codec = 0;
454 aii.fps1000 = ADM_Fps1000FromUs(info->frameIncrement);
455 aii.orgFrame = 0;
456 DEBUG_PRINTF("avsfilter : send ADV_Info to avsloader [fps1000 = %d, nb_frames = %d]\n", aii.fps1000, aii.nb_frames);
457 if (!send_cmd(avs_pipes[PIPE_LOADER_WRITE].hpipe,
458 LOAD_AVS_SCRIPT, fname,
459 strlen(fname) + sizeof("\0")) ||
460 !send_cmd(avs_pipes[PIPE_FILTER_WRITE].hpipe,
461 SET_CLIP_PARAMETER, &aii,
462 sizeof(aii)))
463 {
464 DEBUG_PRINTF_RED("avsfilter : cannot set script name or set clip parameters\n");
465 deinit_pipes(avs_pipes, CMD_PIPE_NUM);
466 return false;
467 }
468
469 // get avisynth frame info
470 PIPE_MSG_HEADER msg;
471 if (!receive_cmd(avs_pipes[PIPE_LOADER_READ].hpipe, &msg))
472 {
473 DEBUG_PRINTF_RED("avsfilter : cannot receive command (SEND_PITCH_DATA_PIPE_SOURCE, OR SET_CLIP_PARAMETER)\n");
474 deinit_pipes(avs_pipes, CMD_PIPE_NUM);
475 return false;
476 }
477
478 switch (msg.avs_cmd)
479 {
480 case SEND_PITCH_DATA_PIPE_SOURCE:
481 if (!receive_data(avs_pipes[PIPE_LOADER_READ].hpipe, &msg, pd_pipe_source))
482 {
483 DEBUG_PRINTF_RED("avsfilter : cannot receive SEND_PITCH_DATA_PIPE_SOURCE\n");
484 deinit_pipes(avs_pipes, CMD_PIPE_NUM);
485 return false;
486 }
487 DEBUG_PRINTF("avsfilter : receive SEND_PITCH_DATA_PIPE_SOURCE YUV = %d %d %d\n", pd_pipe_source->pitchY, pd_pipe_source->pitchU, pd_pipe_source->pitchV);
488 if (!receive_cmd(avs_pipes[PIPE_LOADER_READ].hpipe, &msg) ||
489 msg.avs_cmd != SET_CLIP_PARAMETER)
490 {
491 DEBUG_PRINTF_RED("avsfilter : cannot receive SET_CLIP_PARAMETER header message\n");
492 deinit_pipes(avs_pipes, CMD_PIPE_NUM);
493 return false;
494 }
495 case SET_CLIP_PARAMETER:
496 if (!receive_data(avs_pipes[PIPE_LOADER_READ].hpipe, &msg, &aio))
497 {
498 DEBUG_PRINTF_RED("avsfilter : cannot receive avisynth clip parameters\n");
499 deinit_pipes(avs_pipes, CMD_PIPE_NUM);
500 return false;
501 }
502 break;
503 default :
504 DEBUG_PRINTF_RED("avsfilter : receive unknown command %d\n", msg.avs_cmd);
505 deinit_pipes(avs_pipes, CMD_PIPE_NUM);
506 return false;
507 break;
508 }
509
510 DEBUG_PRINTF("avsfilter : receive ADV_Info from avsloader [fps1000 = %d, nb_frames = %d]\n", aio.fps1000, aio.nb_frames);
511 avisynth_info->width = aio.width;
512 avisynth_info->height = aio.height;
513 avisynth_info->frameIncrement = ADM_UsecFromFps1000(aio.fps1000);
514 avisynth_info->totalDuration = aio.nb_frames * avisynth_info->frameIncrement;
515 if (aio.encoding == MAGIC_ADV_PROTOCOL_VAL)
516 {
517 DEBUG_PRINTF("avsfilter : send GET_PITCH_DATA to avsloader\n");
518 if (!send_cmd(avs_pipes[PIPE_LOADER_WRITE].hpipe,
519 GET_PITCH_DATA, NULL, 0))
520 {
521 DEBUG_PRINTF_RED("avsfilter : cannot send GET_PITCH_DATA\n");
522 deinit_pipes(avs_pipes, CMD_PIPE_NUM);
523 return false;
524 }
525 }
526
527 // correct avisynth_info for span of frames, calculate fps change metrics
528 /* float k_fps;
529 k_fps = float(avisynth_info->frameIncrement) / float(info->frameIncrement);
530 DEBUG_PRINTF("avsfilter : FPS change metrics %f\n", k_fps);
531 avisynth_info->nb_frames = int (info->nb_frames * k_fps);
532 avisynth_info->orgFrame = int (info->orgFrame * k_fps);
533 DEBUG_PRINTF("avsfilter : Calculate new span for avisynth script [%d - %d]\n",
534 avisynth_info->orgFrame,avisynth_info->orgFrame + avisynth_info->nb_frames);*/
535 return true;
536 }
537 #ifdef VERSION_2_5
538
539 DECLARE_VIDEO_FILTER(avsfilter,
540 0,0,12,
541 ADM_UI_ALL,
542 VF_MISC,
543 "avsfilter",
544 "avsfilter",
545 "Use avisynth script as video filter.");
546
547 #else
548 extern "C"
549 {
550 SCRIPT_CREATE(FILTER_create_fromscript,avsfilter,avsParam);
551 BUILD_CREATE(FILTER_create,avsfilter);
552
FILTER_getName(void)553 char *FILTER_getName(void)
554 {
555 return AVSFILTER_VERSION_INFO;
556 }
557
FILTER_getDesc(void)558 char *FILTER_getDesc(void)
559 {
560 return "This filter do intermediate processing via avisynth script";
561 }
562
FILTER_getVersion(void)563 uint32_t FILTER_getVersion(void)
564 {
565 return 1;
566 }
FILTER_getAPIVersion(void)567 uint32_t FILTER_getAPIVersion(void)
568 {
569 return ADM_FILTER_API_VERSION;
570 }
571 }
572 #endif
573
getConfiguration(void)574 const char *avsfilter::getConfiguration(void)
575 {
576 static char buf[MAXPATHLEN];
577
578 snprintf((char *)buf, MAXPATHLEN, "wine_app : %s\n loader : %s\n script : %s\npipe timeout %d\n",
579 param.wine_app.c_str(), param.avs_loader.c_str(), param.avs_script.c_str(), param.pipe_timeout);
580 return buf;
581 }
582
583 bool avsfilter_config_jserialize(const char *file, const avsfilter_config *key);
584 bool avsfilter_config_jdeserialize(const char *file, const ADM_paramList *tmpl,avsfilter_config *key);
585
configure(void)586 bool avsfilter::configure(void)
587 {
588 DEBUG_PRINTF("avsfilter : before dialog init\n");
589 print_objects();
590
591 #define PX(x) &(param.x)
592 std::string pWineApp=std::string(param.wine_app);
593 std::string pLoaderFile=std::string(param.avs_loader);
594 std::string pAvsScript=std::string(param.avs_script);
595
596
597 diaElemFile wine_app(0,pWineApp,
598 QT_TRANSLATE_NOOP("avsfilter","_wine app file:"), NULL,
599 QT_TRANSLATE_NOOP("avsfilter","Select wine filename[wine/cedega/etc.]"));
600 diaElemFile loaderfile(0,pLoaderFile,
601 QT_TRANSLATE_NOOP("avsfilter","_loader file:"), NULL,
602 QT_TRANSLATE_NOOP("avsfilter","Select loader filename[avsload.exe]"));
603 diaElemFile avsfile(0,pAvsScript,
604 QT_TRANSLATE_NOOP("avsfilter","_avs file:"), NULL,
605 QT_TRANSLATE_NOOP("avsfilter","Select avs filename[*.avs]"));
606 diaElemUInteger pipe_timeout(PX(pipe_timeout),QT_TRANSLATE_NOOP("avsfilter","_pipe timeout:"),1,30);
607
608 diaElem *elems[4]={&wine_app, &loaderfile, &avsfile, &pipe_timeout};
609
610 if( diaFactoryRun(QT_TRANSLATE_NOOP("avsfilter","AvsFilter config"), 4, elems))
611 {
612 bool res = false;
613 param.wine_app=ADM_strdup(pWineApp.c_str()); // 3x memleak
614 param.avs_loader=ADM_strdup(pLoaderFile.c_str());
615 param.avs_script=ADM_strdup(pAvsScript.c_str());
616
617
618 DEBUG_PRINTF("avsfilter : configure before SetParameters\n");
619
620 // if script/loader names are exist, then taste config
621 if (param.avs_loader.size() &&
622 param.avs_script.size() &&
623 param.wine_app.size())
624 {
625 struct stat st;
626 if (stat((char*)param.avs_script.c_str(), &st) != 0)
627 {
628 DEBUG_PRINTF_RED("avsfilter : cannot stat script file\n");
629 return 0;
630 }
631
632 param.script_mtime = st.st_mtime; // store timestamp
633 param.script_ctime = st.st_ctime;
634
635 print_objects();
636 res = SetParameters(¶m);
637 if (res)
638 avsfilter_config_jserialize(prefs_name, ¶m);
639
640 DEBUG_PRINTF("avsfilter : configure before save prefs [%s][%s]\n",
641 param.avs_script.c_str(), param.avs_loader.c_str());
642 // if setparameters are ok and (therefore) avs_script and avs_loader exist
643 // we store this parameters in filter preferences
644 DEBUG_PRINTF("avsfilter : after save prefs info : frameIncrement %lu totalDuration %llu\n",
645 info.frameIncrement, info.totalDuration);
646
647 DEBUG_PRINTF("avsfilter : configure exit ok\n");
648 return res;
649 }
650 }
651 return 0;
652 }
653
654 /**
655 \fn getTimeRange
656 */
getTimeRange(uint64_t * startTime,uint64_t * endTime)657 bool avsfilter::getTimeRange(uint64_t *startTime, uint64_t *endTime)
658 {
659 *startTime = 0;
660 *endTime = info.totalDuration;
661 return true;
662 }
663
664 //#define SET_AVS(i,x,y,z) {wine_loader->avs_pipes[i].pipename = x; wine_loader->avs_pipes[i].hpipe = y; wine_loader->avs_pipes[i].flags = z;}
665
SetParameters(avsfilter_config * newparam)666 bool avsfilter::SetParameters(avsfilter_config *newparam)
667 {
668 bool full_exact = false;
669 DEBUG_PRINTF("avsfilter : SetParameters\n");
670
671 // find corresponding loader/script
672 WINE_LOADER *loader = find_object(order,
673 newparam->avs_loader.c_str(),
674 newparam->avs_script.c_str(),
675 newparam->script_ctime, newparam->script_mtime,
676 &info,
677 &full_exact);
678 // if loader not found
679 if (!loader)
680 {
681 DEBUG_PRINTF("avsfilter : SetParameters no loader found\n");
682 loader = new (WINE_LOADER);
683 loader->avs_pipes[0].flags = O_RDONLY;
684 loader->avs_pipes[1].flags = O_WRONLY;
685 loader->avs_pipes[2].flags = O_WRONLY;
686 loader->RefCounter = 0;
687 loader->param.avs_script = std::string("");
688 loader->param.avs_loader = std::string("");
689
690 if (!wine_start(newparam->wine_app.c_str(), newparam->avs_loader.c_str(), loader->avs_pipes, newparam->pipe_timeout))
691 {
692 DEBUG_PRINTF_RED("avsfilter : wine_start unsuccessful start!\n");
693 delete loader;
694 deref_wine_loader:
695 if (wine_loader)
696 {
697 wine_loader->RefCounter--;
698 wine_loader = NULL;
699 }
700 return false;
701 }
702
703 DEBUG_PRINTF("avsfilter : SetParameters success start wine\n");
704 loader->order = order;
705 add_object(loader);
706 }
707
708 // all parameters are NOT matched [order only]
709 if (!full_exact)
710 {
711 DEBUG_PRINTF("avsfilter : SetParameters !full_exact\n");
712
713 // matched only order (need reload with new script/geometry/etc)
714 if (!avs_start(&info, &loader->output_info, newparam->avs_script.c_str(), loader->avs_pipes, &pd_pipe_source, &pd_avsloader))
715 {
716 DEBUG_PRINTF_RED("avsfilter : SetParameters fail avs_start\n");
717 delete_object(loader);
718 goto deref_wine_loader;
719 }
720
721 DEBUG_PRINTF("avsfilter : SetParameters avs_start ok\n");
722 loader->RefCounter = 0;
723 memcpy(&loader->input_info, &info, sizeof(info));
724 loader->param.avs_loader = newparam->avs_loader;
725 loader->param.avs_script = newparam->avs_script;
726 loader->param.script_ctime = newparam->script_ctime; // store timestamp
727 loader->param.script_mtime = newparam->script_mtime;
728 }
729
730 if (wine_loader && wine_loader != loader) wine_loader->RefCounter--;
731 wine_loader = loader;
732 wine_loader->RefCounter++;
733 out_frame_sz = ((loader->output_info.width * loader->output_info.height) * 3) >>1;
734 // 22.11 fix size of output filter with fullexact found loader
735 info.width = loader->output_info.width;
736 info.height = loader->output_info.height;
737 info.frameIncrement = loader->output_info.frameIncrement;
738 info.totalDuration = loader->output_info.totalDuration;
739 /* info.fps1000 = loader->output_info.fps1000;
740 info.nb_frames = loader->output_info.nb_frames;
741 info.orgFrame = loader->output_info.orgFrame;*/
742
743 /* DEBUG_PRINTF("avsfilter : clip info : geom %d:%d fps1000 %d num_frames %d\n",
744 info.width, info.height, info.fps1000, info.nb_frames);*/
745 DEBUG_PRINTF("avsfilter : clip info : geom %d:%d frameIncrement %lu totalDuration %llu\n",
746 info.width, info.height, info.frameIncrement, info.totalDuration);
747
748 DEBUG_PRINTF("avsfilter : SetParameters return Ok\n");
749 return true;
750 }
751
avsfilter(ADM_coreVideoFilter * in,CONFcouple * couples)752 avsfilter::avsfilter(ADM_coreVideoFilter *in,
753 CONFcouple *couples) : ADM_coreVideoFilter(in,couples)
754 {
755 ADM_assert(in);
756 tmp_buf = NULL;
757 in=in;
758 DEBUG_PRINTF("Create AVSfilter(%X), AVDMGenericVideoStream %X\n", this, in);
759
760 wine_loader = NULL;
761 // param = new (avsfilter_config);
762 DEBUG_PRINTF("avsfilter : preconstructor info : frameIncrement %lu totalDuration %llu\n",
763 info.frameIncrement, info.totalDuration);
764 memcpy(&info, previousFilter->getInfo(),sizeof(info));
765 DEBUG_PRINTF("avsfilter : constructor info : frameIncrement %lu totalDuration %llu\n",
766 info.frameIncrement, info.totalDuration);
767
768 // info.encoding=1;
769 //vidCache = NULL;
770
771 #define AVSFILTER_CONFIG_NAME "/avsfilter.config2"
772 std::string psd = ADM_getUserPluginSettingsDir();
773 int sz_prefs_name = strlen (psd.c_str()) + sizeof(AVSFILTER_CONFIG_NAME) + 1;
774 prefs_name = new char [sz_prefs_name];
775 snprintf(prefs_name, sz_prefs_name, "%s%s", psd.c_str(), AVSFILTER_CONFIG_NAME);
776
777 if (!couples || !ADM_paramLoad(couples,
778 avsfilter_config_param,
779 ¶m))
780 {
781 if (!avsfilter_config_jdeserialize(prefs_name, avsfilter_config_param, ¶m))
782 {
783 param.wine_app = ADM_strdup("wine");
784 param.avs_script = ADM_strdup("test.avs");;
785 param.avs_loader = ADM_strdup(AVS_WINE_BINARY_PATH"/avsload.exe");
786 param.pipe_timeout = 10;
787 param.script_ctime = 0;
788 param.script_mtime = 0;
789 }
790 }
791
792 DEBUG_PRINTF("avsfilter : constructor info #2: frameIncrement %lu totalDuration %llu\n",
793 info.frameIncrement, info.totalDuration);
794
795 DEBUG_PRINTF("avsfilter : wine_app %s avsloader %s avsscript %s\n",
796 param.wine_app.c_str(), param.avs_loader.c_str(), param.avs_script.c_str());
797
798 if (!SetParameters(¶m))
799 {
800 DEBUG_PRINTF_RED("avsfilter : SetParameters return false\n");
801 DEBUG_PRINTF("avsfilter : info after error: frameIncrement %lu totalDuration %llu\n",
802 info.frameIncrement, info.totalDuration);
803 return;
804 }
805
806 DEBUG_PRINTF("avsfilter : constructor info #3: frameIncrement %lu totalDuration %llu\n",
807 info.frameIncrement, info.totalDuration);
808
809 #ifndef NOCOMPILE26
810 if (prefs->get(FILTERS_AVSFILTER_WINE_APP, &tmp_str) == RC_OK &&
811 strlen(tmp_str) > 0)
812 {
813 _param->wine_app = (ADM_filename*)ADM_strdup (tmp_str);
814 DEBUG_PRINTF("avsfilter : wine_app from config is %s\n", _param->wine_app);
815 ADM_dealloc(tmp_str);
816 }
817
818 if (prefs->get(FILTERS_AVSFILTER_AVS_SCRIPT, &tmp_str) == RC_OK &&
819 strlen(tmp_str) > 0)
820 {
821 _param->avs_script = (ADM_filename*)ADM_strdup (tmp_str);
822 DEBUG_PRINTF("avsfilter : avsscript from config is %s\n", _param->avs_script);
823 ADM_dealloc(tmp_str);
824 }
825
826 if (prefs->get(FILTERS_AVSFILTER_AVS_LOADER, &tmp_str) == RC_OK &&
827 strlen(tmp_str) > 0)
828 {
829 _param->avs_loader = (ADM_filename*)ADM_strdup (tmp_str);
830 DEBUG_PRINTF("avsfilter : avsloader from config is %s\n", _param->avs_loader);
831 ADM_dealloc(tmp_str);
832 }
833 prefs->get(FILTERS_AVSFILTER_PIPE_TIMEOUT, &_param->pipe_timeout);
834
835 struct stat st;
836 if (_param->avs_script)
837 if (stat((char*)_param->avs_script, &st) != 0)
838 {
839 DEBUG_PRINTF_RED("avsfilter : cannot stat script file\n");
840 return;
841 }
842 else
843 {
844 _param->script_mtime = st.st_mtime; // store timestamp
845 _param->script_ctime = st.st_ctime;
846 }
847 }
848 #endif
849 _uncompressed=new ADMImageDefault(in->getInfo()->width,in->getInfo()->height);
850 ADM_assert(_uncompressed);
851 in_frame_sz = ((_uncompressed->_width * _uncompressed->_height) * 3) >>1;
852 tmp_buf = (unsigned char*)ADM_alloc(PIPE_MAX_TRANSFER_SZ * 2);
853 ADM_assert(tmp_buf);
854 DEBUG_PRINTF("avsfilter : after constructor info : frameIncrement %lu totalDuration %llu\n",
855 info.frameIncrement, info.totalDuration);
856
857 if (_uncompressed->GetPitch(PLANAR_Y) == pd_pipe_source.pitchY &&
858 _uncompressed->GetPitch(PLANAR_U) == pd_pipe_source.pitchU &&
859 _uncompressed->GetPitch(PLANAR_V) == pd_pipe_source.pitchV)
860 {
861 use_adv_protocol_avsfilter_to_pipesource = true;
862 DEBUG_PRINTF("avsfilter : use_adv_protocol_avsfilter_to_pipesource = true\n");
863 }
864
865 // vidCache=new VideoCache(16,in);
866 }
867
868 avsfilter::~avsfilter()
869 {
870 if (wine_loader)
871 {
872 wine_loader->RefCounter--;
873 if (!wine_loader->RefCounter) wine_loader = NULL;
874 }
875
876 if (tmp_buf) ADM_dezalloc(tmp_buf);
877 delete [] prefs_name;
878 prefs_name=NULL;
879
880 /* if (vidCache)
881 {
882 delete vidCache;
883 vidCache = NULL;
884 }*/
885 }
886
887 void avsfilter::setCoupledConf( CONFcouple *couples)
888 {
889 DEBUG_PRINTF("avsfilter : setCoupledConf\n");
890 ADM_paramLoad(couples, avsfilter_config_param, ¶m);
891 }
892
893 bool avsfilter::getCoupledConf( CONFcouple **couples)
894 {
895 //*couples=new CONFcouple(6);
896
897 //#define CSET(x) (*couples)->setCouple((char *)#x,(_param.x))
898 DEBUG_PRINTF("avsfilter : getCoupledConf\n");
899 DEBUG_PRINTF("avsfilter : getCoupledConf info: frameIncrement %lu totalDuration %llu\n",
900 info.frameIncrement, info.totalDuration);
901 bool t = ADM_paramSave(couples, avsfilter_config_param, ¶m);
902 DEBUG_PRINTF("avsfilter : getCoupledConf info #2: frameIncrement %lu totalDuration %llu\n",
903 info.frameIncrement, info.totalDuration);
904 return t;
905
906 /* CSET(wine_app);
907 CSET(avs_script);
908 CSET(avs_loader);
909 CSET(pipe_timeout);
910 CSET(script_mtime);
911 CSET(script_ctime);*/
912 /* DEBUG_PRINTF("avsfilter : getCoupledConf end\n");
913 return 1;*/
914 }
915
916 bool receive_bit_blt(int h,
917 uint8_t* srcp, int src_pitch,
918 int row_size, int height)
919 {
920 for (int y = height; y > 0; --y)
921 {
922 if (ppread(h, (void*)srcp, row_size) != row_size) return false;
923 srcp += src_pitch;
924 }
925 return true;
926 }
927
928 bool send_bit_blt(int h,
929 uint8_t* srcp, int src_pitch,
930 int row_size, int height, unsigned char *data)
931 {
932 unsigned char *org_data = data;
933 for (int y = height; y > 0; --y)
934 {
935 int cp_sz;
936 memcpy(data, (void*)srcp, row_size);
937 srcp += src_pitch;
938 data += row_size;
939 cp_sz = data - org_data;
940 if (cp_sz >= PIPE_MAX_TRANSFER_SZ || y == 1)
941 {
942 if (ppwrite(h, (void*)org_data, cp_sz) != cp_sz) return false;
943 else
944 {
945 data = org_data;
946 DEBUG_PRINTF("avsfilter : send_bit_blt copy %d\n", cp_sz);
947 }
948 }
949 }
950 return true;
951 }
952
953 bool avsfilter::getNextFrame(uint32_t *fn, ADMImage *data)
954 {
955 uint32_t iframe = nextFrame;
956 uint32_t frame, tmpframe;
957 frame = iframe;
958
959 DEBUG_PRINTF("avsfilter : receive getFrameNumberNoAlloc %d, wine_loader %X\n",
960 frame, wine_loader);
961
962 // check framenumber
963 if (!wine_loader || ((iframe * wine_loader->output_info.frameIncrement) > wine_loader->output_info.totalDuration))
964 {
965 DEBUG_PRINTF("avsfilter : input framenumber (%d) is out of bounds [time %d > %d] \n", iframe,
966 iframe * wine_loader->output_info.frameIncrement, wine_loader->output_info.totalDuration);
967 return false;
968 }
969
970 FRAME_DATA fd = {frame};
971
972 // send command to get filtered data
973 if (!send_cmd(wine_loader->avs_pipes[PIPE_LOADER_WRITE].hpipe,
974 use_adv_protocol_avsloader_to_avsfilter ? GET_FRAME_WITH_PITCH : GET_FRAME, (void*)&fd,
975 sizeof(FRAME_DATA)))
976 {
977 DEBUG_PRINTF_RED("avsfilter : error send GET_FRAME to avsloader\n");
978 return 0;
979 }
980
981 // read all data from avsloader and pipe dll
982 PIPE_MSG_HEADER msg;
983 while (receive_cmd(wine_loader->avs_pipes[PIPE_LOADER_READ].hpipe, &msg))
984 {
985 switch(msg.avs_cmd)
986 {
987 default:
988 break;
989 case SEND_PITCH_DATA_AVSLOADER:
990 DEBUG_PRINTF("avsfilter : receive SEND_PITCH_DATA_AVSLOADER\n");
991 if (!receive_data(wine_loader->avs_pipes[PIPE_LOADER_READ].hpipe, &msg, &pd_avsloader))
992 {
993 DEBUG_PRINTF_RED("avsfilter : cannot get SEND_PITCH_DATA_AVSLOADER\n");
994 return 0;
995 }
996 DEBUG_PRINTF("avsfilter : receive SEND_PITCH_DATA_AVSLOADER YUV = %d %d %d\n", pd_avsloader.pitchY, pd_avsloader.pitchU, pd_avsloader.pitchV);
997 if (data->GetPitch(PLANAR_Y) == pd_avsloader.pitchY &&
998 data->GetPitch(PLANAR_U) == pd_avsloader.pitchU &&
999 data->GetPitch(PLANAR_V) == pd_avsloader.pitchV)
1000 {
1001 use_adv_protocol_avsloader_to_avsfilter = true;
1002 DEBUG_PRINTF("avsfilter : use_adv_protocol_avsloader_to_avsfilter = true\n");
1003 }
1004 break;
1005
1006 case GET_FRAME: // this request from pipe_source for input frame(s) to avisynth core
1007 DEBUG_PRINTF("avsfilter : receive GET_FRAME\n");
1008 if (!receive_data(wine_loader->avs_pipes[PIPE_LOADER_READ].hpipe,
1009 &msg, &fd))
1010 {
1011 DEBUG_PRINTF_RED("\navsfilter : error receive data\n");
1012 return 0;
1013 }
1014
1015 DEBUG_PRINTF("avsfilter : GET_FRAME number %d\n", fd.frame);
1016 tmpframe = fd.frame;
1017 DEBUG_PRINTF("avsfilter : %d but really get %d\n", fd.frame, tmpframe);
1018 //src=vidCache->getImage(tmpframe);
1019 if (!previousFilter->getNextFrame(&tmpframe, _uncompressed))
1020 {
1021 DEBUG_PRINTF("avsfilter : !!!OOPS!!!\n");
1022 return false;
1023 }
1024
1025 /* DEBUG_PRINTF("avsfilter : in frame size %lu pitchYUV %d %d %d, widthYUV %d %d %d, heightYUV %d %d %d\n",
1026 in_frame_sz, _uncompressed->GetPitch(PLANAR_Y), _uncompressed->GetPitch(PLANAR_U), _uncompressed->GetPitch(PLANAR_V),
1027 _uncompressed->GetWidth(PLANAR_Y), _uncompressed->GetWidth(PLANAR_U), _uncompressed->GetWidth(PLANAR_V),
1028 _uncompressed->GetHeight(PLANAR_Y), _uncompressed->GetHeight(PLANAR_U), _uncompressed->GetHeight(PLANAR_V));*/
1029
1030 if (use_adv_protocol_avsfilter_to_pipesource)
1031 {
1032 uint32_t pitch_data_sizeY = _uncompressed->GetPitch(PLANAR_Y) * _uncompressed->GetHeight(PLANAR_Y);
1033 uint32_t pitch_data_sizeU = _uncompressed->GetPitch(PLANAR_U) * _uncompressed->GetHeight(PLANAR_U);
1034 uint32_t pitch_data_sizeV = _uncompressed->GetPitch(PLANAR_V) * _uncompressed->GetHeight(PLANAR_V);
1035 uint32_t pitch_data_size = pitch_data_sizeY + pitch_data_sizeU + pitch_data_sizeV;
1036 DEBUG_PRINTF("avsfilter : pitch frame size %lu\n", pitch_data_size);
1037
1038 if (!send_cmd_with_specified_size(wine_loader->avs_pipes[PIPE_FILTER_WRITE].hpipe,
1039 PUT_FRAME_WITH_PITCH,
1040 (void*)&fd, sizeof(FRAME_DATA), pitch_data_size) ||
1041 ppwrite(wine_loader->avs_pipes[PIPE_FILTER_WRITE].hpipe, _uncompressed->GetReadPtr(PLANAR_Y), pitch_data_sizeY) != pitch_data_sizeY ||
1042 ppwrite(wine_loader->avs_pipes[PIPE_FILTER_WRITE].hpipe, _uncompressed->GetReadPtr(PLANAR_U), pitch_data_sizeU) != pitch_data_sizeU ||
1043 ppwrite(wine_loader->avs_pipes[PIPE_FILTER_WRITE].hpipe, _uncompressed->GetReadPtr(PLANAR_V), pitch_data_sizeV) != pitch_data_sizeV)
1044 {
1045 DEBUG_PRINTF_RED("avsfilter : error send uncompressed PITCH frame to dll\n");
1046 return 0;
1047 }
1048 }
1049 else
1050 // send frame to pipe_source
1051 if (!send_cmd_with_specified_size(wine_loader->avs_pipes[PIPE_FILTER_WRITE].hpipe,
1052 PUT_FRAME, (void*)&fd, sizeof(FRAME_DATA), in_frame_sz) ||
1053 !send_bit_blt(wine_loader->avs_pipes[PIPE_FILTER_WRITE].hpipe,
1054 _uncompressed->GetReadPtr(PLANAR_Y), _uncompressed->GetPitch(PLANAR_Y),
1055 _uncompressed->GetWidth(PLANAR_Y), _uncompressed->GetHeight(PLANAR_Y), tmp_buf) ||
1056 !send_bit_blt(wine_loader->avs_pipes[PIPE_FILTER_WRITE].hpipe,
1057 _uncompressed->GetReadPtr(PLANAR_U), _uncompressed->GetPitch(PLANAR_U),
1058 _uncompressed->GetWidth(PLANAR_U), _uncompressed->GetHeight(PLANAR_U), tmp_buf) ||
1059 !send_bit_blt(wine_loader->avs_pipes[PIPE_FILTER_WRITE].hpipe,
1060 _uncompressed->GetReadPtr(PLANAR_V), _uncompressed->GetPitch(PLANAR_V),
1061 _uncompressed->GetWidth(PLANAR_V), _uncompressed->GetHeight(PLANAR_V), tmp_buf))
1062 {
1063 DEBUG_PRINTF_RED("avsfilter : error send uncompressed frame to dll\n");
1064 return 0;
1065 }
1066
1067 //YPLANE(_uncompressed),
1068 DEBUG_PRINTF("avsfilter : send data ok for frame %d\n", fd.frame);
1069 break;
1070
1071 case PUT_FRAME_WITH_PITCH:
1072 case PUT_FRAME: // this request from avsload.exe with filtering data after avisynth
1073 DEBUG_PRINTF("avsfilter : receive %s, msg.sz %d\n", msg.avs_cmd == PUT_FRAME_WITH_PITCH ? "PUT_FRAME_WITH_PITCH" : "PUT_FRAME", msg.sz);
1074 if (msg.avs_cmd == PUT_FRAME && msg.sz != out_frame_sz + sizeof(FRAME_DATA))
1075 {
1076 DEBUG_PRINTF_RED("avsfilter : PUT_FRAME error : msg.sz [%d] != out_frame_sz+sizeof(FRAME_DATA) [%d,%d]\n",
1077 msg.sz, out_frame_sz, sizeof(FRAME_DATA));
1078 return 0;
1079 }
1080
1081 // DEBUG_PRINTF("avsfilter : read 1\n");
1082 if (!receive_data_by_size(wine_loader->avs_pipes[PIPE_LOADER_READ].hpipe,
1083 &fd, sizeof(FRAME_DATA)))
1084 {
1085 DEBUG_PRINTF_RED("avsfilter : receive data error#1\n");
1086 return 0;
1087 }
1088
1089 // ADM_assert(fd.frame == (iframe + info.orgFrame));
1090
1091 /* DEBUG_PRINTF("avsfilter : data->GetWidth(PLANAR_Y) %d data->GetHeight(PLANAR_Y) %d\n",
1092 data->GetWidth(PLANAR_Y), data->GetHeight(PLANAR_Y));
1093 DEBUG_PRINTF("avsfilter : data->GetWidth(PLANAR_U) %d data->GetHeight(PLANAR_U) %d\n",
1094 data->GetWidth(PLANAR_U), data->GetHeight(PLANAR_U));
1095 DEBUG_PRINTF("avsfilter : data->GetWidth(PLANAR_V) %d data->GetHeight(PLANAR_V) %d\n",
1096 data->GetWidth(PLANAR_V), data->GetHeight(PLANAR_V));*/
1097
1098 if (msg.avs_cmd == PUT_FRAME_WITH_PITCH)
1099 {
1100 uint32_t pitch_data_sizeY = data->GetPitch(PLANAR_Y) * data->GetHeight(PLANAR_Y);
1101 uint32_t pitch_data_sizeU = data->GetPitch(PLANAR_U) * data->GetHeight(PLANAR_U);
1102 uint32_t pitch_data_sizeV = data->GetPitch(PLANAR_V) * data->GetHeight(PLANAR_V);
1103 uint32_t pitch_data_size = pitch_data_sizeY + pitch_data_sizeU + pitch_data_sizeV;
1104
1105 if (msg.sz != (pitch_data_size + sizeof(FRAME_DATA)))
1106 {
1107 DEBUG_PRINTF_RED("avsfilter : PUT_FRAME_WITH_PITCH error : msg.sz [%d] != pitch_data_size + sizeof(FRAME_DATA) [%d,%d]\n",
1108 msg.sz, pitch_data_size, sizeof(FRAME_DATA));
1109 return 0;
1110 }
1111
1112 if (ppread(wine_loader->avs_pipes[PIPE_LOADER_READ].hpipe, (void*)data->GetReadPtr(PLANAR_Y), pitch_data_sizeY) != pitch_data_sizeY ||
1113 ppread(wine_loader->avs_pipes[PIPE_LOADER_READ].hpipe, (void*)data->GetReadPtr(PLANAR_U), pitch_data_sizeU) != pitch_data_sizeU ||
1114 ppread(wine_loader->avs_pipes[PIPE_LOADER_READ].hpipe, (void*)data->GetReadPtr(PLANAR_V), pitch_data_sizeV) != pitch_data_sizeV)
1115 {
1116 DEBUG_PRINTF_RED("avsfilter : receive data error for PUT_FRAME_WITH_PITCH\n");
1117 return 0;
1118 }
1119 }
1120 else
1121 {
1122 // DEBUG_PRINTF("avsfilter : read %d frame number Y plane\n", fd.frame);
1123 if (!receive_bit_blt(wine_loader->avs_pipes[PIPE_LOADER_READ].hpipe,
1124 data->GetWritePtr(PLANAR_Y), data->GetPitch(PLANAR_Y),
1125 data->GetWidth(PLANAR_Y), data->GetHeight(PLANAR_Y)))
1126 {
1127 DEBUG_PRINTF_RED("avsfilter : receive data error#2\n");
1128 return 0;
1129 }
1130
1131 // DEBUG_PRINTF("avsfilter : read %d frame number U plane\n", fd.frame);
1132 if (!receive_bit_blt(wine_loader->avs_pipes[PIPE_LOADER_READ].hpipe,
1133 data->GetWritePtr(PLANAR_U), data->GetPitch(PLANAR_U),
1134 data->GetWidth(PLANAR_U), data->GetHeight(PLANAR_U)))
1135 {
1136 DEBUG_PRINTF_RED("avsfilter : receive data error#3\n");
1137 return 0;
1138 }
1139 // DEBUG_PRINTF("avsfilter : read %d frame number V plane\n", fd.frame);
1140 if (!receive_bit_blt(wine_loader->avs_pipes[PIPE_LOADER_READ].hpipe,
1141 data->GetWritePtr(PLANAR_V), data->GetPitch(PLANAR_V),
1142 data->GetWidth(PLANAR_V), data->GetHeight(PLANAR_V)))
1143 {
1144 DEBUG_PRINTF_RED("avsfilter : receive data error#4\n");
1145 return 0;
1146 }
1147 }
1148 // *len = out_frame_sz;
1149 DEBUG_PRINTF("avsfilter : copy data\n");
1150 DEBUG_PRINTF("avsfilter : data parameters %d:%d\n",
1151 data->_width, data->_height);
1152 data->copyInfo(_uncompressed);
1153 data->Pts = _uncompressed->Pts;
1154 // vidCache->unlockAll();
1155 *fn=nextFrame;
1156 nextFrame++;
1157 return true;
1158 break;
1159 }
1160 }
1161 return false;
1162 }
1163