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 11th December 2020, 10:51   #1  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 2,904
Passing the field parity correctly

Hi,
I'd like to get and pass the field parity correctly from ffms2 inside Avisynth.
In clip properties, there are IsFieldBased() and GetParity() but there's a problem.
All clips inside Avisynth as they're indexed are framebased unless we manually change it by writing things like AssumeFieldBased(), so the bool IsFieldBased() is kinda useless in my case as it would always return false.
For GetParity() the story is different, 'cause it works both with Frame Based clips and Field Based Clips, so, even if ffms2 doesn't set the fieldbased flag, is not a big deal, 'cause it does set the TFF flag, so GetParity correctly returns true if the frame analyzed is top field first and false otherwise. This is a problem, though, 'cause "otherwise" can mean two things: either that the stream is bottom field first or that it's progressive. Is there a way to get whether a stream is interlaced or progressive automatically? Don't you think indexers should honor the flags and set AssumeFieldBased() when dealing with interlaced stuff instead of treating everything as frame based?

For the records, I tried LSMASH as well by calling LWLibavVideoSource and it doesn't set the flag either.

Code:
LWLibavVideoSource("interlaced_test.mxf")
IsFieldBased() ? Subtitle("Fields") : last
always returns false, therefore it just shows the video

Code:
LWLibavVideoSource("interlaced_test.mxf")
GetParity() ? Subtitle("Fields") : last
does show the word "Fields" on the top left for TFF and it doesn't show it for progressive files, however it doesn't show it for BFF files either...
FranceBB is offline   Reply With Quote
Old 11th December 2020, 11:00   #2  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 2,587
frame properties _FieldBased maybe is what you need
__________________
See My Avisynth Stuff
real.finder is offline   Reply With Quote
Old 11th December 2020, 11:16   #3  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 2,904
Isn't it going to work only if the user set it via AssumeFieldBased()?
FranceBB is offline   Reply With Quote
Old 11th December 2020, 11:59   #4  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 2,587
Quote:
Originally Posted by FranceBB View Post
Isn't it going to work only if the user set it via AssumeFieldBased()?
AssumeFieldBased has to do with clip properties

_FieldBased has to do with frame properties

clip properties has nothing to do with frame properties, they are two separate worlds

frame properties is taken from VS (there were plan to do this in vanilla Avisynth before avs 2.6 but didn't done)
__________________
See My Avisynth Stuff
real.finder is offline   Reply With Quote
Old 11th December 2020, 12:41   #5  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 2,904
You mean in the C++ API Interface?

Like:

Code:
int image_type;

enum {
  IT_BFF        = 1<<0,
  IT_TFF        = 1<<1,
  IT_FIELDBASED = 1<<2
};
in the image properties?

'cause I know that things like

Code:
bool IsParityKnown() const;
in the C++ API are only gonna work if it has been set by the user. Can you confirm that

Code:
bool IsFieldBased() const;
in the C++ API works with ffms2 and LSMASH without specifying it?
Otherwise, if I didn't get it right, what do you mean with _FieldBased?
FranceBB is offline   Reply With Quote
Old 11th December 2020, 13:45   #6  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 2,587
it's

Quote:
####### field based #######
"progressive" (0)
"top_field" (2)
"bottom_field" (1)
source and more info https://github.com/Asd-g/AviSynthPlu...WLInfo.avsi#L4 (don't know if they are in avs wiki)

it can also used in avs script https://github.com/Asd-g/AviSynthPlu...onGen.avsi#L97 more info https://forum.doom9.org/showthread.p...66#post1909566 (I think they not added to the wiki yet)

keep in mind that you need updated LSMASHSource https://forum.doom9.org/showthread.p...57#post1926057 or/and ffms2 https://forum.doom9.org/showthread.p...93#post1928993
__________________
See My Avisynth Stuff
real.finder is offline   Reply With Quote
Old 11th December 2020, 15:29   #7  |  Link
jordanh
Registered User
 
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 55
Ohh thats amazing functions!
To be honest, FranceBB opened this topic actually for me and it went into a wrong direction so i'll try to clear things up:
What we want to do here is to patch the ffmpeg avisynth demux plugin which means of course we underly lots of restrictions, e.g. backward compatibility and such.
The goal is to tell ffmpeg which field order the finally returned clip has got so it can set up internal filter engine stuff automatically and one does not have to script this part anymore.

Currently, from the C api i use avs_is_parity_known and avs_is_tff functions, they work when the avs script contains the AssumeFieldbased and AssumeTFF/BFF functions.
But after all i wondered if i could go one level deeper and even set the field order when the user did not contain the Assume functions in his script.

On my way i recognized that avs_get_parity(env,framenum) will actually work without the Assume* functions, in difference to avs_is_parity_known it will decode a frame but that might be something worth to sacrifice.
The only problem left is that avs_is_field_based from the C API will always return false if there are no Assume* functions, so from my understanding i could use this logic go be most accurate:

1) we have TFF when avs_get_parity is true
2) otherwise we have UNKNOWN (i can set this in ffmpeg)
3) Except avs_is_bff is set, in that case we have Bottom Field (but it only works when Assume* functions are in the avs script)

