home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / Multimedia / AVStoDVD / AVStoDVD_280_Install.exe / AVSMeter / source / avisynth25.h next >
C/C++ Source or Header  |  2014-09-14  |  29KB  |  782 lines

  1. // Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.
  2. // http://www.avisynth.org
  3.  
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
  17. // http://www.gnu.org/copyleft/gpl.html .
  18. //
  19. // Linking Avisynth statically or dynamically with other modules is making a
  20. // combined work based on Avisynth.  Thus, the terms and conditions of the GNU
  21. // General Public License cover the whole combination.
  22. //
  23. // As a special exception, the copyright holders of Avisynth give you
  24. // permission to link Avisynth with independent modules that communicate with
  25. // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
  26. // terms of these independent modules, and to copy and distribute the
  27. // resulting combined work under terms of your choice, provided that
  28. // every copy of the combined work is accompanied by a complete copy of
  29. // the source code of Avisynth (the version of Avisynth used to produce the
  30. // combined work), being distributed under the terms of the GNU General
  31. // Public License plus this exception.  An independent module is a module
  32. // which is not derived from or based on Avisynth, such as 3rd-party filters,
  33. // import and export plugins, or graphical user interfaces.
  34.  
  35.  
  36.  
  37.  
  38.  
  39. #ifndef __AVISYNTH_H__
  40. #define __AVISYNTH_H__
  41.  
  42. #pragma warning(disable : 279)
  43.  
  44. enum {AVISYNTH_INTERFACE_VERSION = 3};
  45.  
  46.  
  47. /* Define all types necessary for interfacing with avisynth.dll
  48.    Moved from internal.h */
  49.  
  50. // Win32 API macros, notably the types BYTE, DWORD, ULONG, etc.
  51. #include <windef.h>
  52.  
  53. // COM interface macros
  54. #include <objbase.h>
  55.  
  56.  
  57. // Raster types used by VirtualDub & Avisynth
  58. #define in64 (__int64)(unsigned short)
  59. typedef unsigned long    Pixel;    // this will break on 64-bit machines!
  60. typedef unsigned long    Pixel32;
  61. typedef unsigned char    Pixel8;
  62. typedef long            PixCoord;
  63. typedef long            PixDim;
  64. typedef long            PixOffset;
  65.  
  66.  
  67. /* Compiler-specific crap */
  68.  
  69. // Tell MSVC to stop precompiling here
  70. #ifdef _MSC_VER
  71.   #pragma hdrstop
  72. #endif
  73.  
  74. // Set up debugging macros for MS compilers; for others, step down to the
  75. // standard <assert.h> interface
  76. #ifdef _MSC_VER
  77.   #include <crtdbg.h>
  78. #else
  79.   #define _RPT0(a,b) ((void)0)
  80.   #define _RPT1(a,b,c) ((void)0)
  81.   #define _RPT2(a,b,c,d) ((void)0)
  82.   #define _RPT3(a,b,c,d,e) ((void)0)
  83.   #define _RPT4(a,b,c,d,e,f) ((void)0)
  84.  
  85.   #define _ASSERTE(x) assert(x)
  86.   #include <assert.h>
  87. #endif
  88.  
  89.  
  90.  
  91. // I had problems with Premiere wanting 1-byte alignment for its structures,
  92. // so I now set the Avisynth struct alignment explicitly here.
  93. #pragma pack(push,8)
  94.  
  95. #define FRAME_ALIGN 16
  96. // Default frame alignment is 16 bytes, to help P4, when using SSE2
  97.  
  98. // The VideoInfo struct holds global information about a clip (i.e.
  99. // information that does not depend on the frame number).  The GetVideoInfo
  100. // method in IClip returns this struct.
  101.  
  102. // Audio Sample information
  103. typedef float SFLOAT;
  104.  
  105. enum {SAMPLE_INT8  = 1<<0,
  106.       SAMPLE_INT16 = 1<<1,
  107.       SAMPLE_INT24 = 1<<2,    // Int24 is a very stupid thing to code, but it's supported by some hardware.
  108.       SAMPLE_INT32 = 1<<3,
  109.       SAMPLE_FLOAT = 1<<4};
  110.  
  111. enum {
  112.    PLANAR_Y=1<<0,
  113.    PLANAR_U=1<<1,
  114.    PLANAR_V=1<<2,
  115.    PLANAR_ALIGNED=1<<3,
  116.    PLANAR_Y_ALIGNED=PLANAR_Y|PLANAR_ALIGNED,
  117.    PLANAR_U_ALIGNED=PLANAR_U|PLANAR_ALIGNED,
  118.    PLANAR_V_ALIGNED=PLANAR_V|PLANAR_ALIGNED,
  119.   };
  120.  
  121. class AvisynthError /* exception */ {
  122. public:
  123.   const char* const msg;
  124.   AvisynthError(const char* _msg) : msg(_msg) {}
  125. };
  126.  
  127. struct VideoInfo {
  128.   int width, height;    // width=0 means no video
  129.   unsigned fps_numerator, fps_denominator;
  130.   int num_frames;
  131.   // This is more extensible than previous versions. More properties can be added seeminglesly.
  132.  
  133.   // Colorspace properties.
  134.   enum {
  135.     CS_BGR = 1<<28,
  136.     CS_YUV = 1<<29,
  137.     CS_INTERLEAVED = 1<<30,
  138.     CS_PLANAR = 1<<31,
  139.         CS_Shift_Sub_Width   =  0,
  140.         CS_Shift_Sub_Height  =  8,
  141.         CS_Sub_Width_Mask    = 7 << CS_Shift_Sub_Width,
  142.         CS_Sub_Width_1       = 3 << CS_Shift_Sub_Width, // YV24
  143.     CS_Sub_Width_2       = 0 << CS_Shift_Sub_Width, // YV12, I420, YV16
  144.     CS_Sub_Width_4       = 1 << CS_Shift_Sub_Width, // YUV9, YV411
  145.     CS_VPlaneFirst       = 1 << 3, // YV12, YV16, YV24, YV411, YUV9
  146.     CS_UPlaneFirst       = 1 << 4, // I420
  147.         CS_Sub_Height_Mask   = 7 << CS_Shift_Sub_Height,
  148.         CS_Sub_Height_1      = 3 << CS_Shift_Sub_Height, // YV16, YV24, YV411
  149.         CS_Shift_Sample_Bits = 16,
  150.         CS_Sample_Bits_Mask  = 7 << CS_Shift_Sample_Bits,
  151.         CS_Sample_Bits_8     = 0 << CS_Shift_Sample_Bits,
  152.         CS_PLANAR_MASK = CS_PLANAR | CS_INTERLEAVED | CS_YUV | CS_BGR | CS_Sample_Bits_Mask | CS_Sub_Height_Mask | CS_Sub_Width_Mask,
  153.         CS_PLANAR_FILTER     = ~( CS_VPlaneFirst | CS_UPlaneFirst ),
  154.         CS_YV411 = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Height_1 | CS_Sub_Width_4,  // YUV 4:1:1 planar
  155.         CS_YV24  = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Height_1 | CS_Sub_Width_1,  // YUV 4:4:4 planar
  156.     CS_YV16  = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Height_1 | CS_Sub_Width_2,  // YUV 4:2:2 planar
  157.         CS_Y8    = CS_PLANAR | CS_INTERLEAVED | CS_YUV | CS_Sample_Bits_8                                     // Y   4:0:0 planar
  158.   };
  159.  
  160.   // Specific colorformats
  161.   enum { CS_UNKNOWN = 0,
  162.          CS_BGR24 = 1<<0 | CS_BGR | CS_INTERLEAVED,
  163.          CS_BGR32 = 1<<1 | CS_BGR | CS_INTERLEAVED,
  164.          CS_YUY2  = 1<<2 | CS_YUV | CS_INTERLEAVED,
  165.          CS_YV12  = 1<<3 | CS_YUV | CS_PLANAR,  // y-v-u, 4:2:0 planar
  166.          CS_I420  = 1<<4 | CS_YUV | CS_PLANAR,  // y-u-v, 4:2:0 planar
  167.          CS_IYUV  = 1<<4 | CS_YUV | CS_PLANAR,  // same as above
  168.   };
  169.   int pixel_type;                // changed to int as of 2.5
  170.  
  171.  
  172.   int audio_samples_per_second;   // 0 means no audio
  173.   int sample_type;                // as of 2.5
  174.   __int64 num_audio_samples;      // changed as of 2.5
  175.   int nchannels;                  // as of 2.5
  176.  
  177.   // Imagetype properties
  178.  
  179.   int image_type;
  180.  
  181.   enum {
  182.     IT_BFF = 1<<0,
  183.     IT_TFF = 1<<1,
  184.     IT_FIELDBASED = 1<<2
  185.   };
  186.  
  187.   // useful functions of the above
  188.     bool IsYV411() const { return (pixel_type & CS_PLANAR_MASK) == (CS_YV411 & CS_PLANAR_FILTER); }
  189.     bool IsYV24()  const { return (pixel_type & CS_PLANAR_MASK) == (CS_YV24  & CS_PLANAR_FILTER); }
  190.     bool IsYV16()  const { return (pixel_type & CS_PLANAR_MASK) == (CS_YV16  & CS_PLANAR_FILTER); }
  191.     bool IsY8()    const { return (pixel_type & CS_PLANAR_MASK) == (CS_Y8    & CS_PLANAR_FILTER); } 
  192.  
  193.   bool HasVideo() const { return (width!=0); }
  194.   bool HasAudio() const { return (audio_samples_per_second!=0); }
  195.   bool IsRGB() const { return !!(pixel_type&CS_BGR); }
  196.   bool IsRGB24() const { return (pixel_type&CS_BGR24)==CS_BGR24; } // Clear out additional properties
  197.   bool IsRGB32() const { return (pixel_type & CS_BGR32) == CS_BGR32 ; }
  198.   bool IsYUV() const { return !!(pixel_type&CS_YUV ); }
  199.   bool IsYUY2() const { return (pixel_type & CS_YUY2) == CS_YUY2; }
  200.   bool IsYV12() const { return ((pixel_type & CS_YV12) == CS_YV12)||((pixel_type & CS_I420) == CS_I420); }
  201.   bool IsColorSpace(int c_space) const { return ((pixel_type & c_space) == c_space); }
  202.   bool Is(int property) const { return ((pixel_type & property)==property ); }
  203.   bool IsPlanar() const { return !!(pixel_type & CS_PLANAR); }
  204.   bool IsFieldBased() const { return !!(image_type & IT_FIELDBASED); }
  205.   bool IsParityKnown() const { return ((image_type & IT_FIELDBASED)&&(image_type & (IT_BFF|IT_TFF))); }
  206.   bool IsBFF() const { return !!(image_type & IT_BFF); }
  207.   bool IsTFF() const { return !!(image_type & IT_TFF); }
  208.   bool IsVPlaneFirst() const {return ((pixel_type & CS_YV12) == CS_YV12); }  // Don't use this
  209.   int BytesFromPixels(int pixels) const { return pixels * (BitsPerPixel()>>3); }   // Will not work on planar images, but will return only luma planes
  210.   int RowSize() const { return BytesFromPixels(width); }  // Also only returns first plane on planar images
  211.   int BMPSize() const { if (IsPlanar()) {int p = height * ((RowSize()+3) & ~3); p+=p>>1; return p;  } return height * ((RowSize()+3) & ~3); }
  212.   __int64 AudioSamplesFromFrames(__int64 frames) const { return (fps_numerator && HasVideo()) ? ((__int64)(frames) * audio_samples_per_second * fps_denominator / fps_numerator) : 0; }
  213.   int FramesFromAudioSamples(__int64 samples) const { return (fps_denominator && HasAudio()) ? (int)((samples * (__int64)fps_numerator)/((__int64)fps_denominator * (__int64)audio_samples_per_second)) : 0; }
  214.   __int64 AudioSamplesFromBytes(__int64 bytes) const { return HasAudio() ? bytes / BytesPerAudioSample() : 0; }
  215.   __int64 BytesFromAudioSamples(__int64 samples) const { return samples * BytesPerAudioSample(); }
  216.   int AudioChannels() const { return HasAudio() ? nchannels : 0; }
  217.   int SampleType() const{ return sample_type;}
  218.   bool IsSampleType(int testtype) const{ return !!(sample_type&testtype);}
  219.   int SamplesPerSecond() const { return audio_samples_per_second; }
  220.   int BytesPerAudioSample() const { return nchannels*BytesPerChannelSample();}
  221.   void SetFieldBased(bool isfieldbased)  { if (isfieldbased) image_type|=IT_FIELDBASED; else  image_type&=~IT_FIELDBASED; }
  222.   void Set(int property)  { image_type|=property; }
  223.   void Clear(int property)  { image_type&=~property; }
  224.  
  225.   int BitsPerPixel() const {
  226.     switch (pixel_type) {
  227.       case CS_BGR24:
  228.         return 24;
  229.       case CS_BGR32:
  230.         return 32;
  231.       case CS_YUY2:
  232.         return 16;
  233.       case CS_YV12:
  234.       case CS_I420:
  235.         return 12;
  236.       default:
  237.         return 0;
  238.     }
  239.   }
  240.  
  241.   int BytesPerChannelSample() const {
  242.     switch (sample_type) {
  243.     case SAMPLE_INT8:
  244.       return sizeof(signed char);
  245.     case SAMPLE_INT16:
  246.       return sizeof(signed short);
  247.     case SAMPLE_INT24:
  248.       return 3;
  249.     case SAMPLE_INT32:
  250.       return sizeof(signed int);
  251.     case SAMPLE_FLOAT:
  252.       return sizeof(SFLOAT);
  253.     default:
  254.       _ASSERTE("Sample type not recognized!");
  255.       return 0;
  256.     }
  257.   }
  258.  
  259.   // useful mutator
  260.   void SetFPS(unsigned numerator, unsigned denominator) {
  261.     if ((numerator == 0) || (denominator == 0)) {
  262.       fps_numerator = 0;
  263.       fps_denominator = 1;
  264.     }
  265.     else {
  266.       unsigned x=numerator, y=denominator;
  267.       while (y) {   // find gcd
  268.         unsigned t = x%y; x = y; y = t;
  269.       }
  270.       fps_numerator = numerator/x;
  271.       fps_denominator = denominator/x;
  272.     }
  273.   }
  274.  
  275.   // Range protected multiply-divide of FPS
  276.   void MulDivFPS(unsigned multiplier, unsigned divisor) {
  277.     unsigned __int64 numerator   = UInt32x32To64(fps_numerator,   multiplier);
  278.     unsigned __int64 denominator = UInt32x32To64(fps_denominator, divisor);
  279.  
  280.     unsigned __int64 x=numerator, y=denominator;
  281.     while (y) {   // find gcd
  282.       unsigned __int64 t = x%y; x = y; y = t;
  283.     }
  284.     numerator   /= x; // normalize
  285.     denominator /= x;
  286.  
  287.     unsigned __int64 temp = numerator | denominator; // Just looking top bit
  288.     unsigned u = 0;
  289.     while (temp & 0xffffffff80000000) { // or perhaps > 16777216*2
  290.       temp = Int64ShrlMod32(temp, 1);
  291.       u++;
  292.     }
  293.     if (u) { // Scale to fit
  294.       const unsigned round = 1 << (u-1);
  295.       SetFPS( (unsigned)Int64ShrlMod32(numerator   + round, u),
  296.               (unsigned)Int64ShrlMod32(denominator + round, u) );
  297.     }
  298.     else {
  299.       fps_numerator   = (unsigned)numerator;
  300.       fps_denominator = (unsigned)denominator;
  301.     }
  302.   }
  303.  
  304.   // Test for same colorspace
  305.   bool IsSameColorspace(const VideoInfo& vi) const {
  306.     if (vi.pixel_type == pixel_type) return TRUE;
  307.     if (IsYV12() && vi.IsYV12()) return TRUE;
  308.     return FALSE;
  309.   }
  310.  
  311. };
  312.  
  313.  
  314.  
  315.  
  316. // VideoFrameBuffer holds information about a memory block which is used
  317. // for video data.  For efficiency, instances of this class are not deleted
  318. // when the refcount reaches zero; instead they're stored in a linked list
  319. // to be reused.  The instances are deleted when the corresponding AVS
  320. // file is closed.
  321.  
  322. class VideoFrameBuffer {
  323.   BYTE* const data;
  324.   const int data_size;
  325.   // sequence_number is incremented every time the buffer is changed, so
  326.   // that stale views can tell they're no longer valid.
  327.   long sequence_number;
  328.  
  329.   friend class VideoFrame;
  330.   friend class Cache;
  331.   friend class ScriptEnvironment;
  332.   long refcount;
  333.  
  334. public:
  335.   VideoFrameBuffer(int size);
  336.   VideoFrameBuffer();
  337.   ~VideoFrameBuffer();
  338.  
  339.   const BYTE* GetReadPtr() const { return data; }
  340.   BYTE* GetWritePtr() { ++sequence_number; return data; }
  341.   int GetDataSize() { return data_size; }
  342.   int GetSequenceNumber() { return sequence_number; }
  343.   int GetRefcount() { return refcount; }
  344. };
  345.  
  346.  
  347. class IClip;
  348. class PClip;
  349. class PVideoFrame;
  350. class IScriptEnvironment;
  351. class AVSValue;
  352.  
  353.  
  354. // VideoFrame holds a "window" into a VideoFrameBuffer.  Operator new
  355. // is overloaded to recycle class instances.
  356.  
  357. class VideoFrame {
  358.   int refcount;
  359.   VideoFrameBuffer* const vfb;
  360.   const int offset, pitch, row_size, height, offsetU, offsetV, pitchUV;  // U&V offsets are from top of picture.
  361.  
  362.   friend class PVideoFrame;
  363.   void AddRef() { InterlockedIncrement((long *)&refcount); }
  364.   void Release() { if (refcount==1) InterlockedDecrement(&vfb->refcount); InterlockedDecrement((long *)&refcount); }
  365.  
  366.   friend class ScriptEnvironment;
  367.   friend class Cache;
  368.  
  369.   VideoFrame(VideoFrameBuffer* _vfb, int _offset, int _pitch, int _row_size, int _height);
  370.   VideoFrame(VideoFrameBuffer* _vfb, int _offset, int _pitch, int _row_size, int _height, int _offsetU, int _offsetV, int _pitchUV);
  371.  
  372.   void* operator new(unsigned size);
  373. // TESTME: OFFSET U/V may be switched to what could be expected from AVI standard!
  374. public:
  375.   int GetPitch() const { return pitch; }
  376.   int GetPitch(int plane) const { switch (plane) {case PLANAR_U: case PLANAR_V: return pitchUV;} return pitch; }
  377.   int GetRowSize() const { return row_size; }
  378.   int GetRowSize(int plane) const {
  379.     switch (plane) {
  380.     case PLANAR_U: case PLANAR_V: if (pitchUV) return row_size>>1; else return 0;
  381.     case PLANAR_U_ALIGNED: case PLANAR_V_ALIGNED:
  382.       if (pitchUV) {
  383.         int r = ((row_size+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)) )>>1; // Aligned rowsize
  384.         if (r<=pitchUV)
  385.           return r;
  386.         return row_size>>1;
  387.       } else return 0;
  388.     case PLANAR_Y_ALIGNED:
  389.       int r = (row_size+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)); // Aligned rowsize
  390.       if (r<=pitch)
  391.         return r;
  392.       return row_size;
  393.     }
  394.     return row_size; }
  395.   int GetHeight() const { return height; }
  396.   int GetHeight(int plane) const {  switch (plane) {case PLANAR_U: case PLANAR_V: if (pitchUV) return height>>1; return 0;} return height; }
  397.  
  398.   // generally you shouldn't use these three
  399.   VideoFrameBuffer* GetFrameBuffer() const { return vfb; }
  400.   int GetOffset() const { return offset; }
  401.   int GetOffset(int plane) const { switch (plane) {case PLANAR_U: return offsetU;case PLANAR_V: return offsetV;default: return offset;}; }
  402.  
  403.   // in plugins use env->SubFrame()
  404.   VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height) const;
  405.   VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int pitchUV) const;
  406.  
  407.  
  408.   const BYTE* GetReadPtr() const { return vfb->GetReadPtr() + offset; }
  409.   const BYTE* GetReadPtr(int plane) const { return vfb->GetReadPtr() + GetOffset(plane); }
  410.  
  411.   bool IsWritable() const { return (refcount == 1 && vfb->refcount == 1); }
  412.  
  413.   BYTE* GetWritePtr() const {
  414.     if (vfb->GetRefcount()>1) {
  415.       _ASSERT(FALSE);
  416.       //throw AvisynthError("Internal Error - refcount was more than one!");
  417.     }
  418.     return IsWritable() ? (vfb->GetWritePtr() + offset) : 0;
  419.   }
  420.  
  421.   BYTE* GetWritePtr(int plane) const {
  422.     if (plane==PLANAR_Y) {
  423.       if (vfb->GetRefcount()>1) {
  424.         _ASSERT(FALSE);
  425. //        throw AvisynthError("Internal Error - refcount was more than one!");
  426.       }
  427.       return IsWritable() ? vfb->GetWritePtr() + GetOffset(plane) : 0;
  428.     }
  429.     return vfb->data + GetOffset(plane);
  430.   }
  431.  
  432.   ~VideoFrame() { InterlockedDecrement(&vfb->refcount); }
  433. };
  434.  
  435. enum {
  436.   CACHE_NOTHING=0,
  437.   CACHE_RANGE=1,
  438.   CACHE_ALL=2,
  439.   CACHE_AUDIO=3,
  440.   CACHE_AUDIO_NONE=4,
  441.   CACHE_AUDIO_AUTO=5
  442.  };
  443.  
  444. // Base class for all filters.
  445. class IClip {
  446.   friend class PClip;
  447.   friend class AVSValue;
  448.   int refcnt;
  449.   void AddRef() { InterlockedIncrement((long *)&refcnt); }
  450.   void Release() { InterlockedDecrement((long *)&refcnt); if (!refcnt) delete this; }
  451. public:
  452.   IClip() : refcnt(0) {}
  453.  
  454.   virtual int __stdcall GetVersion() { return AVISYNTH_INTERFACE_VERSION; }
  455.  
  456.   virtual PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) = 0;
  457.   virtual bool __stdcall GetParity(int n) = 0;  // return field parity if field_based, else parity of first field in frame
  458.   virtual void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) = 0;  // start and count are in samples
  459.   virtual void __stdcall SetCacheHints(int cachehints,int frame_range) = 0 ;  // We do not pass cache requests upwards, only to the next filter.
  460.   virtual const VideoInfo& __stdcall GetVideoInfo() = 0;
  461.   virtual __stdcall ~IClip() {}
  462.   //virtual ~IClip() {}
  463. };
  464.  
  465.  
  466. // smart pointer to IClip
  467. class PClip {
  468.  
  469.   IClip* p;
  470.  
  471.   IClip* GetPointerWithAddRef() const { if (p) p->AddRef(); return p; }
  472.   friend class AVSValue;
  473.   friend class VideoFrame;
  474.  
  475.   void Init(IClip* x) {
  476.     if (x) x->AddRef();
  477.     p=x;
  478.   }
  479.   void Set(IClip* x) {
  480.     if (x) x->AddRef();
  481.     if (p) p->Release();
  482.     p=x;
  483.   }
  484.  
  485. public:
  486.   PClip() { p = 0; }
  487.   PClip(const PClip& x) { Init(x.p); }
  488.   PClip(IClip* x) { Init(x); }
  489.   void operator=(IClip* x) { Set(x); }
  490.   void operator=(const PClip& x) { Set(x.p); }
  491.  
  492.   IClip* operator->() const { return p; }
  493.  
  494.   // useful in conditional expressions
  495.   operator void*() const { return p; }
  496.   bool operator!() const { return !p; }
  497.  
  498.   ~PClip() { if (p) p->Release(); }
  499. };
  500.  
  501.  
  502. // smart pointer to VideoFrame
  503. class PVideoFrame {
  504.  
  505.   VideoFrame* p;
  506.  
  507.   void Init(VideoFrame* x) {
  508.     if (x) x->AddRef();
  509.     p=x;
  510.   }
  511.   void Set(VideoFrame* x) {
  512.     if (x) x->AddRef();
  513.     if (p) p->Release();
  514.     p=x;
  515.   }
  516.  
  517. public:
  518.   PVideoFrame() { p = 0; }
  519.   PVideoFrame(const PVideoFrame& x) { Init(x.p); }
  520.   PVideoFrame(VideoFrame* x) { Init(x); }
  521.   void operator=(VideoFrame* x) { Set(x); }
  522.   void operator=(const PVideoFrame& x) { Set(x.p); }
  523.  
  524.   VideoFrame* operator->() const { return p; }
  525.  
  526.   // for conditional expressions
  527.   operator void*() const { return p; }
  528.   bool operator!() const { return !p; }
  529.  
  530.   ~PVideoFrame() { if (p) p->Release();}
  531. };
  532.  
  533.  
  534. class AVSValue {
  535. public:
  536.  
  537.   AVSValue() { type = 'v'; }
  538.   AVSValue(IClip* c) { type = 'c'; clip = c; if (c) c->AddRef(); }
  539.   AVSValue(const PClip& c) { type = 'c'; clip = c.GetPointerWithAddRef(); }
  540.   AVSValue(bool b) { type = 'b'; boolean = b; }
  541.   AVSValue(int i) { type = 'i'; integer = i; }
  542. //  AVSValue(__int64 l) { type = 'l'; longlong = l; }
  543.   AVSValue(float f) { type = 'f'; floating_pt = f; }
  544.   AVSValue(double f) { type = 'f'; floating_pt = float(f); }
  545.   AVSValue(const char* s) { type = 's'; string = s; }
  546.   AVSValue(const AVSValue* a, int size) { type = 'a'; array = a; array_size = size; }
  547.   AVSValue(const AVSValue& v) { Assign(&v, true); }
  548.  
  549.   ~AVSValue() { if (IsClip() && clip) clip->Release(); }
  550.   AVSValue& operator=(const AVSValue& v) { Assign(&v, false); return *this; }
  551.  
  552.   // Note that we transparently allow 'int' to be treated as 'float'.
  553.   // There are no int<->bool conversions, though.
  554.  
  555.   bool Defined() const { return type != 'v'; }
  556.   bool IsClip() const { return type == 'c'; }
  557.   bool IsBool() const { return type == 'b'; }
  558.   bool IsInt() const { return type == 'i'; }
  559. //  bool IsLong() const { return (type == 'l'|| type == 'i'); }
  560.   bool IsFloat() const { return type == 'f' || type == 'i'; }
  561.   bool IsString() const { return type == 's'; }
  562.   bool IsArray() const { return type == 'a'; }
  563.  
  564.   PClip AsClip() const { _ASSERTE(IsClip()); return IsClip()?clip:0; }
  565.   bool AsBool() const { _ASSERTE(IsBool()); return boolean; }
  566.   int AsInt() const { _ASSERTE(IsInt()); return integer; }
  567. //  int AsLong() const { _ASSERTE(IsLong()); return longlong; }
  568.   const char* AsString() const { _ASSERTE(IsString()); return IsString()?string:0; }
  569.   double AsFloat() const { _ASSERTE(IsFloat()); return IsInt()?integer:floating_pt; }
  570.  
  571.   bool AsBool(bool def) const { _ASSERTE(IsBool()||!Defined()); return IsBool() ? boolean : def; }
  572.   int AsInt(int def) const { _ASSERTE(IsInt()||!Defined()); return IsInt() ? integer : def; }
  573.   double AsFloat(double def) const { _ASSERTE(IsFloat()||!Defined()); return IsInt() ? integer : type=='f' ? floating_pt : def; }
  574.   const char* AsString(const char* def) const { _ASSERTE(IsString()||!Defined()); return IsString() ? string : def; }
  575.  
  576.   int ArraySize() const { _ASSERTE(IsArray()); return IsArray()?array_size:1; }
  577.  
  578.   const AVSValue& operator[](int index) const {
  579.     _ASSERTE(IsArray() && index>=0 && index<array_size);
  580.     return (IsArray() && index>=0 && index<array_size) ? array[index] : *this;
  581.   }
  582.  
  583. private:
  584.  
  585.   short type;  // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, or 'l'ong
  586.   short array_size;
  587.   union {
  588.     IClip* clip;
  589.     bool boolean;
  590.     int integer;
  591.     float floating_pt;
  592.     const char* string;
  593.     const AVSValue* array;
  594. //    __int64 longlong;
  595.   };
  596.  
  597.   void Assign(const AVSValue* src, bool init) {
  598.     if (src->IsClip() && src->clip)
  599.       src->clip->AddRef();
  600.     if (!init && IsClip() && clip)
  601.       clip->Release();
  602.     // make sure this copies the whole struct!
  603.     ((__int32*)this)[0] = ((__int32*)src)[0];
  604.     ((__int32*)this)[1] = ((__int32*)src)[1];
  605.   }
  606. };
  607.  
  608.  
  609. // instantiable null filter
  610. class GenericVideoFilter : public IClip {
  611. protected:
  612.   PClip child;
  613.   VideoInfo vi;
  614. public:
  615.   GenericVideoFilter(PClip _child) : child(_child) { vi = child->GetVideoInfo(); }
  616.   PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) { return child->GetFrame(n, env); }
  617.   void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) { child->GetAudio(buf, start, count, env); }
  618.   const VideoInfo& __stdcall GetVideoInfo() { return vi; }
  619.   bool __stdcall GetParity(int n) { return child->GetParity(n); }
  620.   void __stdcall SetCacheHints(int cachehints,int frame_range) { } ;  // We do not pass cache requests upwards, only to the next filter.
  621. };
  622.  
  623.  
  624.  
  625.  
  626.  
  627. /* Helper classes useful to plugin authors */
  628.  
  629. class AlignPlanar : public GenericVideoFilter
  630. {
  631. public:
  632.   AlignPlanar(PClip _clip);
  633.   static PClip Create(PClip clip);
  634.   PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
  635. };
  636.  
  637.  
  638.  
  639. class FillBorder : public GenericVideoFilter
  640. {
  641. public:
  642.   FillBorder(PClip _clip);
  643.   static PClip Create(PClip clip);
  644.   PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
  645. };
  646.  
  647.  
  648.  
  649. class ConvertAudio : public GenericVideoFilter
  650. /**
  651.   * Helper class to convert audio to any format
  652.  **/
  653. {
  654. public:
  655.   ConvertAudio(PClip _clip, int prefered_format);
  656.   void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env);
  657.   void __stdcall SetCacheHints(int cachehints,int frame_range);  // We do pass cache requests upwards, to the cache!
  658.  
  659.   static PClip Create(PClip clip, int sample_type, int prefered_type);
  660.   static AVSValue __cdecl Create_float(AVSValue args, void*, IScriptEnvironment*);
  661.   static AVSValue __cdecl Create_32bit(AVSValue args, void*, IScriptEnvironment*);
  662.   static AVSValue __cdecl Create_24bit(AVSValue args, void*, IScriptEnvironment*);
  663.   static AVSValue __cdecl Create_16bit(AVSValue args, void*, IScriptEnvironment*);
  664.   static AVSValue __cdecl Create_8bit (AVSValue args, void*, IScriptEnvironment*);
  665.   static AVSValue __cdecl Create_Any  (AVSValue args, void*, IScriptEnvironment*);
  666.   virtual ~ConvertAudio();
  667.  
  668. private:
  669.   void convertToFloat(char* inbuf, float* outbuf, char sample_type, int count);
  670.   void convertToFloat_3DN(char* inbuf, float* outbuf, char sample_type, int count);
  671.   void convertToFloat_SSE(char* inbuf, float* outbuf, char sample_type, int count);
  672.   void convertToFloat_SSE2(char* inbuf, float* outbuf, char sample_type, int count);
  673.   void convertFromFloat(float* inbuf, void* outbuf, char sample_type, int count);
  674.   void convertFromFloat_3DN(float* inbuf, void* outbuf, char sample_type, int count);
  675.   void convertFromFloat_SSE(float* inbuf, void* outbuf, char sample_type, int count);
  676.   void convertFromFloat_SSE2(float* inbuf, void* outbuf, char sample_type, int count);
  677.  
  678.   __inline int Saturate_int8(float n);
  679.   __inline short Saturate_int16(float n);
  680.   __inline int Saturate_int24(float n);
  681.   __inline int Saturate_int32(float n);
  682.  
  683.   char src_format;
  684.   char dst_format;
  685.   int src_bps;
  686.   char *tempbuffer;
  687.   SFLOAT *floatbuffer;
  688.   int tempbuffer_size;
  689. };
  690.  
  691.  
  692. // For GetCPUFlags.  These are backwards-compatible with those in VirtualDub.
  693. enum {
  694.                     /* slowest CPU to support extension */
  695.   CPUF_FORCE        =  0x01,   //  N/A
  696.   CPUF_FPU          =  0x02,   //  386/486DX
  697.   CPUF_MMX          =  0x04,   //  P55C, K6, PII
  698.   CPUF_INTEGER_SSE  =  0x08,   //  PIII, Athlon
  699.   CPUF_SSE          =  0x10,   //  PIII, Athlon XP/MP
  700.   CPUF_SSE2         =  0x20,   //  PIV, Hammer
  701.   CPUF_3DNOW        =  0x40,   //  K6-2
  702.   CPUF_3DNOW_EXT    =  0x80,   //  Athlon
  703.   CPUF_X86_64       =  0xA0,   //  Hammer (note: equiv. to 3DNow + SSE2, which
  704.                                //          only Hammer will have anyway)
  705.   CPUF_SSE3         = 0x100,   //  PIV+, Hammer
  706. };
  707. #define MAX_INT 0x7fffffff
  708. #define MIN_INT -0x7fffffff  // ::FIXME:: research why this is not 0x80000000
  709.  
  710.  
  711.  
  712. class IScriptEnvironment {
  713. public:
  714.   virtual __stdcall ~IScriptEnvironment() {}
  715.   //virtual ~IScriptEnvironment() {}
  716.  
  717.   virtual /*static*/ long __stdcall GetCPUFlags() = 0;
  718.  
  719.   virtual char* __stdcall SaveString(const char* s, int length = -1) = 0;
  720.   virtual char* __stdcall Sprintf(const char* fmt, ...) = 0;
  721.   // note: val is really a va_list; I hope everyone typedefs va_list to a pointer
  722.   virtual char* __stdcall VSprintf(const char* fmt, void* val) = 0;
  723.  
  724.   __declspec(noreturn) virtual void __stdcall ThrowError(const char* fmt, ...) = 0;
  725.  
  726.   class NotFound /*exception*/ {};  // thrown by Invoke and GetVar
  727.  
  728.   typedef AVSValue (__cdecl *ApplyFunc)(AVSValue args, void* user_data, IScriptEnvironment* env);
  729.  
  730.   virtual void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data) = 0;
  731.   virtual bool __stdcall FunctionExists(const char* name) = 0;
  732.   virtual AVSValue __stdcall Invoke(const char* name, const AVSValue args, const char** arg_names=0) = 0;
  733.  
  734.   virtual AVSValue __stdcall GetVar(const char* name) = 0;
  735.   virtual bool __stdcall SetVar(const char* name, const AVSValue& val) = 0;
  736.   virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) = 0;
  737.  
  738.   virtual void __stdcall PushContext(int level=0) = 0;
  739.   virtual void __stdcall PopContext() = 0;
  740.  
  741.   // align should be 4 or 8
  742.   virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, int align=FRAME_ALIGN) = 0;
  743.  
  744.   virtual bool __stdcall MakeWritable(PVideoFrame* pvf) = 0;
  745.  
  746.   virtual /*static*/ void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) = 0;
  747.  
  748.   typedef void (__cdecl *ShutdownFunc)(void* user_data, IScriptEnvironment* env);
  749.   virtual void __stdcall AtExit(ShutdownFunc function, void* user_data) = 0;
  750.  
  751.   virtual void __stdcall CheckVersion(int version = AVISYNTH_INTERFACE_VERSION) = 0;
  752.  
  753.   virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) = 0;
  754.  
  755.   virtual int __stdcall SetMemoryMax(int mem) = 0;
  756.  
  757.   virtual int __stdcall SetWorkingDir(const char * newdir) = 0;
  758.  
  759.   virtual void* __stdcall ManageCache(int key, void* data) = 0;
  760.  
  761.   enum PlanarChromaAlignmentMode {
  762.             PlanarChromaAlignmentOff,
  763.             PlanarChromaAlignmentOn,
  764.             PlanarChromaAlignmentTest };
  765.  
  766.   virtual bool __stdcall PlanarChromaAlignment(PlanarChromaAlignmentMode key) = 0;
  767.  
  768.   virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) = 0;
  769.  
  770.     virtual void __stdcall DeleteScriptEnvironment() = 0;
  771. };
  772.  
  773.  
  774. // avisynth.dll exports this; it's a way to use it as a library, without
  775. // writing an AVS script or without going through AVIFile.
  776. IScriptEnvironment* __stdcall CreateScriptEnvironment(int version = AVISYNTH_INTERFACE_VERSION);
  777.  
  778.  
  779. #pragma pack(pop)
  780.  
  781. #endif //__AVISYNTH_H__
  782.