View Full Version : Subframe and SeparateFields
Wilbert
11th March 2010, 23:12
Some questions about Subframe and SeparateFields:
PVideoFrame SeparateFields::GetFrame(int n, IScriptEnvironment* env)
{
PVideoFrame frame = child->GetFrame(n>>1, env);
if (vi.IsPlanar()) {
const bool topfield = (child->GetParity(n)+n)&1;
const int UVoffset = !topfield ? frame->GetPitch(PLANAR_U) : 0;
const int Yoffset = !topfield ? frame->GetPitch(PLANAR_Y) : 0;
return env->SubframePlanar(frame,Yoffset, frame->GetPitch()*2, frame->GetRowSize(), frame->GetHeight()>>1,
UVoffset, UVoffset, frame->GetPitch(PLANAR_U)*2);
}
return env->Subframe(frame,(GetParity(n) ^ vi.IsYUY2()) * frame->GetPitch(),
frame->GetPitch()*2, frame->GetRowSize(), frame->GetHeight()>>1);
}
Why is it not simply
if (vi.IsPlanar()) {
const bool topfield = child->GetParity(n);
...
and also
return env->Subframe(frame, GetParity(n) * frame->GetPitch(),
frame->GetPitch()*2, frame->GetRowSize(), frame->GetHeight()>>1);
What's so special with YUY2 compared to RGB?
Gavino
12th March 2010, 12:47
Why is it not simply
if (vi.IsPlanar()) {
const bool topfield = child->GetParity(n);
...
Because relative to child (the source clip), n is the field number, not the frame number.
However, I would expect it to be this->GetParity(n) (or just GetParity(n)) instead. Otherwise, source clips that have gone through a filter that re-orders parity on a per-frame basis (eg SelectEvery) will not give the right results.
What's so special with YUY2 compared to RGB?
RGB is stored 'upside-down', so for top fields you want line 1, not line 0.
IanB
12th March 2010, 21:39
const bool topfield = (child->GetParity(n)+n)&1;Yes this does seem a bit wrong, n exceeds the frame count of the child clip for the second half.
Given the GetParity code is thisinline bool __stdcall GetParity(int n) { return child->GetParity(n>>1) ^ (n&1); }and that it is used in the YUY2/RGB cases, I also think just GetParity(n) is what it should be.
Wilbert
13th March 2010, 00:48
It's all tricky stuff, but i agree with both of you. Strange that we didn't notice this before, because you get incorrect results.
Example: source = 2 frames (frame 0 = BFF, frame 1 = TFF):
2 frames => 4 fields (planar colorformat)
GetParity(n):
output: n=0 => GetParity(n>>1) ^ (n&1) = GetParity(0) ^ 0 = 0 ^ 0 = 0 (correct; since GetParity(0)=0=BFF)
output: n=1 => GetParity(n>>1) ^ (n&1) = GetParity(0) ^ 1 = 0 ^ 1 = 1 (correct)
output: n=2 => GetParity(n>>1) ^ (n&1) = GetParity(1) ^ 0 = 1 ^ 0 = 1 (correct; since GetParity(1)=1=TFF)
output: n=3 => GetParity(n>>1) ^ (n&1) = GetParity(1) ^ 1 = 1 ^ 1 = 0 (correct)
topfield = (child->GetParity(n)+n)&1;
output: n=0 => (0+0)&1 = 0 (correct)
output: n=1 => (1+1)&1 = 0 (wrong)
output: n=2 => (1+2)&1 = 1 (correct)
output: n=3 => (0+3)&1 = 1 (wrong)
You should get duplicate fields then, since the offsets are the same for every frame?
Btw, I still don't understand what happens when SubframePlanar is called. I'm looking at avisynth.cpp, but it is still a mistery. Could you explain it?
Gavino
13th March 2010, 11:41
Strange that we didn't notice this before, because you get incorrect results.
Example: source = 2 frames (frame 0 = BFF, frame 1 = TFF) ...
The reason you don't normally see a problem is that your example is unusual. Frame-based clips (the usual source material) normally have the same parity for every frame, since the entire clip is usually TFF or BFF. So GetParity(n) is independent of n and the error makes no difference.
The problem only shows up if an earlier filter has introduced a non-standard parity function, where the parity depends on the frame number.
Wilbert
13th March 2010, 14:32
The reason you don't normally see a problem is that your example is unusual. Frame-based clips (the usual source material) normally have the same parity for every frame, since the entire clip is usually TFF or BFF. So GetParity(n) is independent of n and the error makes no difference.
Ok, i see.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.