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. |
28th August 2015, 12:44 | #1 | Link |
Registered User
Join Date: Oct 2002
Location: France
Posts: 2,316
|
Question about source and destination in pluggin
I'm wondering something, because of VDub pluggin behavior.
In VDub pluggin, there is the FILTERPARAM_SWAP_BUFFERS parameter. If you use it, memory storage for source and destination will be differents. If you don't, source and destination pointers will be the same. How avisynth behave, when i'm doing something like this : Code:
PVideoFrame __stdcall AutoYUY2::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n,env); PVideoFrame dst = env->NewVideoFrame(vi); uint8_t *dstp = dst->GetWritePtr(PLANAR_Y); const uint8_t *srcYp = src->GetReadPtr(PLANAR_Y); |
29th August 2015, 12:41 | #4 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
With GetFrame() you need to use env->MakeWritable(&dst); before any writing (EDIT: Creates new frame and blits the contents of frame into the new writable one), best used where you are modifying just selected pixels or channels.
NewVideoFrame is already writable but you need to render all channels with valid data.
__________________
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; 29th August 2015 at 12:44. |
30th August 2015, 10:13 | #5 | Link |
Registered User
Join Date: Oct 2002
Location: France
Posts: 2,316
|
In my case, colorspace change, so using NewVideoFrame is obviously the correct way.
In case you eventualy don't need to create a new frame, i assume somthing like this would be the correct way : Code:
PVideoFrame __stdcall AutoYUY2::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame frame = child->GetFrame(n,env); const uint8_t *src = frame->GetReadPtr(PLANAR_Y); env->MakeWritable(&frame); uint8_t *dst=frame->GetWritePtr(PLANAR_Y); Last edited by jpsdr; 30th August 2015 at 10:15. |
30th August 2015, 12:16 | #6 | Link |
Angel of Night
Join Date: Nov 2004
Location: Tangled in the silks
Posts: 9,559
|
MakeWritable already works like vdub! The dest buffer is the same as source and you'd better keep track. It's NewVideoFrame that is the standard way that creates an entirely new canvas for you to write on.
But seriously, it's 2015. Memory is in vast supply and you can memory transfer one to two thousand frames a second at 1080p. Why would you ever need to use MakeWritable unless you're making a simple, small change to an existing image? Any full-frame processing would be better off writing to a new buffer to eliminate any possibility of bugs. (For instance, your idea of stride may not be the same as the buffer's.) |
1st September 2015, 09:47 | #7 | Link |
Registered User
Join Date: Oct 2002
Location: France
Posts: 2,316
|
Don't want to open another thread, more or less related...
If i want to know the size of the whole frame, should be multiplanar or not, is vi.BMPSize() the size of the whole frame ? If not, what is it ? I've not been able to see anything else that could provide this information in the avisynth.h. |
1st September 2015, 14:50 | #8 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
From Wiki here: http://avisynth.nl/index.php/Filter_..._API/VideoInfo
Code:
int BMPSize() const; For interleaved formats it will return the size of the frame in bytes where the width is rounded up to a multiple of 4 bytes. For planar formats it will do the same but only for the first plane. So, it's the number of bytes of a frame as it was a BMP frame. examples: 640x480 RGB24: BMPSize() = 480 * 3*640 = 921600 643x480 RGB24: BMPSize() = 480 * 3*644 = 927360 640x480 YV24: BMPSize() = 480 * 640 = 307200 643x480 YV24: BMPSize() = 480 * 644 = 309120 Since v5 the behavior for planar formats is the same as for interleaved formats. Code:
// struct VideoInfo &VideoInfo::BMPSize, // int (VideoInfo::*BMPSize)() const; Code:
/* Baked ******************** bool VideoInfo::IsVPlaneFirst() const {return ((pixel_type & CS_YV12) == CS_YV12); } // Don't use this int VideoInfo::BytesFromPixels(int pixels) const { return pixels * (BitsPerPixel()>>3); } // Will not work on planar images, but will #return only luma planes int VideoInfo::RowSize() const { return BytesFromPixels(width); } // Also only returns first plane on planar images int VideoInfo::BMPSize() const { if (IsPlanar()) {int p = height * ((RowSize()+3) & ~3); p+=p>>1; return p; } return height * ((RowSize()+3) & ~3); } __int64 VideoInfo::AudioSamplesFromFrames(__int64 frames) const { return (fps_numerator && HasVideo()) ? ((__int64)(frames) * audio_samples_per_second * fps_denominator / fps_numerator) : 0; } Baked ********************/ Code:
int VideoInfo::BMPSize() const { if (!IsY8() && IsPlanar()) { // Y plane const int Ybytes = ((RowSize(PLANAR_Y)+3) & ~3) * height; const int UVbytes = Ybytes >> (GetPlaneWidthSubsampling(PLANAR_U)+GetPlaneHeightSubsampling(PLANAR_U)); return Ybytes + UVbytes*2; } return height * ((RowSize()+3) & ~3); } Code:
int VideoInfo::RowSize(int plane) const { const int rowsize = BytesFromPixels(width); switch (plane) { case PLANAR_U: case PLANAR_V: return (!IsY8() && IsPlanar()) ? rowsize>>GetPlaneWidthSubsampling(plane) : 0; case PLANAR_U_ALIGNED: case PLANAR_V_ALIGNED: return (!IsY8() && IsPlanar()) ? ((rowsize>>GetPlaneWidthSubsampling(plane))+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)) : 0; // Aligned rowsize case PLANAR_Y_ALIGNED: return (rowsize+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)); // Aligned rowsize } return rowsize; } ... int VideoInfo::GetPlaneWidthSubsampling(int plane) const { // Subsampling in bitshifts! if (plane == PLANAR_Y) // No subsampling return 0; if (IsY8()) throw AvisynthError("Filter error: GetPlaneWidthSubsampling not available on Y8 pixel type."); if (plane == PLANAR_U || plane == PLANAR_V) { if (IsYUY2()) return 1; else if (IsPlanar()) return ((pixel_type>>CS_Shift_Sub_Width)+1) & 3; else throw AvisynthError("Filter error: GetPlaneWidthSubsampling called with unsupported pixel type."); } throw AvisynthError("Filter error: GetPlaneWidthSubsampling called with unsupported plane."); } ... int VideoInfo::GetPlaneHeightSubsampling(int plane) const { // Subsampling in bitshifts! if (plane == PLANAR_Y) // No subsampling return 0; if (IsY8()) throw AvisynthError("Filter error: GetPlaneHeightSubsampling not available on Y8 pixel type."); if (plane == PLANAR_U || plane == PLANAR_V) { if (IsYUY2()) return 0; else if (IsPlanar()) return ((pixel_type>>CS_Shift_Sub_Height)+1) & 3; else throw AvisynthError("Filter error: GetPlaneHeightSubsampling called with unsupported pixel type."); } throw AvisynthError("Filter error: GetPlaneHeightSubsampling called with supported plane."); } Also note, pitch can change at every frame due to eg crop and interleave.
__________________
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; 1st September 2015 at 15:05. |
|
|