PageRenderTime 63ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/AvisynthWrapper/avisynth.h

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