📄 avisynth.h
字号:
// return 9; case CS_Y8: return 8; default: return 8; } } int BytesPerChannelSample() const { switch (sample_type) { case SAMPLE_INT8: return sizeof(signed char); case SAMPLE_INT16: return sizeof(signed short); case SAMPLE_INT24: return 3; case SAMPLE_INT32: return sizeof(signed int); case SAMPLE_FLOAT: return sizeof(SFLOAT); default: _ASSERTE("Sample type not recognized!"); return 0; } } // useful mutator void SetFPS(unsigned numerator, unsigned denominator) { if ((numerator == 0) || (denominator == 0)) { fps_numerator = 0; fps_denominator = 1; } else { unsigned x=numerator, y=denominator; while (y) { // find gcd unsigned t = x%y; x = y; y = t; } fps_numerator = numerator/x; fps_denominator = denominator/x; } } // Range protected multiply-divide of FPS void MulDivFPS(unsigned multiplier, unsigned divisor) { unsigned __int64 numerator = UInt32x32To64(fps_numerator, multiplier); unsigned __int64 denominator = UInt32x32To64(fps_denominator, divisor); unsigned __int64 x=numerator, y=denominator; while (y) { // find gcd unsigned __int64 t = x%y; x = y; y = t; } numerator /= x; // normalize denominator /= x; unsigned __int64 temp = numerator | denominator; // Just looking top bit unsigned u = 0; while (temp & 0xffffffff80000000ULL) { // or perhaps > 16777216*2 temp = Int64ShrlMod32(temp, 1); u++; } if (u) { // Scale to fit const unsigned round = 1 << (u-1); SetFPS( (unsigned)Int64ShrlMod32(numerator + round, u), (unsigned)Int64ShrlMod32(denominator + round, u) ); } else { fps_numerator = (unsigned)numerator; fps_denominator = (unsigned)denominator; } } // Test for same colorspace bool IsSameColorspace(const VideoInfo& vi) const { if (vi.pixel_type == pixel_type) return TRUE; if (IsYV12() && vi.IsYV12()) return TRUE; return FALSE; }};// VideoFrameBuffer holds information about a memory block which is used// for video data. For efficiency, instances of this class are not deleted// when the refcount reaches zero; instead they're stored in a linked list// to be reused. The instances are deleted when the corresponding AVS// file is closed.class VideoFrameBuffer { BYTE* const data; const int data_size; // sequence_number is incremented every time the buffer is changed, so // that stale views can tell they're no longer valid. long sequence_number; friend class VideoFrame; friend class Cache;#ifdef AVS26 friend class CacheMT; // ::FIXME:: illegal class extension#endif friend class ScriptEnvironment; long refcount;public: VideoFrameBuffer(int size); VideoFrameBuffer(); ~VideoFrameBuffer(); const BYTE* GetReadPtr() const { return data; } BYTE* GetWritePtr() { ++sequence_number; return data; } int GetDataSize() { return data_size; } int GetSequenceNumber() { return sequence_number; } int GetRefcount() { return refcount; }};class IClip;class PClip;class PVideoFrame;class IScriptEnvironment;class AVSValue;// VideoFrame holds a "window" into a VideoFrameBuffer. Operator new// is overloaded to recycle class instances.class VideoFrame { int refcount; VideoFrameBuffer* const vfb; const int offset, pitch, row_size, height, offsetU, offsetV, pitchUV; // U&V offsets are from top of picture. int pixel_type; const int row_sizeUV, heightUV; friend class PVideoFrame; void AddRef() { InterlockedIncrement((long *)&refcount); } void Release() { if (refcount==1) InterlockedDecrement(&vfb->refcount); InterlockedDecrement((long *)&refcount); } friend class ScriptEnvironment; friend class Cache;#ifdef AVS26 friend class CacheMT; // ::FIXME:: illegal class extension#endif VideoFrame(VideoFrameBuffer* _vfb, int _offset, int _pitch, int _row_size, int _height, int pixel_type); VideoFrame(VideoFrameBuffer* _vfb, int _offset, int _pitch, int _row_size, int _height, int _offsetU, int _offsetV, int _pitchUV, int _row_sizeUV, int _heightUV, int pixel_type);#ifndef WIN64 void* operator new(unsigned size);#else void* operator new(size_t size);#endif// TESTME: OFFSET U/V may be switched to what could be expected from AVI standard!public: int GetPitch() const { return pitch; } int GetPitch(int plane) const { switch (plane) {case PLANAR_U: case PLANAR_V: return pitchUV;} return pitch; } int GetRowSize() const { return row_size; } int GetRowSize(int plane) const { switch (plane) {#ifdef AVS26 case PLANAR_U: case PLANAR_V: if (pitchUV) return row_sizeUV; else return 0; case PLANAR_U_ALIGNED: case PLANAR_V_ALIGNED: { int rUV = (row_sizeUV+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)); // Aligned rowsize if (rUV<=pitchUV) return rUV; return row_sizeUV; }#else case PLANAR_U: case PLANAR_V: if (pitchUV) return row_size>>1; else return 0; case PLANAR_U_ALIGNED: case PLANAR_V_ALIGNED: if (pitchUV) { int r = ((row_size+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)) )>>1; // Aligned rowsize if (r<=pitchUV) return r; return row_size>>1; } else return 0;#endif case PLANAR_Y_ALIGNED: int r = (row_size+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)); // Aligned rowsize if (r<=pitch) return r; return row_size; } return row_size; } int GetHeight() const { return height; }#ifdef AVS26 int GetHeight(int plane) const { switch (plane) {case PLANAR_U: case PLANAR_V: if (pitchUV) return heightUV; return 0;} return height; }#else int GetHeight(int plane) const { switch (plane) {case PLANAR_U: case PLANAR_V: if (pitchUV) return height>>1; return 0;} return height; }#endif // generally you shouldn't use these three VideoFrameBuffer* GetFrameBuffer() const { return vfb; } int GetOffset() const { return offset; } int GetOffset(int plane) const { switch (plane) {case PLANAR_U: return offsetU;case PLANAR_V: return offsetV;default: return offset;}; } // in plugins use env->SubFrame() //If you really want to use these remember to increase vfb->refcount before calling and decrement it afterwards. VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height) const; VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int pitchUV) const; const BYTE* GetReadPtr() const { return vfb->GetReadPtr() + offset; } const BYTE* GetReadPtr(int plane) const { return vfb->GetReadPtr() + GetOffset(plane); } bool IsWritable() const { return (refcount == 1 && vfb->refcount == 1); } BYTE* GetWritePtr() const { if (vfb->GetRefcount()>1) { _ASSERT(FALSE); //throw AvisynthError("Internal Error - refcount was more than one!"); } return IsWritable() ? (vfb->GetWritePtr() + offset) : 0; } BYTE* GetWritePtr(int plane) const { if (plane==PLANAR_Y) { if (vfb->GetRefcount()>1) { _ASSERT(FALSE);// throw AvisynthError("Internal Error - refcount was more than one!"); } return IsWritable() ? vfb->GetWritePtr() + GetOffset(plane) : 0; } return vfb->data + GetOffset(plane); } ~VideoFrame() { InterlockedDecrement(&vfb->refcount); }};enum { CACHE_NOTHING=0, CACHE_RANGE=1, CACHE_ALL=2, CACHE_AUDIO=3, CACHE_AUDIO_NONE=4 };// Base class for all filters.class IClip { friend class PClip; friend class AVSValue; int refcnt; void AddRef() { InterlockedIncrement((long *)&refcnt); } void Release() { InterlockedDecrement((long *)&refcnt); if (!refcnt) delete this; }public: IClip() : refcnt(0) {} virtual int __stdcall GetVersion() { return AVISYNTH_INTERFACE_VERSION; } virtual PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) = 0; virtual bool __stdcall GetParity(int n) = 0; // return field parity if field_based, else parity of first field in frame virtual void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) = 0; // start and count are in samples virtual void __stdcall SetCacheHints(int cachehints,int frame_range) = 0 ; // We do not pass cache requests upwards, only to the next filter. virtual const VideoInfo& __stdcall GetVideoInfo() = 0; virtual __stdcall ~IClip() {}};// smart pointer to IClipclass PClip { IClip* p; IClip* GetPointerWithAddRef() const { if (p) p->AddRef(); return p; } friend class AVSValue; friend class VideoFrame; void Init(IClip* x) { if (x) x->AddRef(); p=x; } void Set(IClip* x) { if (x) x->AddRef(); if (p) p->Release(); p=x; }public: PClip() { p = 0; } PClip(const PClip& x) { Init(x.p); } PClip(IClip* x) { Init(x); } void operator=(IClip* x) { Set(x); } void operator=(const PClip& x) { Set(x.p); } IClip* operator->() const { return p; } // useful in conditional expressions operator void*() const { return p; } bool operator!() const { return !p; } ~PClip() { if (p) p->Release(); }};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -