Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Development

Reply
 
Thread Tools Search this Thread Display Modes
Old 14th October 2010, 22:51   #1  |  Link
Bob Wya
Registered User
 
Join Date: Feb 2005
Location: Cambridge,UK
Posts: 35
Newbie filter development question : invoking other filters

Hi

After weeks of battling with a problem I have finally given up and come on the forums!! I am developing an avisynth filter against 2.58 using MS Visual 2008. I should say that although I have done a Comp Sci degree (years ago ) I am a bit clueless about programming in C++ (object scope, etc. boogles my brain)!! Also I cannot figure out how I would hook up VS 2008 to debug my filter (since I am simply calling it by running a .avs test script).

Basically my filter class constructor does the following:
(1) SampleClip: parse every frame detecting border sizes
(2) UpdateClip: invoke a chain of internal Avisynth filters (trim, subtitle, resize, addborders, etc.) to (optionally) preview the filter "in action"
(3) avsfile_write: writes an avisynth script with the appropriate trim(), resize(), addborder() commands. This file is outputed to the current working directory.

The GetFrame(): function simply accesses frame in a new clip created in step (2).

I have a couple of problems:
(1) I can't find a way to access the name of current .avs file that is being framecoded from.
(2) My code crashes when I try and change the original frame size (using envoked resizing filters). Frame-served output is fine when I retain equal frame sizes between the source and desination clips.
The actual crash occurs in the GetFrame() function (with the first frame being served). I presume the destination clip I create (at the end of UpdateClip()) is somehow not updating the clip properties of the 'env' class or something??!!

Heres some snippets of my (rather bloated) source code!! Please ask if I have not explained myself clearly enough!!

Bob


Code:
class autocentre : public GenericVideoFilter
{
...
  PClip		source_clip, trimed_subclip, text_overlayed_subclip, resized_subclip, subclip_with_borders, destination_clip;
...
  public:
  autocentre(PClip _child, int _mode, const char *_matrix, const char *_ResizeCommand, int _targetWidth, int _targetHeight,
  int _leftCrop, int _topCrop, int _rightCrop, int _bottomCrop,
  int _widthMultipleOf, int _heightMultipleOf,  double _hardThreshold, double _softThresholdLimit, double _medianDeviationLimit,
  int _horizontalBlocksThreshold, int _verticalBlocksThreshold, IScriptEnvironment *env) : GenericVideoFilter(_child) {
...
}
...
}

...

int __stdcall autocentre::UpdateClip(IScriptEnvironment* env)
{
...
  for (unsigned int i_frame_range=0; i_frame_range<v_clip_regions.size() ; ++i_frame_range) {
...
    start_frame = v_clip_regions[i_frame_range].start;
    end_frame	= v_clip_regions[i_frame_range].end;
...
    AVSValue  trimargs[3] = { source_clip, start_frame, start_frame-end_frame-1};
    trimed_subclip = env->Invoke("Trim",AVSValue(trimargs,3)).AsClip();
...
    AVSValue  arguments[13] = { text_overlayed_subclip, overlay_text_p, frame_crop_borders[en_left]+(target_clip_width>>5), -1,
        frame_number, frame_number, "Arial", font_size, 0x00aaaa00, 0x00000011, 4, -2, 10}; 
    text_overlayed_subclip = env->Invoke("Subtitle", AVSValue(arguments, 13)).AsClip();
...
    AVSValue  arguments[7] = { text_overlayed_subclip, target_clip_width, target_clip_height, float(frame_crop_borders[en_left]), float(frame_crop_borders[en_top]),
        float(frame_crop_borders[en_right]), float(frame_crop_borders[en_bottom]) };
    resized_subclip = env->Invoke(command_string.c_str(), AVSValue(arguments, 7)).AsClip();
...
    AVSValue  arguments[6] = { resized_subclip, v_new_black_borders[en_left], v_new_black_borders[en_top], v_new_black_borders[en_right], v_new_black_borders[en_bottom], 0x000000 };

    v_clip_regions[i_frame_range].destination_subclip = env->Invoke("AddBorders", AVSValue(arguments, 6)).AsClip();
...
  }
  AVSValue *p_arguments;
  p_arguments = new AVSValue[v_clip_regions.size()];
  for (unsigned int i_frame_range=0; i_frame_range<v_clip_regions.size() ; ++i_frame_range) {
    p_arguments[i_frame_range] = v_clip_regions[i_frame_range].destination_subclip;
  }
  if (v_clip_regions.size() == 1)
    destination_clip = v_clip_regions[0].destination_subclip;
  else
    destination_clip = env->Invoke("UnAlignedSplice", AVSValue(p_arguments, v_clip_regions.size())).AsClip(); 
}

PVideoFrame __stdcall autocentre::GetFrame(int frame_number, IScriptEnvironment* env)
{
  return	destination_clip->GetFrame(frame_number, env);
}
Bob Wya is offline   Reply With Quote
Old 14th October 2010, 23:25   #2  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,430
Quote:
Originally Posted by Bob Wya View Post
Code:
    AVSValue  arguments[13] = { text_overlayed_subclip, overlay_text_p, frame_crop_borders[en_left]+(target_clip_width>>5), -1,
        frame_number, frame_number, "Arial", font_size, 0x00aaaa00, 0x00000011, 4, -2, 10}; 
    text_overlayed_subclip = env->Invoke("Subtitle", AVSValue(arguments, 13)).AsClip();
