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 29th May 2018, 06:19   #1  |  Link
MysteryX
Soul Architect
 
MysteryX's Avatar
 
Join Date: Apr 2014
Posts: 2,559
Passing PVideoFrame to Functions

I remember in the past I tried passing PVideoFrame to functions and it caused problems, but I never understood why. Also other codes generally call GetWritePtr/GetRowSize/GetPitch/GetHeight and pass those to functions.

I'm trying it again and the code isn't working as expected. Could someone enlighten me on this issue?

I'm porting Deblock from VapourSynth to Avisynth with high-bit-depth support as an exercise to understand VapourSynth code.

Here's the function that needs the frame reference.
https://github.com/mysteryx93/Avisyn...block.cpp#L197

The problem with instead taking 4 arguments is that I have 3 planes, and it would requires a LOT of parameters to pass the information of all 3 planes -- does it have to be done that way?

Either way I'd like to understand why passing PVideoFrame doesn't work. If I call MakeWriteable in GetFrame, the frame isn't writeable within the function so I have to call it there before calling GetWritePtr.

Current code doesn't crash, but the output is exactly the same as the input.

Last edited by MysteryX; 6th June 2018 at 02:03.
MysteryX is offline   Reply With Quote
Old 29th May 2018, 09:02   #2  |  Link
pinterf
Registered User
 
Join Date: Jan 2014
Posts: 2,314
Quote:
Originally Posted by MysteryX View Post
I remember in the past I tried passing PVideoFrame to functions and it caused problems, but I never understood why. Also other codes generally call GetWritePtr/GetRowSize/GetPitch/GetHeight and pass those to functions.

I'm trying it again and the code isn't working as expected. Could someone enlighten me on this issue?

I'm porting Deblock from VapourSynth to Avisynth with high-bit-depth support as an exercise to understand VapourSynth code.

Here's the function that needs the frame reference.
https://github.com/mysteryx93/Debloc...block.cpp#L197

Either way I'd like to understand why passing PVideoFrame doesn't work. If I call MakeWriteable in GetFrame, the frame isn't writeable within the function so I have to call it there before calling GetWritePtr.

Current code doesn't crash, but the output is exactly the same as the input.
Have you tried PVideoFrame &dst instead of PVideoFrame dst?
pinterf is offline   Reply With Quote
Old 29th May 2018, 11:10   #3  |  Link
TheFluff
Excessively jovial fellow
 
Join Date: Jun 2004
Location: rude
Posts: 1,100
Quote:
Originally Posted by MysteryX View Post
I remember in the past I tried passing PVideoFrame to functions and it caused problems, but I never understood why. Also other codes generally call GetWritePtr/GetRowSize/GetPitch/GetHeight and pass those to functions.

I'm trying it again and the code isn't working as expected. Could someone enlighten me on this issue?

I'm porting Deblock from VapourSynth to Avisynth with high-bit-depth support as an exercise to understand VapourSynth code.

Here's the function that needs the frame reference.
https://github.com/mysteryx93/Debloc...block.cpp#L197

The problem with instead taking 4 arguments is that I have 3 planes, and it would requires a LOT of parameters to pass the information of all 3 planes -- does it have to be done that way?

Either way I'd like to understand why passing PVideoFrame doesn't work. If I call MakeWriteable in GetFrame, the frame isn't writeable within the function so I have to call it there before calling GetWritePtr.

Current code doesn't crash, but the output is exactly the same as the input.
Are you aware of the distinction between pass-by-value, pass-by-pointer and pass-by-reference? If not, you should probably read up on it, it's kinda sorta important. The very short version though is that directly passing an object instance as an argument to a function in C++, like you do in the code you linked, then you pass it by value. This will invoke the PVideoFrame copy constructor (or potentially move constructor in C++11 or later I think?) and you'll get a new copy of the object inside the function you called. Not only is this rather inefficient, it's probably not what you want. You want to pass a reference to the original object. pinterf told you how to do that.
TheFluff is offline   Reply With Quote
Old 29th May 2018, 15:01   #4  |  Link
MysteryX
Soul Architect
 
MysteryX's Avatar
 
