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 29th August 2013, 23:21   #181  |  Link
IanB
Avisynth Developer
 
Join Date: Jan 2003
Location: Melbourne, Australia
Posts: 3,167
@Chikuzen,

Not sure how you this is coming unstuck here, dumb ansi code page encoding was unimaginatively designed with 1 char is 1 byte. When (If) we move to UTF-8 then some code points can be up to 4? bytes so we will certainly need to cope with it then. Do you have a specific ansi code page in mind that exceeds this crippled design, one of the Japanese sets maybe?

I can certainly bump the buffer size, I just want to be able to make sure some internal library buff[MAX_PATH] is still not going to crash and burn.
IanB is offline   Reply With Quote
Old 29th August 2013, 23:54   #182  |  Link
Chikuzen
typo lover
 
Chikuzen's Avatar
 
Join Date: May 2009
Posts: 595
Quote:
Originally Posted by IanB View Post
Do you have a specific ansi code page in mind that exceeds this crippled design, one of the Japanese sets maybe?
yes, I consider about CP932 .
I don't know which code page is used in China, Korea, Vietnam,etc...it will be the same since tens of thousands of characters are used in East Asia.
it will be better to make it MAX_PATH * 4, of course.
Stack overflow does not happen only 1KB array.
__________________
my repositories
Chikuzen is offline   Reply With Quote
Old 30th August 2013, 13:07   #183  |  Link
ultim
AVS+ Dev
 
ultim's Avatar
 
Join Date: Aug 2013
Posts: 359
Quote:
Originally Posted by IanB View Post
@ultim,

Forcing alignment is generally for setting a PVideoFrame to describe an existing foreign video buffer layout. This can avoid an unnecessary copy of the data. e.g. a source filter to match the memory layout delivered by a codec, or matching the memory layout of a hardware device.

Setting some pointers and a few describing numbers is of order a million times faster than actually copying the data bytes. TurboPascal7 above was advocating always making Crop that million times slower for the sake of always maintaining memory alignment.
Thanks for your help. I understand your reasoning, but the situation you described does not fully apply here, as far as I can tell. Because NewPlanarVideoFrame/NewVideoFrame always request a VideoFrame with an internal VideoFrameBuffer as a backing store (either a new one or a cached one, but always an internal one). So the existing foreign buffer that needs to be mimicked must still be copied over anyway. And in that case we might as well request a buffer with the highest alignment, so that future filters can employ special instruction sets.

Also, another thing that for me seems to invalidate your argument, is that to completely mimic a foreign buffer, you also need to mimic its pitch. NewPlanarVideoFrame/NewVideoFrame do not take pitch as an argument, so by method declaration it is impossible to use these methods to always describe an external buffer correctly. Internally these methods use rowsize and align to "guess" the pitch, but that won't always work and you're just relying on luck.

Here is an example where guessing the pitch as now won't work:
- foreign buffer rowsize is mod8/mod4/mod2/odd
- foreign rowsize = foreign pitch
- requesting alignment on 16 byte boundary
Here, because rowsize=pitch, rows after the 1st will not be 16-byte aligned, but it still makes sense to accelerate processing (e.g with SSE) if neighboring pixels are independent of each other (e.g. brightness/exposure adjustment, or simple recoloring techniques). Yet, the current methods will calculate a pitch that is mod16, so you can't describe the foreign buffer at all.

So, to summarize my points,
- because the method declarations are inadaquate to describe foreign video correctly in every case
- and because these methods will always use an internal backing store for the frame anyway, thus a copy must always be made ...
... even after your previous explanation, I still think that in these methods it doesn't make sense to force small alignments (using a negative alignment value). It only hinders later processing filters.

I hope I didn't embarass myself by writing something stupid in this long post

Last edited by ultim; 30th August 2013 at 13:32.
ultim is offline   Reply With Quote
Old 30th August 2013, 23:42   #184  |  Link
IanB
Avisynth Developer
 
Join Date: Jan 2003
Location: Melbourne, Australia
Posts: 3,167
@ultim, It's not a perfect system but it serves what has been required so far.

Clarification :- The start of first line of the video frame is always 16 byte aligned! The "align" value only determines how the "pitch" is calculated from the "rowsize".
Code:
...
   const int pitch = (row_size+align-1) / align * align;