That doesn't look right - you are applying Subtitle to a clip that has not yet been defined. Should this not be trimed_subclip?

You should enclose the Invoke calls in try/catch blocks to catch any errors that might arise.
Gavino is offline   Reply With Quote
Old 15th October 2010, 09:57   #3  |  Link
Bob Wya
Registered User
 
Join Date: Feb 2005
Location: Cambridge,UK
Posts: 35
Quote:
Originally Posted by Gavino View Post
That doesn't look right - you are applying Subtitle to a clip that has not yet been defined. Should this not be trimed_subclip?

You should enclose the Invoke calls in try/catch blocks to catch any errors that might arise.
Uhhhm yeh sorry that was a cut and paste error (I had been trying something different earlier in my code - to see if it made any difference!!)

I am writing to a log file. Like I say the code completes fine when I don't alter the clip resolution (I see the frame-served video). When I change the resolution I see this at the end of my log file:
Code:
...
target clip width=1280
target clip height=1016
left crop=0.0
top crop=2.0
right crop=0.0
bottom crop=-2.0
invoked resize command: Lanczos4Resize
completed subclip processing!!
UpdateClip() exit
filter complete
GetFrame(0)
and the Media Player Classic window either disappears or shows something about a stream error (??)

Are you saying that the invoked filters may have created the error? Despite the code actually appearing to get successfully through the constructor completely and crapping out in the standard GetFrame() function for my filter?


Can I log any environment/ clip parameters in my GetFrame() function - before it returns the first frame - that might clarify why it is not working/ causing Avisynth to crash?

Thanks
Bob
Bob Wya is offline   Reply With Quote
Old 15th October 2010, 13:32   #4  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,430
Quote:
Originally Posted by Bob Wya View Post
Are you saying that the invoked filters may have created the error? Despite the code actually appearing to get successfully through the constructor completely and crapping out in the standard GetFrame() function for my filter?
If it gets that far, then I suppose the Invokes must have completed without raising an exception. Nevertheless, it is good practice to use a try/catch to trap any errors which might occur.
Quote:
Can I log any environment/ clip parameters in my GetFrame() function - before it returns the first frame - that might clarify why it is not working/ causing Avisynth to crash?
You could log various clip properties (width, height, etc) of both this (from the vi variable) and destination_clip (from GetVideoInfo()).

Thinking about it, the problem probably is that these do have different sizes. If your final clip has different dimensions to the child (source) clip, then you need to change vi.width and height in your constructor.
Gavino is offline   Reply With Quote
Old 15th October 2010, 23:56   #5  |  Link
Bob Wya
Registered User
 
Join Date: Feb 2005
Location: Cambridge,UK
Posts: 35
Sweet!!

I just added:
Code:
vi=destination_clip->GetVideoInfo();
to the end of my constructor (UpdateClip() function).

Did a bit of hacking around to get my invoking filter functions tidied up a bit. Now loh and behold I get a fully working and resized output video stream!

I don't suppose you know the answer to my other question?
Quote:
(1) I can't find a way to access the name of current .avs file that is being framecoded from.
Basically I am trying to take the input .avs script and spit out an altered copy (with a name something like '...-new.avs'). This is so that I can easily automate the processing of a folder of DVD-Rebuilder .avs scripts.


Bob
Bob Wya is offline   Reply With Quote
Old 16th October 2010, 00:13   #6  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,430
Quote:
Originally Posted by Bob Wya View Post
I don't suppose you know the answer to my other question?
"I can't find a way to access the name of current .avs file that is being framecoded from. "
See stickboy's solution at post #7 in this thread. It's a script function which you can 'Invoke' from your code (put it in a .avsi file in your plugins folder and it will always be available).
Gavino is offline   Reply With Quote
Old 16th October 2010, 15:28   #7  |  Link
Bob Wya
Registered User
 
Join Date: Feb 2005
Location: Cambridge,UK
Posts: 35
Quote:
Originally Posted by Gavino View Post
See stickboy's solution at post #7 in this thread. It's a script function which you can 'Invoke' from your code (put it in a .avsi file in your plugins folder and it will always be available).
Thanks, like hundreds of other people no doubt, I've found or been directed to that thread... Hmmm I'll just wait till it's in the Avisynth API (where it should have been put months ago) rather than use some 'gross hack'...


Bob
Bob Wya is offline   Reply With Quote
Old 16th October 2010, 16:23   #8  |  Link
jmartinr
Registered User
 
jmartinr's Avatar
 
Join Date: Dec 2007
Location: Enschede, NL
Posts: 300
You might consider using the trick and use the filename you get as an inputparameter for your filter.
__________________
Roelofs Coaching
jmartinr is offline   Reply With Quote
Reply

Tags
autocentre, avisynth script, c++ source code, invoke internal filter

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 18:43.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2023, vBulletin Solutions Inc.