I believe above should be safe and work with all source plugins.
What i am not sure of is if this is really all i can do and if its reliable to say we have TFF when avs_get_parity is true but avs_is_field_based is false.

Last edited by jordanh; 11th December 2020 at 15:34.
jordanh is offline   Reply With Quote
Old 17th December 2020, 09:24   #8  |  Link
jordanh
Registered User
 
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 55
Quote:
...we have TFF when avs_get_parity is true but avs_is_field_based is false?
Sorry to bump this, i hoped it was easy to answer...
Just to make it clear, i am talking about these 2 functions from the C API:

AVSC_API(int, avs_get_parity)(AVS_Clip *, int n);
AVSC_INLINE int avs_is_field_based(const AVS_VideoInfo * p)
jordanh is offline   Reply With Quote
Old 17th December 2020, 14:15   #9  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
I dont know C interface at all, but for CPP interface, can be useful to lookup old v2.58 baked header,
before 2.60 and AVS+ 'un-baked' the headers. [see the v2.58 C header]

From v2.58 CPP header

Code:
// From VidioInfo

  enum {
    IT_BFF = 1<<0,
    IT_TFF = 1<<1,
    IT_FIELDBASED = 1<<2
  };

  bool IsFieldBased() const { return !!(image_type & IT_FIELDBASED); }
  bool IsParityKnown() const { return ((image_type & IT_FIELDBASED)&&(image_type & (IT_BFF|IT_TFF))); }
  bool IsBFF() const { return !!(image_type & IT_BFF); }
  bool IsTFF() const { return !!(image_type & IT_TFF); }

// from IClip
/ Base class for all filters.
  virtual bool __stdcall GetParity(int n) = 0;  // return field parity if field_based, else parity of first field in frame

// instantiable null filter
//class GenericVideoFilter : public IClip {
  bool __stdcall GetParity(int n) { return child->GetParity(n); }
__________________
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; 17th December 2020 at 14:46.
StainlessS is offline   Reply With Quote
Old 20th February 2021, 13:12   #10  |  Link
jordanh
Registered User
 
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 55
After lots of thinking, it now looks like an external application receiving the frames can only threat the frames as interlaced when the following conditions are met:
1) IsFieldBased() == true
2) IsBFF() or IsTFF() == true

Essentially that renders to IsParityKnown() == true.
The reason for IsFieldBased must be true (instead of isFrameBased) is that separatefields forces fieldbased and after weave we have framebased again. A single frame can only be "interlaced" from a 3rdparty app's perspective when both fields are contained in one frame. If the fields are in separate frames, (which means fieldbaesd from avisynth perspective) the material is progressive from 3rdparty perspective.
jordanh is offline   Reply With Quote
Old 21st February 2021, 23:23   #11  |  Link
jordanh
Registered User
 
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 55
as there have been internal questions about it, here some (hopefully) explainative images about it.
This example assumes the input file is 25i. This means that most source plugins like ffms will return the clip as framebased and progressive (even if it is actually interlaced).

Lets look at the Separatefields() function, assuming that the source plugin decides not to inform the environment about the field order (therefore we must analyze the source file on our own and set assumeTFF or BFF on our own)

Watch how the isFieldBased and/or isFrameBased flag behaves:



Looking at this first picture, if this "clip" is returned finally to the calling 3rdparty appliacation, the final clip is progressive, 50p and half height of the original source. Framebased == false



After Weave() we have 25i again. Framebased == true

Again, the FINALLY RETURNED PICTURE CAN ONLY BE INTERLACED from the receiveing 3rdparty applications perspective when it is FRAMEBASED. In the case it is FIELD based, it must automatically be progressive from the perspective of the application receiving the final frame.

i belive the trick here is to forget about how avisynth internally thinks about fields and interlacing and to focus on what the finally returned output clip looks like from perspective of the 3rdparty application.

Last edited by jordanh; 22nd February 2021 at 00:10.
jordanh 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 10:39.


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