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
Register FAQ Calendar Today's Posts Search

Reply
 
Thread Tools Search this Thread Display Modes
Old 13th November 2016, 22:32   #1  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
SOLVED :) Compiler Bug ??? (VS 2010)

SOLVED Problem disappears with mvtools2 v2.7.1.22.


Hi Guys, having a bit of a problem with below code (VS2010), there dont seem to be similar problem in VS98 or VS2003 ToolKit 3.

Produces -1.IND000000000000 condition (but only on very first frame [EDIT: RT_AverageLuma will not access frame -1]).
Code producing error is during conversion of __int64 value of 255 to double.

Script
Code:
FN="LowBitrateAnime.AVI"
Avisource(FN)

Function StartOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") {
    c
    thSCD1=Default(thSCD1,400)
    thSCD2=Default(thSCD2,130)
    sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
    I_fv=sup.MAnalyse(isb=false,delta=1,blksize=16,overlap=8)
    Return c.MSCDetection(I_fv,thSCD1=thSCD1,thSCD2=thSCD2)
}

SC=StartOfSceneClip

SSS="""
    n=current_frame
    f=SC.RT_AverageLuma(n=n,W=1,H=1)  # Sample single pixel
    RT_Subtitle("%d] F=%f",n,f)       # Shows '0] F=-1.#IND00' on first frame
    return last
"""

Scriptclip(SSS)

Code fragment
Code:
    // Roughly What happens earlier in source
    // __int64 acc      = 0;
    // unsigned int sum = 0;
    // sum = sum + 255
    // unsigned int Pixels=1;  // EDIT: Added


    // floating point error flags (eg 1.0/3.0 gives _EM_INEXACT)
    unsigned int e = (_clearfp());
    if(e) {
        dprintf("RT_AverageLuma2: ***ERROR*** E=%X\n",e);
    }

    acc += sum;                                 // acc = 255
    double dacc = double(acc);                  // -1.#IND000000000000 ... SHOCK HORROR
    double result = dacc / Pixels;

//  e = (_clearfp() & ~_EM_INEXACT);
    e = (_clearfp());
    if(e) {
        dprintf("RT_AverageLuma3: ***ERROR*** E=$%X dacc=%f($%I64X) Pixels=%d",e,dacc,acc,Pixels);
    }

    return result;
}
Debugview Output, prints 2nd Error only (ie RT_AverageLuma3: error [EDIT: Below E=$10 is _EM_INEXACT])
Code:
00000006	1.73375964	RT_AverageLuma3: ***ERROR*** E=$10 dacc=-1.#IND00($FF) Pixels=1

Disassembly
Code:
	// floating point error flags (eg 1.0/3.0 gives _EM_INEXACT)
    // unsigned int e = (_clearfp() & ~_EM_INEXACT);
	unsigned int e = (_clearfp());
04DEBFBA  call        @ILT+1620(__clearfp) (4DE3659h)
04DEBFBF  mov         dword ptr [e],eax
	if(e) {
04DEBFC5  cmp         dword ptr [e],0
04DEBFCC  je          $LN7+183h (4DEBFE2h)
		dprintf("RT_AverageLuma2: ***ERROR*** E=%X\n",e);
04DEBFCE  mov         eax,dword ptr [e]
04DEBFD4  push        eax
04DEBFD5  push        offset string "RT_AverageLuma2: ***ERROR*** E=%"... (4ECF1ACh)
04DEBFDA  call        dprintf (4DE31DBh)
04DEBFDF  add         esp,8
	}

	acc += sum;
04DEBFE2  mov         eax,dword ptr [sum]
04DEBFE5  xor         ecx,ecx
04DEBFE7  add         eax,dword ptr [acc]
04DEBFEA  adc         ecx,dword ptr [ebp-38h]
04DEBFED  mov         dword ptr [acc],eax
04DEBFF0  mov         dword ptr [ebp-38h],ecx
	double dacc = double(acc);
04DEBFF3  fild        qword ptr [acc]
04DEBFF6  fstp        qword ptr [dacc]
	double result = dacc / Pixels;
04DEBFFC  mov         eax,dword ptr [Pixels]
04DEBFFF  mov         dword ptr [ebp-1A0h],eax
04DEC005  mov         dword ptr [ebp-19Ch],0
04DEC00F  fild        qword ptr [ebp-1A0h]
04DEC015  fdivr       qword ptr [dacc]
04DEC01B  fstp        qword ptr [result]

