View Full Version : Increase the number of frames
slicktail
18th March 2010, 06:22
Hello! I am from Russia, and sorry from my bad Endlish.
I am developing plugin for interpolation frames.
PVideoFrame frame1 = child->GetFrame(n, env);
PVideoFrame frame2 = child->GetFrame(n+1, env);
I get 2 frame and I work with these frames.
I get information based on these 2 frames, and want to write this information in new frame.
Out frame i get with:
PVideoFrame out_frame = env->NewVideoFrame(vi);
But! I work with 2 frame and want to write information between 2 frames in 4-8 out_frames, but know whereby only in one outframe! however i may create it?
Gavino
18th March 2010, 11:06
Your filter's GetFrame function only delivers one frame at a time, as it is called once for every output frame, with the (output) frame number n. Using the value of n, it needs to determine the frame numbers of the two input frames it needs (eg n/4 and n/4 +1), and which of the interpolated frames to create (which might depend on n%4).
In the filter's constructor, you need to change vi.num_frames to the approprite number of output frames for the complete clip.
slicktail
18th March 2010, 12:19
Your filter's GetFrame function only delivers one frame at a time, as it is called once for every output frame, with the (output) frame number n. Using the value of n, it needs to determine the frame numbers of the two input frames it needs (eg n/4 and n/4 +1), and which of the interpolated frames to create (which might depend on n%4).
In the filter's constructor, you need to change vi.num_frames to the approprite number of output frames for the complete clip.
Thank you! please, write an example?
Gavino
18th March 2010, 12:48
Suppose you want to increase the framerate by a factor of 4, interpolating between input frames where necessary. Then output frame n corresponds to somewhere between input frames n/4 and n/4+1. So the logic of your GetFrame function is something like:
PVideoFrame frame1 = child->GetFrame(n/4, env);
PVideoFrame frame2 = child->GetFrame(n/4+1, env);
PVideoFrame out_frame = env->NewVideoFrame(vi);
// Now write output frame interpolating by the fraction (n%4)/4 between frame1 and frame2 ...
Of course, if n%4 is zero, you can just return frame1.
And if it's easier or faster to generate all the interpolated frames at the same time, you can keep a cache to avoid repeating the work on subsequent calls using the same input frames.
slicktail
19th March 2010, 05:30
Suppose you want to increase the framerate by a factor of 4, interpolating between input frames where necessary. Then output frame n corresponds to somewhere between input frames n/4 and n/4+1. So the logic of your GetFrame function is something like:
PVideoFrame frame1 = child->GetFrame(n/4, env);
PVideoFrame frame2 = child->GetFrame(n/4+1, env);
PVideoFrame out_frame = env->NewVideoFrame(vi);
// Now write output frame interpolating by the fraction (n%4)/4 between frame1 and frame2 ...
Of course, if n%4 is zero, you can just return frame1.
And if it's easier or faster to generate all the interpolated frames at the same time, you can keep a cache to avoid repeating the work on subsequent calls using the same input frames.
Thank you. But:
input Videofile contain 100 frames,example
if i use
PVideoFrame frame1 = child->GetFrame(n, env);
I get the output videofile which contain 100 frames.
if i use
PVideoFrame frame1 = child->GetFrame(n/4, env);
I get the output videofile which contain 100 frames, but only 1/4 input videofile. How much may i get all input videofile? (100*4 frames?)
Gavino
19th March 2010, 12:27
I get the output videofile which contain 100 frames, but only 1/4 input videofile. How much may i get all input videofile? (100*4 frames?)
As I said in my first reply: in the filter's constructor, you need to change vi.num_frames to the appropriate number of output frames for the complete clip. In this example, you would set
vi.num_frames = vi.num_frames * 4;
Depending on what you are trying to achieve (eg if you want the video duration to remain unchanged), you may need to change the framerate too.
slicktail
17th April 2010, 11:06
As I said in my first reply: in the filter's constructor, you need to change vi.num_frames to the appropriate number of output frames for the complete clip. In this example, you would set
vi.num_frames = vi.num_frames * 4;
Depending on what you are trying to achieve (eg if you want the video duration to remain unchanged), you may need to change the framerate too.
Thank you. I use
SquareClass2::SquareClass2(PClip _child) : GenericVideoFilter(_child){
vi.num_frames=vi.num_frames*N_intframe;
}
PVideoFrame frame1 = child->GetFrame(n/N_intframe, env);
PVideoFrame frame2 = child->GetFrame(((n/(N_intframe)+1)), env);
Between 2 neighbour frames paste N_intframe frames. But what do i need to do, what increase count of second in all videoframe? because, increase count of frame, count of second wasn't increasing.
Gavino
17th April 2010, 11:54
But what do i need to do, what increase count of second in all videoframe?
Add this to your constructor:
vi.MulDivFPS(N_intframe, 1);
This will multiply the frame rate by N_intframe.
slicktail
17th April 2010, 12:21
Add this to your constructor:
vi.MulDivFPS(N_intframe, 1);
This will multiply the frame rate by N_intframe.
This is similar vi.fps_numerator=vi.fps_numerator*N_intframe; ?
Gavino
17th April 2010, 13:00
Yes, just a bit more general (it can also do division) and robust (it will avoid potential overflow for large numerators/factors and reduce the resulting fraction to its simplest form).
vi.fps_numerator=vi.fps_numerator*N_intframe;
will work fine unless your input frame rate is a strange one like veryBigNumerator/veryBigDenominator, which might overflow on the multiplication.
You might find it helpful to look through avisynth.h to see all the functions you can use in your code.
slicktail
4th May 2010, 13:23
Ok. I want compare 2 video.
first video contain 30fps.
second video contain N*30fps.(N-interpolated frames).
PVideoFrame frame1 = child->GetFrame(n, env);
PVideoFrame frame2 = child2->GetFrame(n, env);
Example, N=4
However may I compare
frame1(0) vs frame2(0),frame2(1),frame2(2),frame2(3),frame2(4) - choose most similar
frame1(1) vs frame2(5),frame2(6),frame2(7),frame2(8),frame2(9) - choose most similar
etc...
?
Gavino
4th May 2010, 13:43
If I understand you correctly, you want to compare child->GetFrame(n, env) with each of
child2->GetFrame(N*n+i, env), for i=0 to N-1
or are you asking how to do the actual comparison, rather than how to get the frames?
slicktail
4th May 2010, 14:06
If I understand you correctly, you want to compare child->GetFrame(n, env) with each of
child2->GetFrame(N*n+i, env), for i=0 to N-1
or are you asking how to do the actual comparison, rather than how to get the frames?
If I understand you correctly, you want to compare child->GetFrame(n, env) with each of
child2->GetFrame(N*n+i, env), for i=0 to N-1
or are you asking how to do the actual comparison, rather than how to get the frames?
I asked about real-time compasion:
PVideoFrame __stdcall CompareClass::GetFrame(int n, IScriptEnvironment* env)
{
PVideoFrame frame1 = child->GetFrame(n, env);
PVideoFrame frame2= child2->GetFrame(N*n+i, env);
PVideoFrame out_frame = env->NewVideoFrame(vi);
//
frame1(0) vs frame2(0),frame2(1),frame2(2),frame2(3),frame2(4) - choose most similar
//
return out_frame;
}
How may sort out i?
Gavino
4th May 2010, 16:46
I still don't understand specifically what you are asking for.
Firstly, you need to decide what you mean by 'similar' and what you are going to use as a measure of 'similarity' between two frames. Possible candidates might be SAD (sum of absolute differences), or SSD (sum of squared differences). Then write code to compute this measure, cycle over the candidate frames and choose the one with the lowest 'difference'.
Or perhaps the above is already obvious to you, and you are having difficulty with a specific part of this process and how to code it in Avisynth? If so, which part?
slicktail
4th May 2010, 17:10
I still don't understand specifically what you are asking for.
Firstly, you need to decide what you mean by 'similar' and what you are going to use as a measure of 'similarity' between two frames. Possible candidates might be SAD (sum of absolute differences), or SSD (sum of squared differences). Then write code to compute this measure, cycle over the candidate frames and choose the one with the lowest 'difference'.
Or perhaps the above is already obvious to you, and you are having difficulty with a specific part of this process and how to code it in Avisynth? If so, which part?
Dear Gavino!
How similar two frames, I know. (I use SSD/SAD). Ploblem is however may i compare 4 frames (example) of first video and 1 frame of second video for one call
PVideoFrame __stdcall CompareClass::GetFrame(int n, IScriptEnvironment* env){}
Because in this function usually
PVideoFrame frame1 = child->GetFrame(n, env);
and then n=0,1,2..endFrame
Gavino
4th May 2010, 17:59
Thanks, I understand the question now. :)
Ploblem is however may i compare 4 frames (example) of first video and 1 frame of second video for one call
You simply call GetFrame as often as required to get all the frames you need for the comparison. Something like this:
PVideoFrame frame1 = child->GetFrame(n, env);
PVideoFrame frame2 = child2->GetFrame(N*n, env);
PVideoFrame out_frame = frame2;
int min_sad = ComputeSAD(frame1, frame2);
for (int i=1; i<N; i++) {
frame2 = child2->GetFrame(N*n+i, env);
int sad = ComputeSAD(frame1, frame2);
if (sad < min_sad) {
min_sad = sad;
out_frame = frame2;
}
}
return out_frame;
Here we compare one frame from child with each of N frames from child2 and return the most similar of the N frames.
slicktail
8th May 2010, 08:09
Thank you, Gavino! Everything is ok now!
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.