...
   const int offset = (-int(vfb->GetWritePtr())) & (FRAME_ALIGN-1); // align first line offset
...
IanB is offline   Reply With Quote
Old 31st August 2013, 23:12   #185  |  Link
ultim
AVS+ Dev
 
ultim's Avatar
 
Join Date: Aug 2013
Posts: 359
Quote:
Originally Posted by IanB View Post
Code:
...
   const int pitch = (row_size+align-1) / align * align;
...
   const int offset = (-int(vfb->GetWritePtr())) & (FRAME_ALIGN-1); // align first line offset
...
Yes I know, that is what I meant when I said 'these methods use rowsize and align to "guess" the pitch'. I made changes to avisynth already, and I am also trying to correct this shortcoming of "align usage". Unfortunately I had to realize at some point that it is impossible to correct this in a sane way without breaking ABI compatibility. Currently, it seems at the very least I'd need to change the constructor parameters to VideoFrameBuffer, which broke at least the ffms2 plugin So I am still thinking about how to improve this aspect without too much trouble.

I forked avisynth locally and I'm making various "improvements". I have a variety of changes ranging from bugfixes and performance improvements, to improving developer friendliness, adding new functionality, and interface extensions in a backwards-compatible way (using COM rules ofc). I'll push my code to GitHub at some later point. I'm afraid you won't like many of them, coz I also restructured the project, moved files and code around and cleaned up header files. These add a LOT of noise to the commits, but thanks to these I feel the code is much less scary for newcomers (so I hope more contributors will show up), and I also reduced compile time by more than 50% (half!).

Anyway, thanks for your help, and I'm pretty sure I'll come back for more
ultim is offline   Reply With Quote
Old 31st August 2013, 23:49   #186  |  Link
IanB
Avisynth Developer
 
Join Date: Jan 2003
Location: Melbourne, Australia
Posts: 3,167
@ultim,

There is no "guess". It is the Avisynth API definition of pitch.

What is there to improve? The API does not mandate alignment, it's historical. Recent caveats do strongly suggest that performance critical memory addresses should be appropriately aligned such that fast code paths are possible, but code must work correctly (but it is allowed to be slow) with what is provided. It is not acceptable to chuck an exception or other wobbly at runtime just because something is not aligned as you would like. It is however acceptable to throw the exception at script load time.


If you have bugs, Report them!
IanB is offline   Reply With Quote
Old 1st September 2013, 00:33   #187  |  Link
ultim
AVS+ Dev
 
ultim's Avatar
 
Join Date: Aug 2013
Posts: 359
Quote:
Originally Posted by IanB View Post
There is no "guess". It is the Avisynth API definition of pitch.
Well, to understand my problem, you have to keep in perspective my original issue: what the use of forced alignment is. You told me it is to mimic external buffers. Fair enough, except that now you define pitch using alignment, and external code (except for avisynth filters) will not. So you shouldn't be using alignment as pitch, OR you shouldn't be able to force it.

Quote:
Originally Posted by IanB View Post
What is there to improve?
Exactly what I just described a line before.

Quote:
Originally Posted by IanB View Post
If you have bugs, Report them!
From the top of my head, I have three things on my fixed-list as of now.
- Messed up SEH+C++ exception interoperation, which borkes under many compilers. Fixed.
- A frame number clamping issue in ComparePlane::CmpPlaneSame, which requires already faulty input parameters to actually manifest, so no big deal, very minor. And actually, because I have not taken the time to properly understand that function, I am only 99% sure it is a bug to begin with, but reasonably sure. Fixed.
- Two BitBlt errors. This is the "funniest" one of all, one correctness error, and another one which prevents it from manifesting but causes performance degradation, both fixed. Unfortunately I have only recently found out that some external plugins (TIVTC at least) already rely on the buggy behavior (darn!), so this cannot be fixed anyway without breaking some plugins. Not good. Which means I will probably revert this change and add the corrected version in a new interface, but I'm still thinking about the best way to handle such cases. Fixing the plugins themself is actually also an option, coz some changes that I'm planning for the future are gonna make that necessary anyway.

See, except maybe for CmpPlaneSame, your are either not affected, or no-fix-possible. So pls don't go all red on me. Also, as you see, I fix anything that I find, so reporting bugs becomes an extra (and tbh somewhat needless) hassle for both you and me when I'm gonna publish the fix anyway. I'm not gonna keep them to myself, don't worry, I'm also working on the code for others, just like you.