Join Date: Apr 2014
Posts: 2,559
Quote:
Originally Posted by pinterf View Post
Have you tried PVideoFrame &dst instead of PVideoFrame dst?
Ah, I thought PVideoFrame was already a pointer by itself.

I'll try that then.
MysteryX is offline   Reply With Quote
Old 29th May 2018, 15:42   #5  |  Link
amichaelt
Guest
 
Posts: n/a
Quote:
Originally Posted by MysteryX View Post
Ah, I thought PVideoFrame was already a pointer by itself.

I'll try that then.
PVideoFrame is a class not a typedef to a pointer. Going to the declaration in avisynth.h would have shown you this.
  Reply With Quote
Old 29th May 2018, 16:30   #6  |  Link
MysteryX
Soul Architect
 
MysteryX's Avatar
 
Join Date: Apr 2014
Posts: 2,559
Alright it works.

Deblock now works in 8-bit and in 32-bit.

16-bit however returns this.


Anyone sees what I'm missing?
https://github.com/mysteryx93/Debloc...ck/deblock.cpp

Curiously 16-bit works on a Y8 clip, but not on a YV420 clip.

Last edited by MysteryX; 29th May 2018 at 16:38.
MysteryX is offline   Reply With Quote
Old 29th May 2018, 18:29   #7  |  Link
wonkey_monkey
Formerly davidh*****
 
wonkey_monkey's Avatar
 
Join Date: Jan 2004
Posts: 2,496
I always thought P stood for pointer...
__________________
My AviSynth filters / I'm the Doctor
wonkey_monkey is offline   Reply With Quote
Old 29th May 2018, 18:56   #8  |  Link
MysteryX
Soul Architect
 
MysteryX's Avatar
 
Join Date: Apr 2014
Posts: 2,559
Quote:
Originally Posted by davidhorman View Post
I always thought P stood for pointer...
Ya, right?

Now where did that idea come from?
MysteryX is offline   Reply With Quote
Old 29th May 2018, 22:14   #9  |  Link
Wilbert
Moderator
 
Join Date: Nov 2001
Location: Netherlands
Posts: 6,364
PVideoFrame is a smart pointer to VideoFrame (just like PClip is a smart pointer to Clip): http://avisynth.nl/index.php/Filter_...PI#PVideoFrame. The difference with a regular pointer is that you don't need to explicitly destroy the object VideoFrame it points to, among other things.

See http://ootips.org/yonat/4dev/smart-pointers.html or https://en.wikipedia.org/wiki/Smart_pointer

Last edited by Wilbert; 29th May 2018 at 22:37.
Wilbert is offline   Reply With Quote
Old 30th May 2018, 18:29   #10  |  Link
amichaelt
Guest
 
Posts: n/a
Quote:
Originally Posted by davidhorman View Post
I always thought P stood for pointer...
And it does in this case as well. It's a smart pointer class that wraps a raw VideoFrame pointer but is not itself a raw pointer. That's why it doesn't act like a raw pointer.

Code:
// smart pointer to VideoFrame
class PVideoFrame {

  VideoFrame* p;

  void Init(VideoFrame* x);
  void Set(VideoFrame* x);

public:
  PVideoFrame() AVS_BakedCode( AVS_LinkCall_Void(PVideoFrame_CONSTRUCTOR0)() )
  PVideoFrame(const PVideoFrame& x) AVS_BakedCode( AVS_LinkCall_Void(PVideoFrame_CONSTRUCTOR1)(x) )
  PVideoFrame(VideoFrame* x) AVS_BakedCode( AVS_LinkCall_Void(PVideoFrame_CONSTRUCTOR2)(x) )
  void operator=(VideoFrame* x) AVS_BakedCode( AVS_LinkCall_Void(PVideoFrame_OPERATOR_ASSIGN0)(x) )
  void operator=(const PVideoFrame& x) AVS_BakedCode( AVS_LinkCall_Void(PVideoFrame_OPERATOR_ASSIGN1)(x) )

  VideoFrame* operator->() const { return p; }

  // for conditional expressions
  operator void*() const { return p; }
  bool operator!() const { return !p; }

