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. |
23rd September 2002, 17:04 | #21 | Link |
Vlad, the Buffy slayer
Join Date: Oct 2001
Location: France
Posts: 445
|
@MarcFD
Of course as it's the first planar format in avisynth we'll have to change a little bit the architecture. But I think we have to use a maximum current avisynth code when possible to use stable code a maximum. I personnaly it's a good idea to keep only one VideoFrameBuffer* in VideoFrame so we don't have to change anything in cache specific code. For now we just have to be talk about new functions of VideoFrame not the internal code (wich can evolve in the future). So my proposition is : Code:
class VideoFrame { int refcount; VideoFrameBuffer* const vfb; const int offset, pitch, row_size, height; friend class PVideoFrame; void AddRef() { ++refcount; } void Release() { if (refcount==1) --vfb->refcount; --refcount; } friend class ScriptEnvironment; friend class Cache; VideoFrame(VideoFrameBuffer* _vfb, int _offset, int _pitch, int _row_size, int _height); void* operator new(unsigned size); public: int GetPitch() const { return pitch; } int GetYPitch () const {return pitch;} int GetUPitch () const {return pitch>>1;} int GetVPitch () const {return pitch>>1;} // we could have done a int GetUVPitch () const {return pitch>>1;} int GetRowSize() const { return row_size; } int GetHeight() const { return height; } // generally you shouldn't use these two VideoFrameBuffer* GetFrameBuffer() const { return vfb; } int GetOffset() const { return offset; } // in plugins use env->SubFrame() VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height) const; const BYTE* GetReadPtr() const { return vfb->GetReadPtr() + offset; } const BYTE* GetReadPtr(BYTE p_channel) const { return vfb->GetReadPtr() + ???? (to be defined); } bool IsWritable() const { return (refcount == 1 && vfb->refcount == 1); } BYTE* GetWritePtr() const { return IsWritable() ? (vfb->GetWritePtr() + offset) : 0; } ~VideoFrame() { --vfb->refcount; } }; The problem will be eventually with U or V pointer wich could be only 2bytes aligned depending of the cropping values. EDIT : Sorry Sh0dan and MarcFd I've waited too long before send my answer, I haven't read your last posts. I also forgot to check for pixel_type in specific Get_Pitch.
__________________
Vlad59 Convolution3D for avisynth 2.0X : http://www.hellninjacommando.com/con3d Convolution3D for avisynth 2.5 : http://www.hellninjacommando.com/con3d/beta Last edited by vlad59; 23rd September 2002 at 17:13. |
23rd September 2002, 17:31 | #22 | Link |
XviD fan
Join Date: Jun 2002
Location: France
Posts: 907
|
the question is :
do you want YUV 4:2:0 (I420/YV12) planar support in avisynth (3 blocks), or you just want block YV12 (1 block) ?? i'd prefer full planar support. (XviD/ffdshow/MPEG2Dec/ect.. uses full YUV 4:2:0 _planar_ format) i don't know how to use polymorphism in C++, but if it's like in Delphi, should be possible to implement a child of VideoFrame, like PlanarVideoFrame, and then use it if you have YV12 colorspace, no ?? maybe it's impossible Last edited by Marc FD; 23rd September 2002 at 17:33. |
23rd September 2002, 17:42 | #23 | Link | ||
Retired AviSynth Dev ;)
Join Date: Nov 2001
Location: Dark Side of the Moon
Posts: 3,480
|
Quote:
Quote:
As now, you cannot write to the pointers yourself, you can only request an empty frame and write to it. If you want 3 pointers, you have to request three pointers, my point is, that you could do this by only requesting one (as now), and easily calculate the rest yourself. Therefore we can force data to be continuous, I can't see any real arguments for not having this, honestly.
__________________
Regards, sh0dan // VoxPod |
||
23rd September 2002, 17:52 | #24 | Link | |
Retired AviSynth Dev ;)
Join Date: Nov 2001
Location: Dark Side of the Moon
Posts: 3,480
|
Quote:
Code:
class VideoFrame { int refcount; VideoFrameBuffer* const vfb; const int offset, pitch, row_size, height, int UV_pitch; friend class PVideoFrame; void AddRef() { ++refcount; } void Release() { if (refcount==1) --vfb->refcount; --refcount; } friend class ScriptEnvironment; friend class Cache; VideoFrame(VideoFrameBuffer* _vfb, int _offset, int _pitch, int _row_size, int _height); void* operator new(unsigned size); enum {YV12_CHANNEL_Y=0;YV12_CHANNEL_U=1;YV12_CHANNEL_V=2}; // for planar modes only. public: int GetPitch() const { return pitch; } int GetYPitch () const {return pitch;} int GetUVPitch () const {return uv_pitch;} int GetRowSize() const { return row_size; } int GetHeight() const { return height; } // generally you shouldn't use these two VideoFrameBuffer* GetFrameBuffer() const { return vfb; } int GetOffset() const { return offset; } // in plugins use env->SubFrame() VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height) const; const BYTE* GetReadPtr() const { return vfb->GetReadPtr() + offset; } const BYTE* GetReadPtr(BYTE p_channel) const { switch (p_channel) { case YV12_CHANNEL_Y: return vfb->GetReadPtr(); case YV12_CHANNEL_U: return vfb->GetReadPtr()+(height*pitch); case YV12_CHANNEL_V: return vfb->GetReadPtr()+(height*pitch)+((height>>1)*uv_pitch); default: _ASSERT(FALSE); } return vfb->GetReadPtr(); } bool IsWritable() const { return (refcount == 1 && vfb->refcount == 1); } BYTE* GetWritePtr() const { return IsWritable() ? (vfb->GetWritePtr() + offset) : 0; } ~VideoFrame() { --vfb->refcount; } }; [EDIT]"Full planar" is still possible, since the enums just could be expanded - perhaps the GetPitch should also be like this: Code:
int GetPitch (BYTE p_channel) const { switch (p_channel) { case YV12_CHANNEL_Y: return pitch; case YV12_CHANNEL_U: return uv_pitch; case YV12_CHANNEL_V: return uv_pitch; default: _ASSERT(FALSE); } return uv_pitch; }
__________________
Regards, sh0dan // VoxPod Last edited by sh0dan; 23rd September 2002 at 17:57. |
|
23rd September 2002, 17:55 | #25 | Link |
Kilted Yaksman
Join Date: Oct 2001
Location: South Carolina
Posts: 1,303
|
do you want YUV 4:2:0 (I420/YV12) planar support in avisynth (3 blocks), or you just want block YV12 (1 block) ??
Remember, the only reason that programs like DVD2AVI/MPEG2DEC/XviD/libavcodec use separate planes is because of the image edging that the MPEG standards necessitate. Any program that desires YV12 input is going to want it in a single block, and will output it as a similar block, since that's what the standard requires (see hardware overlay support for why this is important). If you want SSE2-compatible alignment, you could do that with a single block by aligning it on 32 bytes, giving the UV planes 16-byte alignment. I guess my biggest qualm with separate blocks is that you will have to blit the input into separate buffers at the start, then blit it back into a single block at the end, when you could avoid both. Though you could resolve this by making sure any yv12 input source is block-aware, and fills the pointers for you (i.e. a special build of mpeg2dec or something). -h |
23rd September 2002, 18:04 | #26 | Link | |
XviD fan
Join Date: Jun 2002
Location: France
Posts: 907
|
Quote:
i've taken a look in the avisynth internals (the first time i do this ) and i see know what you think. it make sense for me now sorry if i didn't understood you immediatly Okay, so when we use I420 colorspace with a bit alignement. you need a new pitch,row_size and height. my suggestion Code:
class VideoFrame { int refcount; VideoFrameBuffer* const vfb; const int offset, pitch, row_size, height; const int pitch2, row_size2, height2; // needed for I420 alignement friend class PVideoFrame; void AddRef() { ++refcount; } void Release() { if (refcount==1) --vfb->refcount; --refcount; } friend class ScriptEnvironment; friend class Cache; VideoFrame(VideoFrameBuffer* _vfb, int _offset, int _pitch, int _row_size, int _height); void* operator new(unsigned size); public: int GetPitch() const { return pitch; } int GetPitch2() const {return pitch2;} int GetRowSize() const { return row_size; } int GetRowSize2() const { return row_size2; } int GetHeight() const { return height; } int GetHeight2() const { return height2; } // generally you shouldn't use these two VideoFrameBuffer* GetFrameBuffer() const { return vfb; } int GetOffset() const { return offset; } // in plugins use env->SubFrame() VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height) const; const BYTE* GetReadPtr() const { return vfb->GetReadPtr() + offset; } const BYTE* GetReadPtr(BYTE plane) const { if (plane==Y_PLANE) { return vfb->GetReadPtr() + offset; } else if (plane==U_PLANE) { return vfp->GetReadPtr() + offset + pitch*height(+alignement trick) } else if (plane==V_PLANE) { return vfp->GetReadPtr() + offset + pitch*height(+alignement trick) + pitch2*height2(+alignement trick) } else { return vfb->GetReadPtr() + offset; // default } } vfp->GetReadPtr() + offset + pitch*height + pitch2*height2 + bool IsWritable() const { return (refcount == 1 && vfb->refcount == 1); } BYTE* GetWritePtr() const { return IsWritable() ? (vfb->GetWritePtr() + offset) : 0; } ~VideoFrame() { --vfb->refcount; } }; EDIT : sorry didn't see yours Last edited by Marc FD; 23rd September 2002 at 18:07. |
|
23rd September 2002, 18:14 | #27 | Link | |
Vlad, the Buffy slayer
Join Date: Oct 2001
Location: France
Posts: 445
|
Quote:
And it must also be the same with GetWritePtr. About GetWritePtr I think we will be obliged to provide standard function to copy one plane as Bitblt will copy the three planes. @MarcFD I globally agree with your code example (althought I prefer uv_pitch than pitch2 ). But IMHO height2 and rowsize2 are not usefull as height2 = height/2 and rowsize2 = rowsize/2 Instead we need specific offset for U and V plane (to crop and keep correct alignment). I'll have to think more about it.
__________________
Vlad59 Convolution3D for avisynth 2.0X : http://www.hellninjacommando.com/con3d Convolution3D for avisynth 2.5 : http://www.hellninjacommando.com/con3d/beta Last edited by vlad59; 23rd September 2002 at 18:33. |
|
23rd September 2002, 18:17 | #28 | Link |
Retired AviSynth Dev ;)
Join Date: Nov 2001
Location: Dark Side of the Moon
Posts: 3,480
|
@marcfd:
- Pitches are already aligned - no need to adjust them. Consider pitches aligned widths. - No need for seperate height and row-size - they are always half of the Y-original. - We should use existing naming convensions. In half a year, people will wonder what the difference is between GetPitch() and GetPitch2() - avisynth.h should be as meaningful as possible.
__________________
Regards, sh0dan // VoxPod |
23rd September 2002, 18:19 | #29 | Link | |
XviD fan
Join Date: Jun 2002
Location: France
Posts: 907
|
Quote:
yes of course you don't need them. uv_pitch is not bad but then y_pitch is logical. it's why i prefer the pitch/pitch2 pair or (compromise) a pitch/pitchUV |
|
23rd September 2002, 18:35 | #30 | Link | |
Retired AviSynth Dev ;)
Join Date: Nov 2001
Location: Dark Side of the Moon
Posts: 3,480
|
Quote:
Wouldn't this hold up? Or is my math bad? Code:
const BYTE* GetReadPtr(BYTE p_channel) const { switch (p_channel) { case YV12_CHANNEL_Y: return vfb->GetReadPtr(); case YV12_CHANNEL_U: return vfb->GetReadPtr()+(height*pitch)+(offset>>2); case YV12_CHANNEL_V: return vfb->GetReadPtr()+(height*pitch)+(offset>>1)+((height>>1)*uv_pitch); default: _ASSERT(FALSE); }
__________________
Regards, sh0dan // VoxPod |
|
23rd September 2002, 19:09 | #31 | Link | |
Vlad, the Buffy slayer
Join Date: Oct 2001
Location: France
Posts: 445
|
Quote:
Code:
const BYTE* GetReadPtr(BYTE p_channel) const { switch (p_channel) { case YV12_CHANNEL_Y: return vfb->GetReadPtr() + offset; // at least I'm sure of that case YV12_CHANNEL_U: return vfb->GetReadPtr+(height*(pitch + offset))+(offset>>1); case YV12_CHANNEL_V: return vfb->GetReadPtr()+(height*(pitch + offset))+((height>>1)*(uv_pitch + offset>>1))+ offset>>1; default: _ASSERT(FALSE); } I'm not 100% sure. But I think it's correct (I'm often wrong ). We must also add some check to allow the use of this function only with YV12. So I have many questions : in Code:
enum { UNKNOWN=0, BGR24=0x13, BGR32=0x14, YUY2=0x22, YV12=0x?? }; 0x2? to make isYUV answer true or 0x3? to make a future isPlanar answer true With we should have : Code:
const BYTE* GetReadPtr(BYTE p_channel) const { if (!(pixel_type&0x30)) Throw error or if (pixel_type != YV12) Throw error Lots of things to think about EDIT : @Sh0dan forget about my correction, it's wrong I have misunderstood the use of offset, sorry
__________________
Vlad59 Convolution3D for avisynth 2.0X : http://www.hellninjacommando.com/con3d Convolution3D for avisynth 2.5 : http://www.hellninjacommando.com/con3d/beta Last edited by vlad59; 23rd September 2002 at 19:11. |
|
23rd September 2002, 19:43 | #32 | Link | ||||
Retired AviSynth Dev ;)
Join Date: Nov 2001
Location: Dark Side of the Moon
Posts: 3,480
|
Quote:
YPitch = 100 UVPitch = 50 We crop: top = 4 pixels, left= 6 pixels. Y offset = (4 * 1 byte * Ypitch) + 6 * 1 byte = 406 bytes (not mod4 <shivers>) U offset = (4 pixels * 1 byte * UVpitch)/2 + (6 pixels * 1 byte) /2 = 103 Surprise! None of us was right. Conclusion - we need to store one offset for Y and one for each U and V. Quote:
Quote:
So: Code:
enum { ISBGR=1<<1, ISYUV=1<<2, ISPLANAR=1<<3 }; Quote:
I hope you all see why we can't rush into doing YV12 - there are many considerations we have to do before implementing it.
__________________
Regards, sh0dan // VoxPod |
||||
23rd September 2002, 19:55 | #33 | Link | ||
XviD fan
Join Date: Jun 2002
Location: France
Posts: 907
|
Quote:
4:2:0 -> 0x420 / 4:2:2 -> 0x422 / 4:4:4 -> 0x444 it makes sense ?? Quote:
let's discuss of everything we need |
||
23rd September 2002, 21:35 | #34 | Link | |||
Vlad, the Buffy slayer
Join Date: Oct 2001
Location: France
Posts: 445
|
Quote:
Quote:
So we could have Code:
enum { UNKNOWN=0, BGR24=0x013, BGR32=0x014, YUY2=0x022, YV12=0x122 }; But MarcFD's idea is a good one too. we really need to share our ideas Quote:
I need some sleep after that
__________________
Vlad59 Convolution3D for avisynth 2.0X : http://www.hellninjacommando.com/con3d Convolution3D for avisynth 2.5 : http://www.hellninjacommando.com/con3d/beta |
|||
23rd September 2002, 21:59 | #35 | Link |
Retired AviSynth Dev ;)
Join Date: Nov 2001
Location: Dark Side of the Moon
Posts: 3,480
|
A little OT. Took some time, and finished first proposal for new sample support in 2.1, with float samples and multiple channels. It compiles, and has AVI in/out working. Some audio filters have been converted, but not tested. Plugins seems to be a problem - we'll have to see about that - they seem to break sound(?)
Most interesting changes are in avisynth.h You can see the branch at: http://cvs.sourceforge.net/cgi-bin/v...g=avisynth_2_1
__________________
Regards, sh0dan // VoxPod |
Thread Tools | Search this Thread |
Display Modes | |
|
|