Last edited by ultim; 1st September 2013 at 00:39.
ultim is offline   Reply With Quote
Old 1st September 2013, 06:14   #188  |  Link
Robert Martens
Registered User
 
Join Date: Feb 2010
Location: New York
Posts: 116
Quote:
Originally Posted by IanB View Post
I did warn that some imagination would be required.
I completely understand the value of "exercises left to the reader", as they say, and I'd even go so far as to say I enjoy them. It feels good to figure things out for oneself. At a certain point, however, my imagination gets tapped out, and the options are either ask for help or give up and walk away. I felt the former would be more productive, and possibly more helpful to others.

Thank you for the namespace advice, I'd toyed with that briefly but only around a few functions, not the entire file. I'm not having much luck with it so far, but I'll keep at it and see if I can get anywhere.

In the meantime, I felt I should share what my imagination has gotten me so far, so I put up a Gist with my changes: https://gist.github.com/ItEndsWithTens/6402453 The changes are summarized at the top of interface.cpp. I didn't include a project, just to keep this lightweight, but you should be able to just add the three files to your own and build it without too much hassle.

I can't promise it's the best solution (adding those branches to each function will no doubt have some performance impact), but I'm tentatively confident that it's at least working, so if anyone would like to take a look, or correct my thinking, feel free. If I ever manage a cleaner approach, I'll commit it to the Gist and make a note here.
Robert Martens is offline   Reply With Quote
Old 2nd September 2013, 09:17   #189  |  Link
IanB
Avisynth Developer
 
Join Date: Jan 2003
Location: Melbourne, Australia
Posts: 3,167
@Robert Martens,

I think your main difficulty was not grasping there needs to be 2 distinct API instances. One AVS_Linkage based standard 2.6 API in the InvertNeg.cpp filter and a second 2.5 API stand in from the modified interface.cpp, this second API stand in of course needs to be in a separate namespace so this implementation does not conflict with the first AVS_Linkage based implementation.
Attached Files
File Type: zip InvertNeg.zip (20.6 KB, 22 views)
IanB is offline   Reply With Quote
Old 2nd September 2013, 14:50   #190  |  Link
Robert Martens
Registered User
 