  ~PVideoFrame() AVS_BakedCode( AVS_LinkCall_Void(PVideoFrame_DESTRUCTOR)() )
#ifdef BUILDING_AVSCORE
public:
  void CONSTRUCTOR0();  /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */
  void CONSTRUCTOR1(const PVideoFrame& x);
  void CONSTRUCTOR2(VideoFrame* x);
  void OPERATOR_ASSIGN0(VideoFrame* x);
  void OPERATOR_ASSIGN1(const PVideoFrame& x);
  void DESTRUCTOR();
#endif
}; // end class PVideoFrame

Last edited by amichaelt; 30th May 2018 at 20:49.
  Reply With Quote
Old 5th June 2018, 22:46   #11  |  Link
foxyshadis
Angel of Night
 
foxyshadis's Avatar
 
Join Date: Nov 2004
Location: Tangled in the silks
Posts: 9,559
Quote:
Originally Posted by MysteryX View Post
Alright it works.

Deblock now works in 8-bit and in 32-bit.

16-bit however returns this.


Anyone sees what I'm missing?
https://github.com/mysteryx93/Debloc...ck/deblock.cpp

Curiously 16-bit works on a Y8 clip, but not on a YV420 clip.
Your Deblock Repo is private; I only get a 404 from the link.
foxyshadis is offline   Reply With Quote
Old 5th June 2018, 23:41   #12  |  Link
DJATOM
Registered User
 
DJATOM's Avatar
 
Join Date: Sep 2010
Location: Ukraine, Bohuslav
Posts: 377
It's just renamed: https://github.com/mysteryx93/Avisynth-Deblock
__________________
Me on GitHub
PC Specs: Ryzen 5950X, 64 GB RAM, RTX 2070
DJATOM is offline   Reply With Quote
Old 7th June 2018, 10:15   #13  |  Link
`Orum
Registered User
 
Join Date: Sep 2005
Posts: 178
Not sure (yet) why you're getting the weird chroma issues, but at the very least you might want to address lines like these. The issue is it looks like you're using the preprocessor macros for min()/max() (from Windows.h), which are subject to the double-evaluation issue (though in your case you will get the right answer, it will be slower). There are several ways to work around this but the simplest for C++ is probably detailed here, or just use the STL equivalent.

Edit: If your compiler had C++17 support there's also std::clamp(), or you can always make your own template.
__________________
My filters: DupStep | PointSize

Last edited by `Orum; 7th June 2018 at 11:18.
`Orum is offline   Reply With Quote
Old 8th June 2018, 00:33   #14  |  Link
MysteryX
Soul Architect
 
MysteryX's Avatar
 
Join Date: Apr 2014
Posts: 2,559
It's working now. I was simply checking BitsPerPixel instead of BitsPerComponent in the initializer which caused the initial data to remain at 0 in certain cases.

As for min/max, #define NOMINMAX is there for that. It's using min and max functions defined in Avisynth.
MysteryX is offline   Reply With Quote
Old 8th June 2018, 04:06   #15  |  Link
`Orum
Registered User
 
Join Date: Sep 2005
Posts: 178
Ah okay, I missed that. Looking breifly at the code, this doesn't appear to be one of the fancier deblockers that varies the strength of deblocking on the amount of blocking detected. Any chance we could see that in a later release? Though, to be honest, I haven't needed a deblocking filter for anything encoded in the last decade thanks to in-loop deblocking.
__________________
My filters: DupStep | PointSize
`Orum is offline   Reply With Quote
Old 8th June 2018, 14:31   #16  |  Link
SaurusX
Registered User
 
Join Date: Feb 2017
Posts: 135
Quote:
Originally Posted by `Orum View Post
Ah okay, I missed that. Looking breifly at the code, this doesn't appear to be one of the fancier deblockers that varies the strength of deblocking on the amount of blocking detected. Any chance we could see that in a later release? Though, to be honest, I haven't needed a deblocking filter for anything encoded in the last decade thanks to in-loop deblocking.
There's a lot of old DVD video out there that definitely needs deblocking.
SaurusX is offline   Reply With Quote
Reply


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 22:07.


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