//	e = (_clearfp() & ~_EM_INEXACT);
	e = (_clearfp());
04DEC021  call        @ILT+1620(__clearfp) (4DE3659h)
04DEC026  mov         dword ptr [e],eax
	if(e) {
04DEC02C  cmp         dword ptr [e],0
04DEC033  je          $LN7+202h (4DEC061h)
		dprintf("RT_AverageLuma3: ***ERROR*** E=%X dacc=%f($%I64X) Pixels=%d",e,dacc,acc,Pixels);
04DEC035  mov         eax,dword ptr [Pixels]
04DEC038  push        eax
04DEC039  mov         ecx,dword ptr [ebp-38h]
04DEC03C  push        ecx
04DEC03D  mov         edx,dword ptr [acc]
04DEC040  push        edx
04DEC041  sub         esp,8
04DEC044  fld         qword ptr [dacc]
04DEC04A  fstp        qword ptr [esp]
04DEC04D  mov         eax,dword ptr [e]
04DEC053  push        eax
04DEC054  push        offset string "RT_AverageLuma3: ***ERROR*** E=%"... (4ECF164h)
04DEC059  call        dprintf (4DE31DBh)
04DEC05E  add         esp,1Ch
	}

	return result;
04DEC061  fld         qword ptr [result]
}
Is it possible that the problem resides earlier in code ? if so how can one detect it ?

Perhaps MvTools2 (v2.5.11.20) problem in trying to access first frame-1 ie frame -1, and somehow propagated into my function ?

Any clues anybody ?
__________________
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 ???

Last edited by StainlessS; 14th November 2016 at 02:31.
StainlessS is offline   Reply With Quote
Old 13th November 2016, 22:44   #2  |  Link
Groucho2004
 
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
Did you compile with "/Od"? "_clearfp()" doesn't work properly if you don't disable compiler optimizations.
__________________
Groucho's Avisynth Stuff
Groucho2004 is offline   Reply With Quote
Old 13th November 2016, 22:49   #3  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Debug dll compiled with /Od (as above).

EDIT: Exact same results in release with Maximise Speed /O2.

EDIT: Also occurs if script line mod
Code:
    f=SC.RT_AverageLuma       # Use current_frame and full frame sample
But this has no error
Code:
    f=SC.AverageLuma
I have stepped though the function and spotted no weirdness, everything as expected (not difficult for single pixel sample).

EDIT:
Swapping
Code:
SC=StartOfSceneClip
to
Code:
SC=Last
No problems.
__________________
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 ???

Last edited by StainlessS; 13th November 2016 at 23:12.
StainlessS is offline   Reply With Quote
Old 13th November 2016, 23:56   #4  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Its beginning to taste a lot like a problem in MvTool2 v2.5.11.20.

This has a problem at both ends of the clip, Error on SOS (Start of Scene) at frame 0, and at EOS (End Of Scene) on last frame
(if you in VDMod jump directly to last frame, And also if you jump to last but one, then step forward to last frame.
Strangely not if you jump to last but two and step forward to last frame).
Code:
FN="LowBitrateAnime.AVI"
Avisource(FN)

Function EndOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") {
    thSCD1=Default(thSCD1,400)
    thSCD2=Default(thSCD2,130)
    sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
    I_bv=sup.MAnalyse(isb=true, delta=1,blksize=16,overlap=8)
    Return c.MSCDetection(I_bv,thSCD1=thSCD1,thSCD2=thSCD2)
}

Function StartOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") {
    thSCD1=Default(thSCD1,400)
    thSCD2=Default(thSCD2,130)
    sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
    I_fv=sup.MAnalyse(isb=false,delta=1,blksize=16,overlap=8)
    Return c.MSCDetection(I_fv,thSCD1=thSCD1,thSCD2=thSCD2)
}

EOS = EndOfSceneClip
SOS = StartOfSceneClip

SSS="""
    e = EOS.RT_AverageLuma(n=current_frame,W=1,H=1)
    s = SOS.RT_AverageLuma(n=current_frame,W=1,H=1)
    RT_Subtitle("%d] EOS=%f SOS=%f",current_frame,e,s)
    return last
"""
Scriptclip(SSS)
EDIT: I dont think AverageLuma() uses a 64 bit accumulator (which RT_ does) and so that could be reason for not being affected
on convert to double.

EDIT: Problem persists in earlier MvTool2 v2.5.11.2.
__________________
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 ???