Join Date: Feb 2010
Location: New York
Posts: 116
Quote:
Originally Posted by IanB View Post
I think your main difficulty was not grasping there needs to be 2 distinct API instances.
That actually did get through to me, I understood what you meant when you offered the broad overview of "create a static copy of the linkage and initialize with that"; I didn't understand how to do that, though. That namespaces were the solution didn't occur to me, and once you mentioned that I tried it only to run into problems (which I'll get to presently). The code I posted as a Github gist is merely my desperate, last ditch effort to find a solution that offered one copy of the source code, and one copy of everything binary. Since I couldn't figure out how to do what you'd suggested, I wanted to at least find some way to make it work.

I was confused primarily because I was never sure what exactly was expected of me. You don't owe me your time, and I don't like to say these things for fear of seeming a belligerent ingrate, but I had trouble understanding your posts when you first suggested this, with regard to InvertNeg.cpp:

Quote:
Originally Posted by IanB View Post
Code:
....
const AVS_Linkage *AVS_linkage = &avs_linkage;

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(
        IScriptEnvironment* env,
        const AVS_Linkage* const vectors) {

    AVS_linkage = vectors;
    env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
    return "`InvertNeg' sample plugin";
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(
        IScriptEnvironment* env) {
    env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
    return "`InvertNeg' sample plugin";
}
Then went on to mention the namespace solution, clarifying the initialization to this:

Quote:
Originally Posted by IanB View Post
Code:
...
const AVS_Linkage* AVS_linkage = &Interface::avs_linkage;
...
Before coming to the end result which in your sample project turns out to be:

Code:
const AVS_Linkage* AVS_linkage = 0;

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(
    IScriptEnvironment* env, const AVS_Linkage* const vectors) {
    AVS_linkage = vectors;
    env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
    return "`InvertNeg' sample plugin";
}

namespace AVSInterface25 {

  const AVS_Linkage* AVS_linkage;

}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
    AVS_linkage = AVSInterface25::AVS_linkage;
    env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
    return "`InvertNeg' sample plugin";
}
I've always operated under the assumption that when you, or anyone else on these boards, describe things in only broad strokes, we're expected to put our minds to it and discover the answer ourselves, but when you offer specific lines of code, they are to be treated as sacrosanct and left untouched. We may have to add to them to complete the solution, but we're not meant to meddle in what specific details were already spelled out. I only reached the solution I posted earlier by hesitantly changing your directions, in a flailing, grasping-at-straws desire to get anything that worked; I certainly wasn't comfortable abandoning your instructions. In the future I'll try to be more flexible in my problem solving.

Unfortunately, although VC6 works as expected, I'm having trouble with your sample in my usual environment of Visual Studio 2010 Express; building the project spits out a series of errors related to sourceannotations.h, the first of which is

Code:
sourceannotations.h(244): error C3083: 'vc_attributes': the symbol to the left of a '::' must be a type
Including Windows.h inside the namespace seems to be the issue here. Moving the include out of it solves that problem, but introduces a new one:

Code:
crtdbg.h(1064): error C2039: 'delete[]' : is not a member of '`global namespace''
Since the crtdbg header is only included inside avisynth.h, I'm left believing the only option would be modifying the Avisynth header, but I'm not entirely sure what I should do, or that I even should be doing something so intrusive. I could always pull the crtdbg/debug macro definition block out of the header and add it by hand to all my source files, but that seems ugly. Is it my only option?

Last edited by Robert Martens; 2nd September 2013 at 19:01.
Robert Martens is offline   Reply With Quote
Old 2nd September 2013, 23:04   #191  |  Link
IanB
Avisynth Developer
 
Join Date: Jan 2003
Location: Melbourne, Australia
Posts: 3,167
Okay more than fair enough, you got the concept, just your SDK is putting up a fight about how to make it work.

I find it very hard to describe this sort of stuff without resorting to "loose" code examples, generally code snippets I use for discussion should be treated as definitely untested and probably requiring some sort of context.

Looks like I underestimated the amount of sugar that was going to be needed here. As you note I gave up on this actual construct :-
Code:
const AVS_Linkage* AVS_linkage = &Interface::avs_linkage;
I tried to make that idea fly for a full 5 minutes and replaced it with this :-
Code:
namespace AVSInterface25 {
  const AVS_Linkage* AVS_linkage;
}
.....
    AVS_linkage = AVSInterface25::AVS_linkage;
.....
and yes I got that "is not a member of '`global namespace''" old flannel from the compiler along the way. You just have to keep punching away until you find a syntax that represents the idea and will actually compile.

Not sure about the sourceannotations.h(244), maybe some "LEAN_AND_MEAN" declarations can help.
IanB is offline   Reply With Quote
Old 3rd September 2013, 11:25   #192  |  Link
Pier
Registered User
 
Join Date: Jul 2013
Posts: 29
I was wondering if it was possible to add an ,int "offset" to ConditionalReader in the next version to replace the offset value in the txt file, i mean, for example, if have written varius .txt files with varius kind of data to make something like IsSectionStatic() i would need to write a very large ammount of .txt files for every frame with a different offset value, but if could just use an int "offest", a recursion would allow me to check all the frames until the next scenechange and some other nice thing.
Pier is offline   Reply With Quote
Old 3rd September 2013, 22:08   #193  |  Link
Wilbert
Moderator
 
Join Date: Nov 2001
Location: Netherlands
Posts: 6,364
I thought let's try the second brute force method again (with InvertNeg.hpp as you posted; and changed red parts):

Code:
/* InvertNeg.cpp */

#include <windows.h>

namespace avs25 {
   #include "avisynth25.h"
   #include "InvertNeg.hpp"
}

namespace avs26 {
   #include "avisynth26.h"
   const AVS_Linkage *AVS_linkage = 0;
   #include "InvertNeg.hpp"
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(avs25::IScriptEnvironment* env) {
   env->AddFunction("InvertNeg", "c", avs25::Create_InvertNeg, 0);
   return "InvertNeg sample plugin";
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(avs26::IScriptEnvironment* env, const avs26::AVS_Linkage* const vectors) {
   avs26::AVS_linkage = vectors;
   env->AddFunction("InvertNeg", "c", avs26::Create_InvertNeg, 0);
   return "InvertNeg sample plugin";
}
If I only keep the avs25 sections (including the namespace) it works. If I only keep the avs26 sections (including the namespace) it works. But keeping both, just as above, when compiling i get the errors:

Compiling...
InvertNeg.cpp
F:\CompilingPlugins\InvertNeg\InvertNeg.cpp(11) : error C2143: syntax error : missing ';' before '*'
F:\CompilingPlugins\InvertNeg\InvertNeg.cpp(11) : error C2734: 'AVS_Linkage' : const object must be initialized if not extern
F:\CompilingPlugins\InvertNeg\InvertNeg.cpp(11) : error C2501: 'AVS_linkage' : missing storage-class or type specifiers
F:\CompilingPlugins\InvertNeg\InvertNeg.hpp(2) : error C2504: 'GenericVideoFilter' : base class undefined
F:\CompilingPlugins\InvertNeg\InvertNeg.hpp(4) : error C2629: unexpected 'class avs26::InvertNeg ('

etc ... No idea why it doesn't work. Btw line 11, is the const AVS_Linkage *AVS_linkage = 0; line.

Last edited by Wilbert; 3rd September 2013 at 22:12.
Wilbert is offline   Reply With Quote
Old 5th September 2013, 00:44   #194  |  Link
Robert Martens
Registered User
 
Join Date: Feb 2010
Location: New York
Posts: 116
Wilbert, I think that's the include guard you're bumping up against. Both versions of the Avisynth header define the same name, and you're including them both in the same file. If you just undefine it between your namespace blocks you should avoid the problem:

Code:
namespace avs25 {

  #include "avs25/avisynth.h"

  #include "InvertNeg.hpp"

}

#undef __AVISYNTH_H__

namespace avs26 {

  #include "avs26/avisynth.h"

  const AVS_Linkage *AVS_linkage = 0;

  #include "InvertNeg.hpp"

}

On the topic of the method Ian and I had been discussing, the problem seems to be that sourceannotations, when __cplusplus is defined, creates a namespace called "vc_attributes", then ends up using the scope resolution operator to assume it's directly under the global namespace, i.e. ::vc_attributes. Wrapping the include of that file in our own namespace means the full name ends up being ::AVSInterface25::vc_attributes, and the code in that header can't find anything. The same goes for crtdbg.h.

A little further digging with the /showIncludes switch (in VS2010 it's under Properties->C/C++->Advanced->Show Includes) shows that the aforementioned problem header is being pulled in by way of windows.h->excpt.h->crtdefs.h->sal.h->codeanalysis\sourceannotations.h.

The file's inclusion in sal.h is wrapped with this:

Code:
#if defined(_MSC_EXTENSIONS) && !defined( MIDL_PASS ) && !defined(__midl) && !defined(RC_INVOKED)
My brief research leads me to think those are of no use, though I suppose if push came to shove one could always use RC_INVOKED to pretend the resource compiler is active. Of course, even if you manage to avoid including the file, what happens to the rare bird who wants to use source code annotation? Academic, maybe, but the thought crossed my mind.

In any event, I finally got around to toying with VS 2012 Express, and it has no problems with the code, even with both includes under a custom namespace. Personally I don't mind switching, despite the disappointing Metro UI, but I'm still curious to see if I can come up with a solution for 2010. I'll keep at it.
Robert Martens is offline   Reply With Quote
Old 6th September 2013, 22:06   #195  |  Link
Wilbert
Moderator
 
Join Date: Nov 2001
Location: Netherlands
Posts: 6,364
Quote:
Wilbert, I think that's the include guard you're bumping up against. Both versions of the Avisynth header define the same name, and you're including them both in the same file. If you just undefine it between your namespace blocks you should avoid the problem:
Yes that works fine. Thanks!
Wilbert is offline   Reply With Quote
Old 7th September 2013, 20:12   #196  |  Link
Robert Martens
Registered User
 
Join Date: Feb 2010
Location: New York
Posts: 116
Ian, I'm sorry to say that although I got your version of the project to build successfully, I realized I'd never actually tried to use it in 2.5.8. I gave it a shot a short while ago, only to see everyone's favorite "System Exception: Access Violation" message. Stepping through the code with the debugger showed that the assignment in AvisynthPluginInit2 wasn't actually taking effect, for some reason that still escapes me.

There is nonetheless what I've convinced myself is excellent news! Find at the Github Gist a new version of the code, more in keeping with your original idea. Again, the changes to interface.cpp from revision 1.13 of that file are summarized at the top, but to explain what I did in relation to our discussion so far:

I was off base regarding VS 2012 before; the inclusion of sourceannotations.h appears to occur under different criteria than in 2010, but the file is still there, and may still cause problems for anyone using that functionality. crtdbg.h seems more robust, in that although operator delete and operator delete[] are declared in the file, they are no longer defined there as in 2010.

That's only in Visual Studio 2012, of course, so to account for both of those issues in all compiler/SDK versions, in interface.cpp I kept the inclusion of Windows.h out of the namespace (thereby addressing sourceannotations) and pilfered the debug macro definition from avisynth.h. Contrary to my earlier muddled expectation, this only needs to be done in interface.cpp, since it's the only place we're wrapping the header in a namespace. Placing the include of crtdbg and assert.h outside the namespace has the added benefit that if you ever use anything else in that file that expects to find the assert features, it'll work properly (I ran into that myself with avxsynth). I took the liberty of commenting out the _RPTX macros to avoid warnings about their redefinition, since I know the header will always be there to define them if _MSC_VER is undefined.

I then made avs_linkage non-static and non-const, so it's visible outside interface.cpp.

Over in invertneg.cpp, I made everything below Create_InvertNeg look like this:

Code:
namespace AVSInterface25 {

  struct AVS_Linkage;
  extern AVS_Linkage avs_linkage;

}

const AVS_Linkage* AVS_linkage = reinterpret_cast<AVS_Linkage*>(&AVSInterface25::avs_linkage);

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(
    IScriptEnvironment* env, const AVS_Linkage* const vectors) {
    AVS_linkage = vectors;
    env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
    return "`InvertNeg' sample plugin";
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
    env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
    return "`InvertNeg' sample plugin";
}
I found the cast necessary to allow the initialization. reinterpret_cast is ugly, but it expresses what we're doing more clearly than a C-style cast, and although it's a dangerous cast to develop the habit of using, in this case we know the two structures are identical, differing only by one's existence in a namespace.

How does this approach strike everyone?
Robert Martens is offline   Reply With Quote
Old 9th September 2013, 02:14   #197  |  Link
vcmohan
Registered User
 
Join Date: Jul 2003
Location: India
Posts: 890
When the input video is not planar format, GetWidthSubsampling() and GetHeightSubsampling() give an error message while GetReadPtr or GetPitch and other calls do not. Why this special treatment?
__________________
mohan
my plugins are now hosted here
vcmohan is offline   Reply With Quote
Old 9th September 2013, 03:27   #198  |  Link
IanB
Avisynth Developer
 
Join Date: Jan 2003
Location: Melbourne, Australia
Posts: 3,167
New code enforces correctness, old code a little bit slack.

Also GetPlaneWidth/HeightSubsampling are members of VideoInfo and do not have a useful value to return on error. (0 is no subsampling, -1 --> times 2 super sampling, 1 --> times 2 subsampling)

And GetReadPtr, GetPitch are members of VideoFrame and can usefully return zero for non existent planes.
IanB is offline   Reply With Quote
Old 9th September 2013, 17:30   #199  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
@VcMohan

As you recently posed a query on compiling for both v2.58 and v2.6a4, I assume that you want subsampling for both.
Below some code I use in RoboCrop, perhaps of use:
Code:
    myName="RoboCrop: ";

    if(vi.width==0 || vi.num_frames==0)         env->ThrowError("%sClip has no video",myName);
    # ifdef AVISYNTH_PLUGIN_25
        if(vi.IsPlanar() && vi.pixel_type != 0xA0000008) {              // Planar but NOT YV12, ie Avisynth v2.6+ ColorSpace
            // Here Planar but NOT YV12, If v2.5 Plugin Does NOT support ANY v2.6+ ColorSpaces
            env->ThrowError("%sColorSpace unsupported in v2.5 plugin",myName);
        }
    # endif

    bool isyuv=false,isplanar=false,isyuy2=false,isrgb=false,isy8=false;
    int xmod=1,ymod=1;

    if(isyuv=vi.IsYUV()) {
        if(isplanar=vi.IsPlanar()) {
            PVideoFrame src = child->GetFrame(0, env);                  // get frame 0
            int rowsizeUV=src->GetRowSize(PLANAR_U);
            if(rowsizeUV!=0) {                              // Not Y8
                const int ywid=src->GetRowSize(PLANAR_Y);
                const int yhit=src->GetHeight(PLANAR_Y);
                const int uhit=src->GetHeight(PLANAR_U);
                xmod=ywid/rowsizeUV;
                ymod=yhit/uhit;
            } else {
                isy8=true;
            }
        } else {
            isyuy2=true;
            xmod=2;
        }
    } else {
        isrgb=true;
    }

    xSubS=xmod;     // for Planar GetFrame
    ySubS=ymod;

    laced           =   args[3].AsBool(true);
    ymod = (laced)? ymod*2 : ymod;
v2.58 header does not contain GetWidthSubsampling/GetHeightSubsampling
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 9th September 2013, 21:46   #200  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
Memory leak in ConvertToYV24() ?

Please forgive me if I'm wrong or if the issue is already known - I couldn't find a similar post.

I suspect a 'memory leak' in the ConvertToYV24() function of V2.60.
I load the test script
Code:
ColorBars()
#~ ConvertToYV24()
ScriptClip("return last")
with XMediaRecode and observe its memory usage with ProcessExplorer. While converting the script to a HuffYuv AVI file, XMediaRecode's memory usage stays constant btw. 87 and 90 MBytes.
With the uncommented ConvertToYV24() Line, memory usage grows and grows. With more complex scripts (a ~15 line scriptclip that overlays 4 lines calculated with RTE stats functions over a Histogram("color2") ), the encoder crashes when memory usage reaches about 1,8MBytes.
VDub Portable (1.9.11) also crashes with a message "Think we ran out of memory folks".
OS details in this thread

EDIT: This is the crash script. Omit 'ConvertToYV24()', then it uses about 560MB, not more.
Code:
#=====================================================================================================================
function UVMeterBad(clip c) {
	c
	ScriptClip("""	#"
		c = Last
		c1 = c.crop(0,0,-256,0)
		cU = c1.UToY.BicubicResize(c1.width, c1.height)
		cV = c1.VToY.BicubicResize(c1.width, c1.height)
		MYStats(cU, flgs=$23)
		Um= MYS_yMin	#cU.RT_YPlaneMin()
		Ux= MYS_yMax	#cU.RT_YPlaneMax()
		Us= round(MYS_yStdev)	#round(cU.RT_YPlaneStdev)
		MYStats(cV, flgs=$23)
		Vm= MYS_yMin	#cV.RT_YPlaneMin()
		Vx= MYS_yMax	#cV.RT_YPlaneMax()
		Vs= round(MYS_yStdev)	#round(cV.RT_YPlaneStdev)
		Ymax = c1.YPlaneMax()
		MYStats(cU, c1, flgs=$10, prefix="MUS_", MaskMin=Ymax-1)
		MYStats(cV, c1, flgs=$10, prefix="MVS_", MaskMin=Ymax-1)
		c
		Overlay(BlankClip(c,pixel_type="RGB32",color=$80ff00,width=57,height=1),x=c.width-157,y=127,mode="Exclusion")	#cross hor.
		Overlay(BlankClip(c,pixel_type="RGB32",color=$80ff00,width=1,height=57),x=c.width-129,y=99,mode="Exclusion")	#cross vert.
		Overlay(BlankClip(c,pixel_type="RGB32",color=$ffffff,width=Ux-Um,height=1),x=c.width-129+Um-128,y=127+round(MVS_yAve)-128,mode="Exclusion")	#range hor.
		Overlay(BlankClip(c,pixel_type="RGB32",color=$ffffff,width=1,height=Vx-Vm),x=c.width-129+round(MUS_yAve)-128,y=127+Vm-128,mode="Exclusion") #range vert.
		return last
	""", local=true)	#"
	return last
}
#=====================================================================================================================
ColorBars(pixel_type="YV12")
ConvertToYV24()
Histogram("color2")
UVmeterBad()

Last edited by martin53; 9th September 2013 at 22:24.
martin53 is offline   Reply With Quote
Reply

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 20:55.


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