Log in

View Full Version : MakeWritable and hidden bitblts


kassandro
19th April 2005, 08:02
Does env->MakeWritable(&df) trigger an internal bitblt, if the Avisynths cache is enabled and can this bitblt be avoided if child->SetCacheHints(CACHE_NOTHING, 0) is called in the filter contructor?

esby
19th April 2005, 15:34
src/core/avisynth.cpp


bool ScriptEnvironment::MakeWritable(PVideoFrame* pvf) {
const PVideoFrame& vf = *pvf;
// If the frame is already writable, do nothing.
if (vf->IsWritable()) {
return false;
}

// Otherwise, allocate a new frame (using NewVideoFrame) and
// copy the data into it. Then modify the passed PVideoFrame
// to point to the new buffer.
const int row_size = vf->GetRowSize();
const int height = vf->GetHeight();
PVideoFrame dst;
if (vf->GetPitch(PLANAR_U)) { // we have no videoinfo, so we can only assume that it is Planar
dst = NewPlanarVideoFrame(row_size, height, FRAME_ALIGN,false); // Always V first on internal images
} else {
dst = NewVideoFrame(row_size, height, FRAME_ALIGN);
}
BitBlt(dst->GetWritePtr(), dst->GetPitch(), vf->GetReadPtr(), vf->GetPitch(), row_size, height);
// Blit More planes (pitch, rowsize and height should be 0, if none is present)
BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V), vf->GetReadPtr(PLANAR_V), vf->GetPitch(PLANAR_V), vf->GetRowSi
ze(PLANAR_V), vf->GetHeight(PLANAR_V));
BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U), vf->GetReadPtr(PLANAR_U), vf->GetPitch(PLANAR_U), vf->GetRowSi
ze(PLANAR_U), vf->GetHeight(PLANAR_U));

*pvf = dst;
return true;
}



So obviously a bitblt() is triggered, except if the frame is already writable, meaning it has been created and cached and/or reused.

But I guess that for what you are asking, the setCache() does not avoid to trigger any bitblt() code, as you still need to create a frame.

So what do you want to do exactly?

esby

kassandro
24th April 2005, 18:04
Thanks for the (disappointing) information. I think that Avisynth could be smarter. If the cache is disabled with child->SetCacheHints(CACHE_NOTHING, 0), then it should be clear that the frame is not requested again. Thus there is no need to keep a copy in this case.

sh0dan
24th April 2005, 18:12
...but other filters may have the same input, thus requiering a writeable frame. Consider this script:

v=avisource()
a=yourfilter(v)
b=anotherfilter(v)

return overlay(a,b)

Both yourfilter() and antherfiler() will request the same frame from the source. If both make them writable a bitblit is inavoidable.

kassandro
25th April 2005, 07:28
Originally posted by sh0dan
...but other filters may have the same input, thus requiering a writeable frame. Consider this script:

v=avisource()
a=yourfilter(v)
b=anotherfilter(v)

return overlay(a,b)

Both yourfilter() and antherfiler() will request the same frame from the source. If both make them writable a bitblit is inavoidable.
Good argument. On the other hand, if "yourfilter" uses child->SetCacheHints(CACHE_RANGE, 1) and 1 is too tight for "anotherfilter", then we have the same problem: a frame has to be processed twice. Cache hints are bad, if frames are requested from more than one filter. The Avisynth script parser, could control this, but this would add unpleasant complexity. I would suggest the following: if a clip receives more than one cache hint, it should ignore all the cache hints and persue the default strategy "cache as much as you can" (or a smarter variant). As a consequence, any filter should issue cache hints to clips, which it wants to use. If a filter doesn't do this, it shouldn't wonder about poor performance. Then, if child->SetCacheHints(CACHE_NOTHING, 0) is the only cache hint, MakeWritable should not make bitblt. If there is a chain of such filters, then we could not only save bitblts, but even could keep the frame throughout the processing in the L2 cache, if it is large enough, say 1 or 2 MB.

Bidoche
25th April 2005, 20:45
Originally posted by kassandro
The Avisynth script parser, could control this, but this would add unpleasant complexity. I would suggest the following: if a clip receives more than one cache hint, it should ignore all the cache hints and persue the default strategy "cache as much as you can" (or a smarter variant).I took that into account when designing 3.0 Cache : It use an adaptive heuristic, ie it detects missed cache opportunities to adapt cache size.

kassandro
27th April 2005, 08:28
Originally posted by Bidoche
I took that into account when designing 3.0 Cache : It use an adaptive heuristic, ie it detects missed cache opportunities to adapt cache size.
The adapative heuristic, is it adaptive enough, such that makewritable is without a bitblt, if a frame is requested only once?

Bidoche
27th April 2005, 23:51
Originally posted by kassandro
The adaptive heuristic, is it adaptive enough, such that makewritable is without a bitblt, if a frame is requested only once? All Caches start with caching nothing, and it only grows if the cache detects it is missing opportunities.

So in your case, cache sizes never grow, and MakeWritable will never blit.
(though there is no more MakeWritable, it is implicitly done for you)