Last edited by StainlessS; 14th November 2016 at 00:11.
StainlessS is offline   Reply With Quote
Old 14th November 2016, 00:18   #5  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Problem disappears with mvtools2 v2.7.1.22.

SOLVED

EDIT:
MSCDetection from mvtools2 v2.5.11.2 and v2.5.11.20 must cause some kind of Floating point error that is propagated to the next filter using Floating point.

Only above 3 versions of mvTools2 tested.

EDIT: Wheres the Edit Tags thing gone ? (Wanted to add eg MvTools, MSCDetection, and Floating point error).
EDIT: Found it, on last post, not first.

EDIT: Also broken in v2.5.11.22.
EDIT: V2.6.0.5 unaffected by above problem.
__________________
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 ???

Last edited by StainlessS; 14th November 2016 at 03:05.
StainlessS is offline   Reply With Quote
Old 14th November 2016, 23:14   #6  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Here is small source that demos the problem even using VS6 (Aka VS 98)

Code:
#ifdef UNICODE
    #undef UNICODE                                                  // Avoid default wide character stuff
#endif
#ifdef _UNICODE
    #undef _UNICODE                                                 // Avoid default wide character stuff
#endif
#ifdef MBCS
    #undef MBCS
#endif
#ifdef _MBCS
    #undef _MBCS
#endif
#define _CRT_SECURE_NO_WARNINGS

#include <windows.h>
#include <stdio.h>
#include <float.h>
#include "avisynth.h"

int dprintf(char* fmt, ...) {
    char printString[2048]="FloatTest: ";       // MUST NUL TERM THIS [at some point before vsprintf(p, fmt, argp)]
    char *p=printString;
    while(*p++);
    --p;                                        // @ nul term
    va_list argp;
    va_start(argp, fmt);
    vsprintf(p, fmt, argp);
    va_end(argp);
    while(*p++);
    --p;                                        // @ nul term
    if(printString == p || p[-1] != '\n') { p[0]='\n'; p[1]='\0'; } // append n/l if not there already
    OutputDebugString(printString);
    return int(p-printString);                      // strlen printString
}

AVSValue __cdecl FloatTest(AVSValue args, void* user_data, IScriptEnvironment* env) {
    PClip child = args[0].AsClip();
    const bool test   = args[1].AsBool(false);  // Should we test video frame 0 ?
    const int n = 0;                            // test frame 0 only
    PVideoFrame src;
    __int64 acc=255;
    int Pixels=1;
    double dacc = (double)acc;
    double result = dacc / Pixels;
    int e;
    if(e = _clearfp()) {
        dprintf("FloatTest1: ***ERROR*** E=$%X dacc=%f($%I64X) Pixels=%d",e,dacc,acc,Pixels);
    }
    if(test)src = child->GetFrame(n,env);           // Force decoding. MUST assign to PVideoFrame
    dacc = (double)acc;        // Error Here when test==true
    result = dacc / Pixels;
    if(e = _clearfp()) {
        dprintf("FloatTest2: ***ERROR*** E=$%X dacc=%f($%I64X) Pixels=%d",e,dacc,acc,Pixels);
    }
    return result;
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
    env->AddFunction("FloatTest","c[test]b", FloatTest, 0);
    return "`FloatTest' FloatTest plugin";
}
And test script, errors if TEST=True (where calls GetFrame on frame 0, without doing anything else to it).

Code:
FN="LowBitrateAnime.AVI"
Avisource(FN)

Function StartOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") {
    thSCD1=Default(thSCD1,400)
    thSCD2=Default(thSCD2,130)
    sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
    I_fv=sup.MAnalyse(isb=false,delta=1,blksize=16,overlap=8)
    Return c.MSCDetection(I_fv,thSCD1=thSCD1,thSCD2=thSCD2)
}

SOS = StartOfSceneClip

TEST=True

SSS="""
    s = SOS.FloatTest(Test=TEST)
    RT_Subtitle("%d] SOS=%f",current_frame,s)
    return last
"""

Scriptclip(SSS)
EDIT: Test target above was MvTool2 v2.5.11.2, no others tested.

EDIT: Made test a bit better, CPP updated.
Here debug output
Code:
00000003    0.80795121  FloatTest: FloatTest2: ***ERROR*** E=$10 dacc=-1.#IND00($FF) Pixels=1
__________________
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 ???

Last edited by StainlessS; 14th November 2016 at 23:35.
StainlessS is offline   Reply With Quote
Reply

Tags
floating point error, mscdetection, mvtools


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 16:24.


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