1 // Avisynth v1.0 beta. Copyright 2000 Ben Rudiak-Gould.
2 // http://www.math.berkeley.edu/~benrg/avisynth.html
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.
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.
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 .
25 #define _ASSERTE(x) assert(x)
30 enum { AVISYNTH_INTERFACE_VERSION
= 1 };
33 // I had problems with Premiere wanting 1-byte alignment for its structures,
34 // so I now set the Avisynth struct alignment explicitly here.
38 // The VideoInfo struct holds global information about a clip (i.e.
39 // information that does not depend on the frame number). The GetVideoInfo
40 // method in IClip returns this struct.
43 int width
, height
; // width=0 means no video
44 unsigned fps_numerator
, fps_denominator
;
46 enum { UNKNOWN
=0, BGR24
=0x13, BGR32
=0x14, YUY2
=0x22 };
47 unsigned char pixel_type
;
50 int audio_samples_per_second
; // 0 means no audio
51 int num_audio_samples
;
52 bool stereo
, sixteen_bit
;
54 // useful functions of the above
55 bool HasVideo() const { return !!width
; }
56 bool HasAudio() const { return !!audio_samples_per_second
; }
57 bool IsRGB() const { return !!(pixel_type
&0x10); }
58 bool IsRGB24() const { return pixel_type
== BGR24
; }
59 bool IsRGB32() const { return pixel_type
== BGR32
; }
60 bool IsYUV() const { return !!(pixel_type
&0x20); }
61 bool IsYUY2() const { return pixel_type
== YUY2
; }
62 int BytesFromPixels(int pixels
) const { return pixels
* (pixel_type
&7); }
63 int RowSize() const { return BytesFromPixels(width
); }
64 int BitsPerPixel() const { return (pixel_type
&7) * 8; }
65 int BMPSize() const { return height
* ((RowSize()+3) & -4); }
66 int AudioSamplesFromFrames(int frames
) const { return int(__int64(frames
) * audio_samples_per_second
* fps_denominator
/ fps_numerator
); }
67 int FramesFromAudioSamples(int samples
) const { return int(__int64(samples
) * fps_numerator
/ fps_denominator
/ audio_samples_per_second
); }
68 int AudioSamplesFromBytes(int bytes
) const { return bytes
>> (stereo
+ sixteen_bit
); }
69 int BytesFromAudioSamples(int samples
) const { return samples
<< (stereo
+ sixteen_bit
); }
70 int BytesPerAudioSample() const { return BytesFromAudioSamples(1); }
73 void SetFPS(unsigned numerator
, unsigned denominator
) {
74 unsigned x
=numerator
, y
=denominator
;
75 while (y
) { // find gcd
76 unsigned t
= x
%y
; x
= y
; y
= t
;
78 fps_numerator
= numerator
/x
;
79 fps_denominator
= denominator
/x
;
84 // VideoFrameBuffer holds information about a memory block which is used
85 // for video data. For efficiency, instances of this class are not deleted
86 // when the refcount reaches zero; instead they're stored in a linked list
87 // to be reused. The instances are deleted when the corresponding AVS
90 class VideoFrameBuffer
{
91 unsigned char* const data
;
93 // sequence_number is incremented every time the buffer is changed, so
94 // that stale views can tell they're no longer valid.
97 friend class VideoFrame
;
102 VideoFrameBuffer(int size
);
106 const unsigned char* GetReadPtr() const { return data
; }
107 unsigned char* GetWritePtr() { ++sequence_number
; return data
; }
108 int GetDataSize() { return data_size
; }
109 int GetSequenceNumber() { return sequence_number
; }
110 int GetRefcount() { return refcount
; }
117 class IScriptEnvironment
;
121 // VideoFrame holds a "window" into a VideoFrameBuffer. Operator new
122 // is overloaded to recycle class instances.
126 VideoFrameBuffer
* const vfb
;
127 const int offset
, pitch
, row_size
, height
;
129 friend class PVideoFrame
;
130 void AddRef() { ++refcount
; }
131 void Release() { if (refcount
==1) --vfb
->refcount
; --refcount
; }
133 friend class ScriptEnvironment
;
136 VideoFrame(VideoFrameBuffer
* _vfb
, int _offset
, int _pitch
, int _row_size
, int _height
);
138 void* operator new(size_t size
);
141 int GetPitch() const { return pitch
; }
142 int GetRowSize() const { return row_size
; }
143 int GetHeight() const { return height
; }
145 // generally you shouldn't use these two
146 VideoFrameBuffer
* GetFrameBuffer() const { return vfb
; }
147 int GetOffset() const { return offset
; }
149 // in plugins use env->SubFrame()
150 VideoFrame
* Subframe(int rel_offset
, int new_pitch
, int new_row_size
, int new_height
) const;
152 const unsigned char* GetReadPtr() const { return vfb
->GetReadPtr() + offset
; }
154 bool IsWritable() const { return (refcount
== 1 && vfb
->refcount
== 1); }
156 unsigned char* GetWritePtr() const {
157 return IsWritable() ? (vfb
->GetWritePtr() + offset
) : 0;
160 ~VideoFrame() { --vfb
->refcount
; }
164 // Base class for all filters.
167 friend class AVSValue
;
169 void AddRef() { ++refcnt
; }
170 void Release() { if (!--refcnt
) delete this; }
172 IClip() : refcnt(0) {}
174 virtual int __stdcall
GetVersion() { return AVISYNTH_INTERFACE_VERSION
; }
176 virtual PVideoFrame __stdcall
GetFrame(int n
, IScriptEnvironment
* env
) = 0;
177 virtual bool __stdcall
GetParity(int n
) = 0; // return field parity if field_based, else parity of first field in frame
178 virtual void __stdcall
GetAudio(void* buf
, int start
, int count
, IScriptEnvironment
* env
) = 0; // start and count are in samples
179 virtual const VideoInfo
& __stdcall
GetVideoInfo() = 0;
180 #if defined(__INTEL_COMPILER)
183 virtual __stdcall
~IClip() {}
188 // smart pointer to IClip
193 IClip
* GetPointerWithAddRef() const { if (p
) p
->AddRef(); return p
; }
194 friend class AVSValue
;
195 friend class VideoFrame
;
197 void Init(IClip
* x
) {
209 PClip(const PClip
& x
) { Init(x
.p
); }
210 PClip(IClip
* x
) { Init(x
); }
211 void operator=(IClip
* x
) { Set(x
); }
212 void operator=(const PClip
& x
) { Set(x
.p
); }
214 IClip
* operator->() const { return p
; }
216 // useful in conditional expressions
217 operator void*() const { return p
; }
218 bool operator!() const { return !p
; }
220 ~PClip() { if (p
) p
->Release(); }
224 // smart pointer to VideoFrame
229 void Init(VideoFrame
* x
) {
233 void Set(VideoFrame
* x
) {
240 PVideoFrame() { p
= 0; }
241 PVideoFrame(const PVideoFrame
& x
) { Init(x
.p
); }
242 PVideoFrame(VideoFrame
* x
) { Init(x
); }
243 void operator=(VideoFrame
* x
) { Set(x
); }
244 void operator=(const PVideoFrame
& x
) { Set(x
.p
); }
246 VideoFrame
* operator->() const { return p
; }
248 // for conditional expressions
249 operator void*() const { return p
; }
250 bool operator!() const { return !p
; }
252 ~PVideoFrame() { if (p
) p
->Release(); }
259 AVSValue() { type
= 'v'; }
260 AVSValue(IClip
* c
) { type
= 'c'; clip
= c
; if (c
) c
->AddRef(); }
261 AVSValue(const PClip
& c
) { type
= 'c'; clip
= c
.GetPointerWithAddRef(); }
262 AVSValue(bool b
) { type
= 'b'; boolean
= b
; }
263 AVSValue(int i
) { type
= 'i'; integer
= i
; }
264 AVSValue(float f
) { type
= 'f'; floating_pt
= f
; }
265 AVSValue(double f
) { type
= 'f'; floating_pt
= float(f
); }
266 AVSValue(const char* s
) { type
= 's'; string
= s
; }
267 AVSValue(const AVSValue
* a
, int size
) { type
= 'a'; array
= a
; array_size
= size
; }
268 AVSValue(const AVSValue
& v
) { Assign(&v
, true); }
270 ~AVSValue() { if (IsClip() && clip
) clip
->Release(); }
271 AVSValue
& operator=(const AVSValue
& v
) { Assign(&v
, false); return *this; }
273 // Note that we transparently allow 'int' to be treated as 'float'.
274 // There are no int<->bool conversions, though.
276 bool Defined() const { return type
!= 'v'; }
277 bool IsClip() const { return type
== 'c'; }
278 bool IsBool() const { return type
== 'b'; }
279 bool IsInt() const { return type
== 'i'; }
280 bool IsFloat() const { return type
== 'f' || type
== 'i'; }
281 bool IsString() const { return type
== 's'; }
282 bool IsArray() const { return type
== 'a'; }
284 PClip
AsClip() const { _ASSERTE(IsClip()); return IsClip()?clip
:0; }
285 bool AsBool() const { _ASSERTE(IsBool()); return boolean
; }
286 int AsInt() const { _ASSERTE(IsInt()); return integer
; }
287 const char* AsString() const { _ASSERTE(IsString()); return IsString()?string
:0; }
288 double AsFloat() const { _ASSERTE(IsFloat()); return IsInt()?integer
:floating_pt
; }
290 bool AsBool(bool def
) const { _ASSERTE(IsBool()||!Defined()); return IsBool() ? boolean
: def
; }
291 int AsInt(int def
) const { _ASSERTE(IsInt()||!Defined()); return IsInt() ? integer
: def
; }
292 double AsFloat(double def
) const { _ASSERTE(IsFloat()||!Defined()); return IsInt() ? integer
: type
=='f' ? floating_pt
: def
; }
293 const char* AsString(const char* def
) const { _ASSERTE(IsString()||!Defined()); return IsString() ? string
: def
; }
295 int ArraySize() const { _ASSERTE(IsArray()); return IsArray()?array_size
:1; }
296 const AVSValue
& operator[](int index
) const {
297 _ASSERTE(IsArray() && index
>=0 && index
<array_size
);
298 return (IsArray() && index
>=0 && index
<array_size
) ? array
[index
] : *this;
303 short type
; // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, or 'v'oid
311 const AVSValue
* array
;
314 void Assign(const AVSValue
* src
, bool init
) {
315 if (src
->IsClip() && src
->clip
)
317 if (!init
&& IsClip() && clip
)
319 // make sure this copies the whole struct!
320 ((__int32
*)this)[0] = ((__int32
*)src
)[0];
321 ((__int32
*)this)[1] = ((__int32
*)src
)[1];
326 // instantiable null filter
327 class GenericVideoFilter
: public IClip
{
332 GenericVideoFilter(PClip _child
) : child(_child
) { vi
= child
->GetVideoInfo(); }
333 PVideoFrame __stdcall
GetFrame(int n
, IScriptEnvironment
* env
) { return child
->GetFrame(n
, env
); }
334 void __stdcall
GetAudio(void* buf
, int start
, int count
, IScriptEnvironment
* env
) { child
->GetAudio(buf
, start
, count
, env
); }
335 const VideoInfo
& __stdcall
GetVideoInfo() { return vi
; }
336 bool __stdcall
GetParity(int n
) { return child
->GetParity(n
); }
340 class AvisynthError
/* exception */ {
342 const char* const msg
;
343 AvisynthError(const char* _msg
) : msg(_msg
) {}
347 // For GetCPUFlags. These are the same as in VirtualDub.
352 CPUF_INTEGER_SSE
= 0x08, // Athlon MMX extensions or Intel SSE
353 CPUF_SSE
= 0x10, // Full SSE (PIII)
354 CPUF_SSE2
= 0x20, // (PIV)
356 CPUF_3DNOW_EXT
= 0x80, // Athlon 3DNow! extensions
360 class IScriptEnvironment
{
362 #if defined(__INTEL_COMPILER)
363 virtual ~IScriptEnvironment() {}
365 virtual __stdcall
~IScriptEnvironment() {}
368 virtual /*static*/ long __stdcall
GetCPUFlags() = 0;
370 virtual char* __stdcall
SaveString(const char* s
, int length
= -1) = 0;
371 virtual char* __stdcall
Sprintf(const char* fmt
, ...) = 0;
372 // note: val is really a va_list; I hope everyone typedefs va_list to a pointer
373 virtual char* __stdcall
VSprintf(const char* fmt
, void* val
) = 0;
375 __declspec(noreturn
) virtual void __stdcall
ThrowError(const char* fmt
, ...) = 0;
377 class NotFound
/*exception*/ {}; // thrown by Invoke and GetVar
379 typedef AVSValue (__cdecl
*ApplyFunc
)(AVSValue args
, void* user_data
, IScriptEnvironment
* env
);
381 virtual void __stdcall
AddFunction(const char* name
, const char* params
, ApplyFunc apply
, void* user_data
) = 0;
382 virtual bool __stdcall
FunctionExists(const char* name
) = 0;
383 virtual AVSValue __stdcall
Invoke(const char* name
, const AVSValue args
, const char** arg_names
=0) = 0;
385 virtual AVSValue __stdcall
GetVar(const char* name
) = 0;
386 virtual bool __stdcall
SetVar(const char* name
, const AVSValue
& val
) = 0;
387 virtual bool __stdcall
SetGlobalVar(const char* name
, const AVSValue
& val
) = 0;
389 virtual void __stdcall
PushContext(int level
=0) = 0;
390 virtual void __stdcall
PopContext() = 0;
392 // align should be 4 or 8
393 virtual PVideoFrame __stdcall
NewVideoFrame(const VideoInfo
& vi
, int align
=8) = 0;
395 virtual bool __stdcall
MakeWritable(PVideoFrame
* pvf
) = 0;
397 virtual /*static*/ void __stdcall
BitBlt(unsigned char* dstp
, int dst_pitch
, const unsigned char* srcp
, int src_pitch
, int row_size
, int height
) = 0;
399 typedef void (__cdecl
*ShutdownFunc
)(void* user_data
, IScriptEnvironment
* env
);
400 virtual void __stdcall
AtExit(ShutdownFunc function
, void* user_data
) = 0;
402 virtual void __stdcall
CheckVersion(int version
= AVISYNTH_INTERFACE_VERSION
) = 0;
404 virtual PVideoFrame __stdcall
Subframe(PVideoFrame src
, int rel_offset
, int new_pitch
, int new_row_size
, int new_height
) = 0;
408 // avisynth.dll exports this; it's a way to use it as a library, without
409 // writing an AVS script or without going through AVIFile.
410 IScriptEnvironment
* __stdcall
CreateScriptEnvironment(int version
= AVISYNTH_INTERFACE_VERSION
);