Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 1 | // Avisynth C Interface Version 0.20 |
2 | // Copyright 2003 Kevin Atkinson |
||
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 | // As a special exception, I give you permission to link to the |
||
20 | // Avisynth C interface with independent modules that communicate with |
||
21 | // the Avisynth C interface solely through the interfaces defined in |
||
22 | // avisynth_c.h, regardless of the license terms of these independent |
||
23 | // modules, and to copy and distribute the resulting combined work |
||
24 | // under terms of your choice, provided that every copy of the |
||
25 | // combined work is accompanied by a complete copy of the source code |
||
26 | // of the Avisynth C interface and Avisynth itself (with the version |
||
27 | // used to produce the combined work), being distributed under the |
||
28 | // terms of the GNU General Public License plus this exception. An |
||
29 | // independent module is a module which is not derived from or based |
||
30 | // on Avisynth C Interface, such as 3rd-party filters, import and |
||
31 | // export plugins, or graphical user interfaces. |
||
32 | |||
33 | // NOTE: this is a partial update of the Avisynth C interface to recognize |
||
34 | // new color spaces added in Avisynth 2.60. By no means is this document |
||
35 | // completely Avisynth 2.60 compliant. |
||
36 | |||
37 | #ifndef __AVISYNTH_C__ |
||
38 | #define __AVISYNTH_C__ |
||
39 | |||
40 | #ifdef __cplusplus |
||
41 | # define EXTERN_C extern "C" |
||
42 | #else |
||
43 | # define EXTERN_C |
||
44 | #endif |
||
45 | |||
46 | #define AVSC_USE_STDCALL 1 |
||
47 | |||
48 | #ifndef AVSC_USE_STDCALL |
||
49 | # define AVSC_CC __cdecl |
||
50 | #else |
||
51 | # define AVSC_CC __stdcall |
||
52 | #endif |
||
53 | |||
54 | #define AVSC_INLINE static __inline |
||
55 | |||
56 | #ifdef AVISYNTH_C_EXPORTS |
||
57 | # define AVSC_EXPORT EXTERN_C |
||
58 | # define AVSC_API(ret, name) EXTERN_C __declspec(dllexport) ret AVSC_CC name |
||
59 | #else |
||
60 | # define AVSC_EXPORT EXTERN_C __declspec(dllexport) |
||
61 | # ifndef AVSC_NO_DECLSPEC |
||
62 | # define AVSC_API(ret, name) EXTERN_C __declspec(dllimport) ret AVSC_CC name |
||
63 | # else |
||
64 | # define AVSC_API(ret, name) typedef ret (AVSC_CC *name##_func) |
||
65 | # endif |
||
66 | #endif |
||
67 | |||
68 | typedef unsigned char BYTE; |
||
69 | #ifdef __GNUC__ |
||
70 | typedef long long int INT64; |
||
71 | #else |
||
72 | typedef __int64 INT64; |
||
73 | #endif |
||
74 | |||
75 | |||
76 | ///////////////////////////////////////////////////////////////////// |
||
77 | // |
||
78 | // Constants |
||
79 | // |
||
80 | |||
81 | #ifndef __AVISYNTH_H__ |
||
82 | enum { AVISYNTH_INTERFACE_VERSION = 4 }; |
||
83 | #endif |
||
84 | |||
85 | enum {AVS_SAMPLE_INT8 = 1<<0, |
||
86 | AVS_SAMPLE_INT16 = 1<<1, |
||
87 | AVS_SAMPLE_INT24 = 1<<2, |
||
88 | AVS_SAMPLE_INT32 = 1<<3, |
||
89 | AVS_SAMPLE_FLOAT = 1<<4}; |
||
90 | |||
91 | enum {AVS_PLANAR_Y=1<<0, |
||
92 | AVS_PLANAR_U=1<<1, |
||
93 | AVS_PLANAR_V=1<<2, |
||
94 | AVS_PLANAR_ALIGNED=1<<3, |
||
95 | AVS_PLANAR_Y_ALIGNED=AVS_PLANAR_Y|AVS_PLANAR_ALIGNED, |
||
96 | AVS_PLANAR_U_ALIGNED=AVS_PLANAR_U|AVS_PLANAR_ALIGNED, |
||
97 | AVS_PLANAR_V_ALIGNED=AVS_PLANAR_V|AVS_PLANAR_ALIGNED, |
||
98 | AVS_PLANAR_A=1<<4, |
||
99 | AVS_PLANAR_R=1<<5, |
||
100 | AVS_PLANAR_G=1<<6, |
||
101 | AVS_PLANAR_B=1<<7, |
||
102 | AVS_PLANAR_A_ALIGNED=AVS_PLANAR_A|AVS_PLANAR_ALIGNED, |
||
103 | AVS_PLANAR_R_ALIGNED=AVS_PLANAR_R|AVS_PLANAR_ALIGNED, |
||
104 | AVS_PLANAR_G_ALIGNED=AVS_PLANAR_G|AVS_PLANAR_ALIGNED, |
||
105 | AVS_PLANAR_B_ALIGNED=AVS_PLANAR_B|AVS_PLANAR_ALIGNED}; |
||
106 | |||
107 | // Colorspace properties. |
||
108 | enum {AVS_CS_BGR = 1<<28, |
||
109 | AVS_CS_YUV = 1<<29, |
||
110 | AVS_CS_INTERLEAVED = 1<<30, |
||
111 | AVS_CS_PLANAR = 1<<31, |
||
112 | |||
113 | AVS_CS_SHIFT_SUB_WIDTH = 0, |
||
114 | AVS_CS_SHIFT_SUB_HEIGHT = 1 << 3, |
||
115 | AVS_CS_SHIFT_SAMPLE_BITS = 1 << 4, |
||
116 | |||
117 | AVS_CS_SUB_WIDTH_MASK = 7 << AVS_CS_SHIFT_SUB_WIDTH, |
||
118 | AVS_CS_SUB_WIDTH_1 = 3 << AVS_CS_SHIFT_SUB_WIDTH, // YV24 |
||
119 | AVS_CS_SUB_WIDTH_2 = 0 << AVS_CS_SHIFT_SUB_WIDTH, // YV12, I420, YV16 |
||
120 | AVS_CS_SUB_WIDTH_4 = 1 << AVS_CS_SHIFT_SUB_WIDTH, // YUV9, YV411 |
||
121 | |||
122 | AVS_CS_VPLANEFIRST = 1 << 3, // YV12, YV16, YV24, YV411, YUV9 |
||
123 | AVS_CS_UPLANEFIRST = 1 << 4, // I420 |
||
124 | |||
125 | AVS_CS_SUB_HEIGHT_MASK = 7 << AVS_CS_SHIFT_SUB_HEIGHT, |
||
126 | AVS_CS_SUB_HEIGHT_1 = 3 << AVS_CS_SHIFT_SUB_HEIGHT, // YV16, YV24, YV411 |
||
127 | AVS_CS_SUB_HEIGHT_2 = 0 << AVS_CS_SHIFT_SUB_HEIGHT, // YV12, I420 |
||
128 | AVS_CS_SUB_HEIGHT_4 = 1 << AVS_CS_SHIFT_SUB_HEIGHT, // YUV9 |
||
129 | |||
130 | AVS_CS_SAMPLE_BITS_MASK = 7 << AVS_CS_SHIFT_SAMPLE_BITS, |
||
131 | AVS_CS_SAMPLE_BITS_8 = 0 << AVS_CS_SHIFT_SAMPLE_BITS, |
||
132 | AVS_CS_SAMPLE_BITS_16 = 1 << AVS_CS_SHIFT_SAMPLE_BITS, |
||
133 | AVS_CS_SAMPLE_BITS_32 = 2 << AVS_CS_SHIFT_SAMPLE_BITS, |
||
134 | |||
135 | AVS_CS_PLANAR_MASK = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV | AVS_CS_BGR | AVS_CS_SAMPLE_BITS_MASK | AVS_CS_SUB_HEIGHT_MASK | AVS_CS_SUB_WIDTH_MASK, |
||
136 | AVS_CS_PLANAR_FILTER = ~( AVS_CS_VPLANEFIRST | AVS_CS_UPLANEFIRST )}; |
||
137 | |||
138 | // Specific colorformats |
||
139 | enum { |
||
140 | AVS_CS_UNKNOWN = 0, |
||
141 | AVS_CS_BGR24 = 1<<0 | AVS_CS_BGR | AVS_CS_INTERLEAVED, |
||
142 | AVS_CS_BGR32 = 1<<1 | AVS_CS_BGR | AVS_CS_INTERLEAVED, |
||
143 | AVS_CS_YUY2 = 1<<2 | AVS_CS_YUV | AVS_CS_INTERLEAVED, |
||
144 | // AVS_CS_YV12 = 1<<3 Reserved |
||
145 | // AVS_CS_I420 = 1<<4 Reserved |
||
146 | AVS_CS_RAW32 = 1<<5 | AVS_CS_INTERLEAVED, |
||
147 | |||
148 | AVS_CS_YV24 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_1, // YVU 4:4:4 planar |
||
149 | AVS_CS_YV16 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_2, // YVU 4:2:2 planar |
||
150 | AVS_CS_YV12 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_2 | AVS_CS_SUB_WIDTH_2, // YVU 4:2:0 planar |
||
151 | AVS_CS_I420 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_UPLANEFIRST | AVS_CS_SUB_HEIGHT_2 | AVS_CS_SUB_WIDTH_2, // YUV 4:2:0 planar |
||
152 | AVS_CS_IYUV = AVS_CS_I420, |
||
153 | AVS_CS_YV411 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_1 | AVS_CS_SUB_WIDTH_4, // YVU 4:1:1 planar |
||
154 | AVS_CS_YUV9 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_HEIGHT_4 | AVS_CS_SUB_WIDTH_4, // YVU 4:1:0 planar |
||
155 | AVS_CS_Y8 = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 // Y 4:0:0 planar |
||
156 | }; |
||
157 | |||
158 | enum { |
||
159 | AVS_IT_BFF = 1<<0, |
||
160 | AVS_IT_TFF = 1<<1, |
||
161 | AVS_IT_FIELDBASED = 1<<2}; |
||
162 | |||
163 | enum { |
||
164 | AVS_FILTER_TYPE=1, |
||
165 | AVS_FILTER_INPUT_COLORSPACE=2, |
||
166 | AVS_FILTER_OUTPUT_TYPE=9, |
||
167 | AVS_FILTER_NAME=4, |
||
168 | AVS_FILTER_AUTHOR=5, |
||
169 | AVS_FILTER_VERSION=6, |
||
170 | AVS_FILTER_ARGS=7, |
||
171 | AVS_FILTER_ARGS_INFO=8, |
||
172 | AVS_FILTER_ARGS_DESCRIPTION=10, |
||
173 | AVS_FILTER_DESCRIPTION=11}; |
||
174 | |||
175 | enum { //SUBTYPES |
||
176 | AVS_FILTER_TYPE_AUDIO=1, |
||
177 | AVS_FILTER_TYPE_VIDEO=2, |
||
178 | AVS_FILTER_OUTPUT_TYPE_SAME=3, |
||
179 | AVS_FILTER_OUTPUT_TYPE_DIFFERENT=4}; |
||
180 | |||
181 | enum { |
||
182 | AVS_CACHE_NOTHING=0, |
||
183 | AVS_CACHE_RANGE=1, |
||
184 | AVS_CACHE_ALL=2, |
||
185 | AVS_CACHE_AUDIO=3, |
||
186 | AVS_CACHE_AUDIO_NONE=4, |
||
187 | AVS_CACHE_AUDIO_AUTO=5 |
||
188 | }; |
||
189 | |||
190 | #define AVS_FRAME_ALIGN 16 |
||
191 | |||
192 | typedef struct AVS_Clip AVS_Clip; |
||
193 | typedef struct AVS_ScriptEnvironment AVS_ScriptEnvironment; |
||
194 | |||
195 | ///////////////////////////////////////////////////////////////////// |
||
196 | // |
||
197 | // AVS_VideoInfo |
||
198 | // |
||
199 | |||
200 | // AVS_VideoInfo is layed out identicly to VideoInfo |
||
201 | typedef struct AVS_VideoInfo { |
||
202 | int width, height; // width=0 means no video |
||
203 | unsigned fps_numerator, fps_denominator; |
||
204 | int num_frames; |
||
205 | |||
206 | int pixel_type; |
||
207 | |||
208 | int audio_samples_per_second; // 0 means no audio |
||
209 | int sample_type; |
||
210 | INT64 num_audio_samples; |
||
211 | int nchannels; |
||
212 | |||
213 | // Imagetype properties |
||
214 | |||
215 | int image_type; |
||
216 | } AVS_VideoInfo; |
||
217 | |||
218 | // useful functions of the above |
||
219 | AVSC_INLINE int avs_has_video(const AVS_VideoInfo * p) |
||
220 | { return (p->width!=0); } |
||
221 | |||
222 | AVSC_INLINE int avs_has_audio(const AVS_VideoInfo * p) |
||
223 | { return (p->audio_samples_per_second!=0); } |
||
224 | |||
225 | AVSC_INLINE int avs_is_rgb(const AVS_VideoInfo * p) |
||
226 | { return !!(p->pixel_type&AVS_CS_BGR); } |
||
227 | |||
228 | AVSC_INLINE int avs_is_rgb24(const AVS_VideoInfo * p) |
||
229 | { return (p->pixel_type&AVS_CS_BGR24)==AVS_CS_BGR24; } // Clear out additional properties |
||
230 | |||
231 | AVSC_INLINE int avs_is_rgb32(const AVS_VideoInfo * p) |
||
232 | { return (p->pixel_type & AVS_CS_BGR32) == AVS_CS_BGR32 ; } |
||
233 | |||
234 | AVSC_INLINE int avs_is_yuv(const AVS_VideoInfo * p) |
||
235 | { return !!(p->pixel_type&AVS_CS_YUV ); } |
||
236 | |||
237 | AVSC_INLINE int avs_is_yuy2(const AVS_VideoInfo * p) |
||
238 | { return (p->pixel_type & AVS_CS_YUY2) == AVS_CS_YUY2; } |
||
239 | |||
240 | AVSC_INLINE int avs_is_yv24(const AVS_VideoInfo * p) |
||
241 | { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV24 & AVS_CS_PLANAR_FILTER); } |
||
242 | |||
243 | AVSC_INLINE int avs_is_yv16(const AVS_VideoInfo * p) |
||
244 | { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV16 & AVS_CS_PLANAR_FILTER); } |
||
245 | |||
246 | AVSC_INLINE int avs_is_yv12(const AVS_VideoInfo * p) |
||
247 | { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV12 & AVS_CS_PLANAR_FILTER); } |
||
248 | |||
249 | AVSC_INLINE int avs_is_yv411(const AVS_VideoInfo * p) |
||
250 | { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV411 & AVS_CS_PLANAR_FILTER); } |
||
251 | |||
252 | AVSC_INLINE int avs_is_y8(const AVS_VideoInfo * p) |
||
253 | { return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_Y8 & AVS_CS_PLANAR_FILTER); } |
||
254 | |||
255 | AVSC_INLINE int avs_is_property(const AVS_VideoInfo * p, int property) |
||
256 | { return ((p->pixel_type & property)==property ); } |
||
257 | |||
258 | AVSC_INLINE int avs_is_planar(const AVS_VideoInfo * p) |
||
259 | { return !!(p->pixel_type & AVS_CS_PLANAR); } |
||
260 | |||
261 | AVSC_INLINE int avs_is_color_space(const AVS_VideoInfo * p, int c_space) |
||
262 | { return avs_is_planar(p) ? ((p->pixel_type & AVS_CS_PLANAR_MASK) == (c_space & AVS_CS_PLANAR_FILTER)) : ((p->pixel_type & c_space) == c_space); } |
||
263 | |||
264 | AVSC_INLINE int avs_is_field_based(const AVS_VideoInfo * p) |
||
265 | { return !!(p->image_type & AVS_IT_FIELDBASED); } |
||
266 | |||
267 | AVSC_INLINE int avs_is_parity_known(const AVS_VideoInfo * p) |
||
268 | { return ((p->image_type & AVS_IT_FIELDBASED)&&(p->image_type & (AVS_IT_BFF | AVS_IT_TFF))); } |
||
269 | |||
270 | AVSC_INLINE int avs_is_bff(const AVS_VideoInfo * p) |
||
271 | { return !!(p->image_type & AVS_IT_BFF); } |
||
272 | |||
273 | AVSC_INLINE int avs_is_tff(const AVS_VideoInfo * p) |
||
274 | { return !!(p->image_type & AVS_IT_TFF); } |
||
275 | |||
276 | AVSC_INLINE int avs_bits_per_pixel(const AVS_VideoInfo * p) |
||
277 | { |
||
278 | switch (p->pixel_type) { |
||
279 | case AVS_CS_BGR24: return 24; |
||
280 | case AVS_CS_BGR32: return 32; |
||
281 | case AVS_CS_YUY2: return 16; |
||
282 | case AVS_CS_YV12: |
||
283 | case AVS_CS_I420: return 12; |
||
284 | default: return 0; |
||
285 | } |
||
286 | } |
||
287 | AVSC_INLINE int avs_bytes_from_pixels(const AVS_VideoInfo * p, int pixels) |
||
288 | { return pixels * (avs_bits_per_pixel(p)>>3); } // Will work on planar images, but will return only luma planes |
||
289 | |||
290 | AVSC_INLINE int avs_row_size(const AVS_VideoInfo * p) |
||
291 | { return avs_bytes_from_pixels(p,p->width); } // Also only returns first plane on planar images |
||
292 | |||
293 | AVSC_INLINE int avs_bmp_size(const AVS_VideoInfo * vi) |
||
294 | { if (avs_is_planar(vi)) {int p = vi->height * ((avs_row_size(vi)+3) & ~3); p+=p>>1; return p; } return vi->height * ((avs_row_size(vi)+3) & ~3); } |
||
295 | |||
296 | AVSC_INLINE int avs_samples_per_second(const AVS_VideoInfo * p) |
||
297 | { return p->audio_samples_per_second; } |
||
298 | |||
299 | |||
300 | AVSC_INLINE int avs_bytes_per_channel_sample(const AVS_VideoInfo * p) |
||
301 | { |
||
302 | switch (p->sample_type) { |
||
303 | case AVS_SAMPLE_INT8: return sizeof(signed char); |
||
304 | case AVS_SAMPLE_INT16: return sizeof(signed short); |
||
305 | case AVS_SAMPLE_INT24: return 3; |
||
306 | case AVS_SAMPLE_INT32: return sizeof(signed int); |
||
307 | case AVS_SAMPLE_FLOAT: return sizeof(float); |
||
308 | default: return 0; |
||
309 | } |
||
310 | } |
||
311 | AVSC_INLINE int avs_bytes_per_audio_sample(const AVS_VideoInfo * p) |
||
312 | { return p->nchannels*avs_bytes_per_channel_sample(p);} |
||
313 | |||
314 | AVSC_INLINE INT64 avs_audio_samples_from_frames(const AVS_VideoInfo * p, INT64 frames) |
||
315 | { return ((INT64)(frames) * p->audio_samples_per_second * p->fps_denominator / p->fps_numerator); } |
||
316 | |||
317 | AVSC_INLINE int avs_frames_from_audio_samples(const AVS_VideoInfo * p, INT64 samples) |
||
318 | { return (int)(samples * (INT64)p->fps_numerator / (INT64)p->fps_denominator / (INT64)p->audio_samples_per_second); } |
||
319 | |||
320 | AVSC_INLINE INT64 avs_audio_samples_from_bytes(const AVS_VideoInfo * p, INT64 bytes) |
||
321 | { return bytes / avs_bytes_per_audio_sample(p); } |
||
322 | |||
323 | AVSC_INLINE INT64 avs_bytes_from_audio_samples(const AVS_VideoInfo * p, INT64 samples) |
||
324 | { return samples * avs_bytes_per_audio_sample(p); } |
||
325 | |||
326 | AVSC_INLINE int avs_audio_channels(const AVS_VideoInfo * p) |
||
327 | { return p->nchannels; } |
||
328 | |||
329 | AVSC_INLINE int avs_sample_type(const AVS_VideoInfo * p) |
||
330 | { return p->sample_type;} |
||
331 | |||
332 | // useful mutator |
||
333 | AVSC_INLINE void avs_set_property(AVS_VideoInfo * p, int property) |
||
334 | { p->image_type|=property; } |
||
335 | |||
336 | AVSC_INLINE void avs_clear_property(AVS_VideoInfo * p, int property) |
||
337 | { p->image_type&=~property; } |
||
338 | |||
339 | AVSC_INLINE void avs_set_field_based(AVS_VideoInfo * p, int isfieldbased) |
||
340 | { if (isfieldbased) p->image_type|=AVS_IT_FIELDBASED; else p->image_type&=~AVS_IT_FIELDBASED; } |
||
341 | |||
342 | AVSC_INLINE void avs_set_fps(AVS_VideoInfo * p, unsigned numerator, unsigned denominator) |
||
343 | { |
||
344 | unsigned x=numerator, y=denominator; |
||
345 | while (y) { // find gcd |
||
346 | unsigned t = x%y; x = y; y = t; |
||
347 | } |
||
348 | p->fps_numerator = numerator/x; |
||
349 | p->fps_denominator = denominator/x; |
||
350 | } |
||
351 | |||
352 | AVSC_INLINE int avs_is_same_colorspace(AVS_VideoInfo * x, AVS_VideoInfo * y) |
||
353 | { |
||
354 | return (x->pixel_type == y->pixel_type) |
||
355 | || (avs_is_yv12(x) && avs_is_yv12(y)); |
||
356 | } |
||
357 | |||
358 | ///////////////////////////////////////////////////////////////////// |
||
359 | // |
||
360 | // AVS_VideoFrame |
||
361 | // |
||
362 | |||
363 | // VideoFrameBuffer holds information about a memory block which is used |
||
364 | // for video data. For efficiency, instances of this class are not deleted |
||
365 | // when the refcount reaches zero; instead they're stored in a linked list |
||
366 | // to be reused. The instances are deleted when the corresponding AVS |
||
367 | // file is closed. |
||
368 | |||
369 | // AVS_VideoFrameBuffer is layed out identicly to VideoFrameBuffer |
||
370 | // DO NOT USE THIS STRUCTURE DIRECTLY |
||
371 | typedef struct AVS_VideoFrameBuffer { |
||
372 | BYTE * data; |
||
373 | int data_size; |
||
374 | // sequence_number is incremented every time the buffer is changed, so |
||
375 | // that stale views can tell they're no longer valid. |
||
376 | volatile long sequence_number; |
||
377 | |||
378 | volatile long refcount; |
||
379 | } AVS_VideoFrameBuffer; |
||
380 | |||
381 | // VideoFrame holds a "window" into a VideoFrameBuffer. |
||
382 | |||
383 | // AVS_VideoFrame is layed out identicly to IVideoFrame |
||
384 | // DO NOT USE THIS STRUCTURE DIRECTLY |
||
385 | typedef struct AVS_VideoFrame { |
||
386 | volatile long refcount; |
||
387 | AVS_VideoFrameBuffer * vfb; |
||
388 | int offset, pitch, row_size, height, offsetU, offsetV, pitchUV; // U&V offsets are from top of picture. |
||
389 | int row_sizeUV, heightUV; |
||
390 | } AVS_VideoFrame; |
||
391 | |||
392 | // Access functions for AVS_VideoFrame |
||
393 | AVSC_INLINE int avs_get_pitch(const AVS_VideoFrame * p) { |
||
394 | return p->pitch;} |
||
395 | |||
396 | AVSC_INLINE int avs_get_pitch_p(const AVS_VideoFrame * p, int plane) { |
||
397 | switch (plane) { |
||
398 | case AVS_PLANAR_U: case AVS_PLANAR_V: return p->pitchUV;} |
||
399 | return p->pitch;} |
||
400 | |||
401 | AVSC_INLINE int avs_get_row_size(const AVS_VideoFrame * p) { |
||
402 | return p->row_size; } |
||
403 | |||
404 | AVSC_INLINE int avs_get_row_size_p(const AVS_VideoFrame * p, int plane) { |
||
405 | int r; |
||
406 | switch (plane) { |
||
407 | case AVS_PLANAR_U: case AVS_PLANAR_V: |
||
408 | if (p->pitchUV) return p->row_sizeUV; |
||
409 | else return 0; |
||
410 | case AVS_PLANAR_U_ALIGNED: case AVS_PLANAR_V_ALIGNED: |
||
411 | if (p->pitchUV) { |
||
412 | r = (p->row_sizeUV+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)); // Aligned rowsize |
||
413 | if (r < p->pitchUV) |
||
414 | return r; |
||
415 | return p->row_sizeUV; |
||
416 | } else return 0; |
||
417 | case AVS_PLANAR_Y_ALIGNED: |
||
418 | r = (p->row_size+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)); // Aligned rowsize |
||
419 | if (r <= p->pitch) |
||
420 | return r; |
||
421 | return p->row_size; |
||
422 | } |
||
423 | return p->row_size; |
||
424 | } |
||
425 | |||
426 | AVSC_INLINE int avs_get_height(const AVS_VideoFrame * p) { |
||
427 | return p->height;} |
||
428 | |||
429 | AVSC_INLINE int avs_get_height_p(const AVS_VideoFrame * p, int plane) { |
||
430 | switch (plane) { |
||
431 | case AVS_PLANAR_U: case AVS_PLANAR_V: |
||
432 | if (p->pitchUV) return p->heightUV; |
||
433 | return 0; |
||
434 | } |
||
435 | return p->height;} |
||
436 | |||
437 | AVSC_INLINE const BYTE* avs_get_read_ptr(const AVS_VideoFrame * p) { |
||
438 | return p->vfb->data + p->offset;} |
||
439 | |||
440 | AVSC_INLINE const BYTE* avs_get_read_ptr_p(const AVS_VideoFrame * p, int plane) |
||
441 | { |
||
442 | switch (plane) { |
||
443 | case AVS_PLANAR_U: return p->vfb->data + p->offsetU; |
||
444 | case AVS_PLANAR_V: return p->vfb->data + p->offsetV; |
||
445 | default: return p->vfb->data + p->offset;} |
||
446 | } |
||
447 | |||
448 | AVSC_INLINE int avs_is_writable(const AVS_VideoFrame * p) { |
||
449 | return (p->refcount == 1 && p->vfb->refcount == 1);} |
||
450 | |||
451 | AVSC_INLINE BYTE* avs_get_write_ptr(const AVS_VideoFrame * p) |
||
452 | { |
||
453 | if (avs_is_writable(p)) { |
||
454 | ++p->vfb->sequence_number; |
||
455 | return p->vfb->data + p->offset; |
||
456 | } else |
||
457 | return 0; |
||
458 | } |
||
459 | |||
460 | AVSC_INLINE BYTE* avs_get_write_ptr_p(const AVS_VideoFrame * p, int plane) |
||
461 | { |
||
462 | if (plane==AVS_PLANAR_Y && avs_is_writable(p)) { |
||
463 | ++p->vfb->sequence_number; |
||
464 | return p->vfb->data + p->offset; |
||
465 | } else if (plane==AVS_PLANAR_Y) { |
||
466 | return 0; |
||
467 | } else { |
||
468 | switch (plane) { |
||
469 | case AVS_PLANAR_U: return p->vfb->data + p->offsetU; |
||
470 | case AVS_PLANAR_V: return p->vfb->data + p->offsetV; |
||
471 | default: return p->vfb->data + p->offset; |
||
472 | } |
||
473 | } |
||
474 | } |
||
475 | |||
476 | |||
477 | AVSC_API(void, avs_release_video_frame)(AVS_VideoFrame *); |
||
478 | // makes a shallow copy of a video frame |
||
479 | AVSC_API(AVS_VideoFrame *, avs_copy_video_frame)(AVS_VideoFrame *); |
||
480 | |||
481 | #ifndef AVSC_NO_DECLSPEC |
||
482 | AVSC_INLINE void avs_release_frame(AVS_VideoFrame * f) |
||
483 | {avs_release_video_frame(f);} |
||
484 | AVSC_INLINE AVS_VideoFrame * avs_copy_frame(AVS_VideoFrame * f) |
||
485 | {return avs_copy_video_frame(f);} |
||
486 | #endif |
||
487 | |||
488 | ///////////////////////////////////////////////////////////////////// |
||
489 | // |
||
490 | // AVS_Value |
||
491 | // |
||
492 | |||
493 | // Treat AVS_Value as a fat pointer. That is use avs_copy_value |
||
494 | // and avs_release_value appropiaty as you would if AVS_Value was |
||
495 | // a pointer. |
||
496 | |||
497 | // To maintain source code compatibility with future versions of the |
||
498 | // avisynth_c API don't use the AVS_Value directly. Use the helper |
||
499 | // functions below. |
||
500 | |||
501 | // AVS_Value is layed out identicly to AVSValue |
||
502 | typedef struct AVS_Value AVS_Value; |
||
503 | struct AVS_Value { |
||
504 | short type; // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, or 'l'ong |
||
505 | // for some function e'rror |
||
506 | short array_size; |
||
507 | union { |
||
508 | void * clip; // do not use directly, use avs_take_clip |
||
509 | char boolean; |
||
510 | int integer; |
||
511 | float floating_pt; |
||
512 | const char * string; |
||
513 | const AVS_Value * array; |
||
514 | } d; |
||
515 | }; |
||
516 | |||
517 | // AVS_Value should be initilized with avs_void. |
||
518 | // Should also set to avs_void after the value is released |
||
519 | // with avs_copy_value. Consider it the equalvent of setting |
||
520 | // a pointer to NULL |
||
521 | static const AVS_Value avs_void = {'v'}; |
||
522 | |||
523 | AVSC_API(void, avs_copy_value)(AVS_Value * dest, AVS_Value src); |
||
524 | AVSC_API(void, avs_release_value)(AVS_Value); |
||
525 | |||
526 | AVSC_INLINE int avs_defined(AVS_Value v) { return v.type != 'v'; } |
||
527 | AVSC_INLINE int avs_is_clip(AVS_Value v) { return v.type == 'c'; } |
||
528 | AVSC_INLINE int avs_is_bool(AVS_Value v) { return v.type == 'b'; } |
||
529 | AVSC_INLINE int avs_is_int(AVS_Value v) { return v.type == 'i'; } |
||
530 | AVSC_INLINE int avs_is_float(AVS_Value v) { return v.type == 'f' || v.type == 'i'; } |
||
531 | AVSC_INLINE int avs_is_string(AVS_Value v) { return v.type == 's'; } |
||
532 | AVSC_INLINE int avs_is_array(AVS_Value v) { return v.type == 'a'; } |
||
533 | AVSC_INLINE int avs_is_error(AVS_Value v) { return v.type == 'e'; } |
||
534 | |||
535 | AVSC_API(AVS_Clip *, avs_take_clip)(AVS_Value, AVS_ScriptEnvironment *); |
||
536 | AVSC_API(void, avs_set_to_clip)(AVS_Value *, AVS_Clip *); |
||
537 | |||
538 | AVSC_INLINE int avs_as_bool(AVS_Value v) |
||
539 | { return v.d.boolean; } |
||
540 | AVSC_INLINE int avs_as_int(AVS_Value v) |
||
541 | { return v.d.integer; } |
||
542 | AVSC_INLINE const char * avs_as_string(AVS_Value v) |
||
543 | { return avs_is_error(v) || avs_is_string(v) ? v.d.string : 0; } |
||
544 | AVSC_INLINE double avs_as_float(AVS_Value v) |
||
545 | { return avs_is_int(v) ? v.d.integer : v.d.floating_pt; } |
||
546 | AVSC_INLINE const char * avs_as_error(AVS_Value v) |
||
547 | { return avs_is_error(v) ? v.d.string : 0; } |
||
548 | AVSC_INLINE const AVS_Value * avs_as_array(AVS_Value v) |
||
549 | { return v.d.array; } |
||
550 | AVSC_INLINE int avs_array_size(AVS_Value v) |
||
551 | { return avs_is_array(v) ? v.array_size : 1; } |
||
552 | AVSC_INLINE AVS_Value avs_array_elt(AVS_Value v, int index) |
||
553 | { return avs_is_array(v) ? v.d.array[index] : v; } |
||
554 | |||
555 | // only use these functions on an AVS_Value that does not already have |
||
556 | // an active value. Remember, treat AVS_Value as a fat pointer. |
||
557 | AVSC_INLINE AVS_Value avs_new_value_bool(int v0) |
||
558 | { AVS_Value v; v.type = 'b'; v.d.boolean = v0 == 0 ? 0 : 1; return v; } |
||
559 | AVSC_INLINE AVS_Value avs_new_value_int(int v0) |
||
560 | { AVS_Value v; v.type = 'i'; v.d.integer = v0; return v; } |
||
561 | AVSC_INLINE AVS_Value avs_new_value_string(const char * v0) |
||
562 | { AVS_Value v; v.type = 's'; v.d.string = v0; return v; } |
||
563 | AVSC_INLINE AVS_Value avs_new_value_float(float v0) |
||
564 | { AVS_Value v; v.type = 'f'; v.d.floating_pt = v0; return v;} |
||
565 | AVSC_INLINE AVS_Value avs_new_value_error(const char * v0) |
||
566 | { AVS_Value v; v.type = 'e'; v.d.string = v0; return v; } |
||
567 | #ifndef AVSC_NO_DECLSPEC |
||
568 | AVSC_INLINE AVS_Value avs_new_value_clip(AVS_Clip * v0) |
||
569 | { AVS_Value v; avs_set_to_clip(&v, v0); return v; } |
||
570 | #endif |
||
571 | AVSC_INLINE AVS_Value avs_new_value_array(AVS_Value * v0, int size) |
||
572 | { AVS_Value v; v.type = 'a'; v.d.array = v0; v.array_size = size; return v; } |
||
573 | |||
574 | ///////////////////////////////////////////////////////////////////// |
||
575 | // |
||
576 | // AVS_Clip |
||
577 | // |
||
578 | |||
579 | AVSC_API(void, avs_release_clip)(AVS_Clip *); |
||
580 | AVSC_API(AVS_Clip *, avs_copy_clip)(AVS_Clip *); |
||
581 | |||
582 | AVSC_API(const char *, avs_clip_get_error)(AVS_Clip *); // return 0 if no error |
||
583 | |||
584 | AVSC_API(const AVS_VideoInfo *, avs_get_video_info)(AVS_Clip *); |
||
585 | |||
586 | AVSC_API(int, avs_get_version)(AVS_Clip *); |
||
587 | |||
588 | AVSC_API(AVS_VideoFrame *, avs_get_frame)(AVS_Clip *, int n); |
||
589 | // The returned video frame must be released with avs_release_video_frame |
||
590 | |||
591 | AVSC_API(int, avs_get_parity)(AVS_Clip *, int n); |
||
592 | // return field parity if field_based, else parity of first field in frame |
||
593 | |||
594 | AVSC_API(int, avs_get_audio)(AVS_Clip *, void * buf, |
||
595 | INT64 start, INT64 count); |
||
596 | // start and count are in samples |
||
597 | |||
598 | AVSC_API(int, avs_set_cache_hints)(AVS_Clip *, |
||
599 | int cachehints, int frame_range); |
||
600 | |||
601 | // This is the callback type used by avs_add_function |
||
602 | typedef AVS_Value (AVSC_CC * AVS_ApplyFunc) |
||
603 | (AVS_ScriptEnvironment *, AVS_Value args, void * user_data); |
||
604 | |||
605 | typedef struct AVS_FilterInfo AVS_FilterInfo; |
||
606 | struct AVS_FilterInfo |
||
607 | { |
||
608 | // these members should not be modified outside of the AVS_ApplyFunc callback |
||
609 | AVS_Clip * child; |
||
610 | AVS_VideoInfo vi; |
||
611 | AVS_ScriptEnvironment * env; |
||
612 | AVS_VideoFrame * (AVSC_CC * get_frame)(AVS_FilterInfo *, int n); |
||
613 | int (AVSC_CC * get_parity)(AVS_FilterInfo *, int n); |
||
614 | int (AVSC_CC * get_audio)(AVS_FilterInfo *, void * buf, |
||
615 | INT64 start, INT64 count); |
||
616 | int (AVSC_CC * set_cache_hints)(AVS_FilterInfo *, int cachehints, |
||
617 | int frame_range); |
||
618 | void (AVSC_CC * free_filter)(AVS_FilterInfo *); |
||
619 | |||
620 | // Should be set when ever there is an error to report. |
||
621 | // It is cleared before any of the above methods are called |
||
622 | const char * error; |
||
623 | // this is to store whatever and may be modified at will |
||
624 | void * user_data; |
||
625 | }; |
||
626 | |||
627 | // Create a new filter |
||
628 | // fi is set to point to the AVS_FilterInfo so that you can |
||
629 | // modify it once it is initilized. |
||
630 | // store_child should generally be set to true. If it is not |
||
631 | // set than ALL methods (the function pointers) must be defined |
||
632 | // If it is set than you do not need to worry about freeing the child |
||
633 | // clip. |
||
634 | AVSC_API(AVS_Clip *, avs_new_c_filter)(AVS_ScriptEnvironment * e, |
||
635 | AVS_FilterInfo * * fi, |
||
636 | AVS_Value child, int store_child); |
||
637 | |||
638 | ///////////////////////////////////////////////////////////////////// |
||
639 | // |
||
640 | // AVS_ScriptEnvironment |
||
641 | // |
||
642 | |||
643 | // For GetCPUFlags. These are backwards-compatible with those in VirtualDub. |
||
644 | enum { |
||
645 | /* slowest CPU to support extension */ |
||
646 | AVS_CPU_FORCE = 0x01, // N/A |
||
647 | AVS_CPU_FPU = 0x02, // 386/486DX |
||
648 | AVS_CPU_MMX = 0x04, // P55C, K6, PII |
||
649 | AVS_CPU_INTEGER_SSE = 0x08, // PIII, Athlon |
||
650 | AVS_CPU_SSE = 0x10, // PIII, Athlon XP/MP |
||
651 | AVS_CPU_SSE2 = 0x20, // PIV, Hammer |
||
652 | AVS_CPU_3DNOW = 0x40, // K6-2 |
||
653 | AVS_CPU_3DNOW_EXT = 0x80, // Athlon |
||
654 | AVS_CPU_X86_64 = 0xA0, // Hammer (note: equiv. to 3DNow + SSE2, |
||
655 | // which only Hammer will have anyway) |
||
656 | AVS_CPUF_SSE3 = 0x100, // PIV+, K8 Venice |
||
657 | AVS_CPUF_SSSE3 = 0x200, // Core 2 |
||
658 | AVS_CPUF_SSE4 = 0x400, // Penryn, Wolfdale, Yorkfield |
||
659 | AVS_CPUF_SSE4_1 = 0x400, |
||
660 | AVS_CPUF_SSE4_2 = 0x800, // Nehalem |
||
661 | }; |
||
662 | |||
663 | AVSC_API(const char *, avs_get_error)(AVS_ScriptEnvironment *); // return 0 if no error |
||
664 | |||
665 | AVSC_API(long, avs_get_cpu_flags)(AVS_ScriptEnvironment *); |
||
666 | AVSC_API(int, avs_check_version)(AVS_ScriptEnvironment *, int version); |
||
667 | |||
668 | AVSC_API(char *, avs_save_string)(AVS_ScriptEnvironment *, const char* s, int length); |
||
669 | AVSC_API(char *, avs_sprintf)(AVS_ScriptEnvironment *, const char * fmt, ...); |
||
670 | |||
671 | AVSC_API(char *, avs_vsprintf)(AVS_ScriptEnvironment *, const char * fmt, void* val); |
||
672 | // note: val is really a va_list; I hope everyone typedefs va_list to a pointer |
||
673 | |||
674 | AVSC_API(int, avs_add_function)(AVS_ScriptEnvironment *, |
||
675 | const char * name, const char * params, |
||
676 | AVS_ApplyFunc apply, void * user_data); |
||
677 | |||
678 | AVSC_API(int, avs_function_exists)(AVS_ScriptEnvironment *, const char * name); |
||
679 | |||
680 | AVSC_API(AVS_Value, avs_invoke)(AVS_ScriptEnvironment *, const char * name, |
||
681 | AVS_Value args, const char** arg_names); |
||
682 | // The returned value must be be released with avs_release_value |
||
683 | |||
684 | AVSC_API(AVS_Value, avs_get_var)(AVS_ScriptEnvironment *, const char* name); |
||
685 | // The returned value must be be released with avs_release_value |
||
686 | |||
687 | AVSC_API(int, avs_set_var)(AVS_ScriptEnvironment *, const char* name, AVS_Value val); |
||
688 | |||
689 | AVSC_API(int, avs_set_global_var)(AVS_ScriptEnvironment *, const char* name, const AVS_Value val); |
||
690 | |||
691 | //void avs_push_context(AVS_ScriptEnvironment *, int level=0); |
||
692 | //void avs_pop_context(AVS_ScriptEnvironment *); |
||
693 | |||
694 | AVSC_API(AVS_VideoFrame *, avs_new_video_frame_a)(AVS_ScriptEnvironment *, |
||
695 | const AVS_VideoInfo * vi, int align); |
||
696 | // align should be at least 16 |
||
697 | |||
698 | #ifndef AVSC_NO_DECLSPEC |
||
699 | AVSC_INLINE |
||
700 | AVS_VideoFrame * avs_new_video_frame(AVS_ScriptEnvironment * env, |
||
701 | const AVS_VideoInfo * vi) |
||
702 | {return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);} |
||
703 | |||
704 | AVSC_INLINE |
||
705 | AVS_VideoFrame * avs_new_frame(AVS_ScriptEnvironment * env, |
||
706 | const AVS_VideoInfo * vi) |
||
707 | {return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);} |
||
708 | #endif |
||
709 | |||
710 | |||
711 | AVSC_API(int, avs_make_writable)(AVS_ScriptEnvironment *, AVS_VideoFrame * * pvf); |
||
712 | |||
713 | AVSC_API(void, avs_bit_blt)(AVS_ScriptEnvironment *, BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height); |
||
714 | |||
715 | typedef void (AVSC_CC *AVS_ShutdownFunc)(void* user_data, AVS_ScriptEnvironment * env); |
||
716 | AVSC_API(void, avs_at_exit)(AVS_ScriptEnvironment *, AVS_ShutdownFunc function, void * user_data); |
||
717 | |||
718 | AVSC_API(AVS_VideoFrame *, avs_subframe)(AVS_ScriptEnvironment *, AVS_VideoFrame * src, int rel_offset, int new_pitch, int new_row_size, int new_height); |
||
719 | // The returned video frame must be be released |
||
720 | |||
721 | AVSC_API(int, avs_set_memory_max)(AVS_ScriptEnvironment *, int mem); |
||
722 | |||
723 | AVSC_API(int, avs_set_working_dir)(AVS_ScriptEnvironment *, const char * newdir); |
||
724 | |||
725 | // avisynth.dll exports this; it's a way to use it as a library, without |
||
726 | // writing an AVS script or without going through AVIFile. |
||
727 | AVSC_API(AVS_ScriptEnvironment *, avs_create_script_environment)(int version); |
||
728 | |||
729 | // this symbol is the entry point for the plugin and must |
||
730 | // be defined |
||
731 | AVSC_EXPORT |
||
732 | const char * AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env); |
||
733 | |||
734 | |||
735 | AVSC_API(void, avs_delete_script_environment)(AVS_ScriptEnvironment *); |
||
736 | |||
737 | |||
738 | AVSC_API(AVS_VideoFrame *, avs_subframe_planar)(AVS_ScriptEnvironment *, AVS_VideoFrame * src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV); |
||
739 | // The returned video frame must be be released |
||
740 | |||
741 | #ifdef AVSC_NO_DECLSPEC |
||
742 | // use LoadLibrary and related functions to dynamically load Avisynth instead of declspec(dllimport) |
||
743 | /* |
||
744 | The following functions needs to have been declared, probably from windows.h |
||
745 | |||
746 | void* malloc(size_t) |
||
747 | void free(void*); |
||
748 | |||
749 | HMODULE LoadLibrary(const char*); |
||
750 | void* GetProcAddress(HMODULE, const char*); |
||
751 | FreeLibrary(HMODULE); |
||
752 | */ |
||
753 | |||
754 | |||
755 | typedef struct AVS_Library AVS_Library; |
||
756 | |||
757 | #define AVSC_DECLARE_FUNC(name) name##_func name |
||
758 | |||
759 | struct AVS_Library { |
||
760 | HMODULE handle; |
||
761 | |||
762 | AVSC_DECLARE_FUNC(avs_add_function); |
||
763 | AVSC_DECLARE_FUNC(avs_at_exit); |
||
764 | AVSC_DECLARE_FUNC(avs_bit_blt); |
||
765 | AVSC_DECLARE_FUNC(avs_check_version); |
||
766 | AVSC_DECLARE_FUNC(avs_clip_get_error); |
||
767 | AVSC_DECLARE_FUNC(avs_copy_clip); |
||
768 | AVSC_DECLARE_FUNC(avs_copy_value); |
||
769 | AVSC_DECLARE_FUNC(avs_copy_video_frame); |
||
770 | AVSC_DECLARE_FUNC(avs_create_script_environment); |
||
771 | AVSC_DECLARE_FUNC(avs_delete_script_environment); |
||
772 | AVSC_DECLARE_FUNC(avs_function_exists); |
||
773 | AVSC_DECLARE_FUNC(avs_get_audio); |
||
774 | AVSC_DECLARE_FUNC(avs_get_cpu_flags); |
||
775 | AVSC_DECLARE_FUNC(avs_get_error); |
||
776 | AVSC_DECLARE_FUNC(avs_get_frame); |
||
777 | AVSC_DECLARE_FUNC(avs_get_parity); |
||
778 | AVSC_DECLARE_FUNC(avs_get_var); |
||
779 | AVSC_DECLARE_FUNC(avs_get_version); |
||
780 | AVSC_DECLARE_FUNC(avs_get_video_info); |
||
781 | AVSC_DECLARE_FUNC(avs_invoke); |
||
782 | AVSC_DECLARE_FUNC(avs_make_writable); |
||
783 | AVSC_DECLARE_FUNC(avs_new_c_filter); |
||
784 | AVSC_DECLARE_FUNC(avs_new_video_frame_a); |
||
785 | AVSC_DECLARE_FUNC(avs_release_clip); |
||
786 | AVSC_DECLARE_FUNC(avs_release_value); |
||
787 | AVSC_DECLARE_FUNC(avs_release_video_frame); |
||
788 | AVSC_DECLARE_FUNC(avs_save_string); |
||
789 | AVSC_DECLARE_FUNC(avs_set_cache_hints); |
||
790 | AVSC_DECLARE_FUNC(avs_set_global_var); |
||
791 | AVSC_DECLARE_FUNC(avs_set_memory_max); |
||
792 | AVSC_DECLARE_FUNC(avs_set_to_clip); |
||
793 | AVSC_DECLARE_FUNC(avs_set_var); |
||
794 | AVSC_DECLARE_FUNC(avs_set_working_dir); |
||
795 | AVSC_DECLARE_FUNC(avs_sprintf); |
||
796 | AVSC_DECLARE_FUNC(avs_subframe); |
||
797 | AVSC_DECLARE_FUNC(avs_subframe_planar); |
||
798 | AVSC_DECLARE_FUNC(avs_take_clip); |
||
799 | AVSC_DECLARE_FUNC(avs_vsprintf); |
||
800 | }; |
||
801 | |||
802 | #undef AVSC_DECLARE_FUNC |
||
803 | |||
804 | |||
805 | AVSC_INLINE AVS_Library * avs_load_library() { |
||
806 | AVS_Library *library = (AVS_Library *)malloc(sizeof(AVS_Library)); |
||
807 | if (library == NULL) |
||
808 | return NULL; |
||
809 | library->handle = LoadLibrary("avisynth"); |
||
810 | if (library->handle == NULL) |
||
811 | goto fail; |
||
812 | |||
813 | #define __AVSC_STRINGIFY(x) #x |
||
814 | #define AVSC_STRINGIFY(x) __AVSC_STRINGIFY(x) |
||
815 | #define AVSC_LOAD_FUNC(name) {\ |
||
816 | library->name = (name##_func) GetProcAddress(library->handle, AVSC_STRINGIFY(name));\ |
||
817 | if (library->name == NULL)\ |
||
818 | goto fail;\ |
||
819 | } |
||
820 | |||
821 | AVSC_LOAD_FUNC(avs_add_function); |
||
822 | AVSC_LOAD_FUNC(avs_at_exit); |
||
823 | AVSC_LOAD_FUNC(avs_bit_blt); |
||
824 | AVSC_LOAD_FUNC(avs_check_version); |
||
825 | AVSC_LOAD_FUNC(avs_clip_get_error); |
||
826 | AVSC_LOAD_FUNC(avs_copy_clip); |
||
827 | AVSC_LOAD_FUNC(avs_copy_value); |
||
828 | AVSC_LOAD_FUNC(avs_copy_video_frame); |
||
829 | AVSC_LOAD_FUNC(avs_create_script_environment); |
||
830 | AVSC_LOAD_FUNC(avs_delete_script_environment); |
||
831 | AVSC_LOAD_FUNC(avs_function_exists); |
||
832 | AVSC_LOAD_FUNC(avs_get_audio); |
||
833 | AVSC_LOAD_FUNC(avs_get_cpu_flags); |
||
834 | AVSC_LOAD_FUNC(avs_get_error); |
||
835 | AVSC_LOAD_FUNC(avs_get_frame); |
||
836 | AVSC_LOAD_FUNC(avs_get_parity); |
||
837 | AVSC_LOAD_FUNC(avs_get_var); |
||
838 | AVSC_LOAD_FUNC(avs_get_version); |
||
839 | AVSC_LOAD_FUNC(avs_get_video_info); |
||
840 | AVSC_LOAD_FUNC(avs_invoke); |
||
841 | AVSC_LOAD_FUNC(avs_make_writable); |
||
842 | AVSC_LOAD_FUNC(avs_new_c_filter); |
||
843 | AVSC_LOAD_FUNC(avs_new_video_frame_a); |
||
844 | AVSC_LOAD_FUNC(avs_release_clip); |
||
845 | AVSC_LOAD_FUNC(avs_release_value); |
||
846 | AVSC_LOAD_FUNC(avs_release_video_frame); |
||
847 | AVSC_LOAD_FUNC(avs_save_string); |
||
848 | AVSC_LOAD_FUNC(avs_set_cache_hints); |
||
849 | AVSC_LOAD_FUNC(avs_set_global_var); |
||
850 | AVSC_LOAD_FUNC(avs_set_memory_max); |
||
851 | AVSC_LOAD_FUNC(avs_set_to_clip); |
||
852 | AVSC_LOAD_FUNC(avs_set_var); |
||
853 | AVSC_LOAD_FUNC(avs_set_working_dir); |
||
854 | AVSC_LOAD_FUNC(avs_sprintf); |
||
855 | AVSC_LOAD_FUNC(avs_subframe); |
||
856 | AVSC_LOAD_FUNC(avs_subframe_planar); |
||
857 | AVSC_LOAD_FUNC(avs_take_clip); |
||
858 | AVSC_LOAD_FUNC(avs_vsprintf); |
||
859 | |||
860 | #undef __AVSC_STRINGIFY |
||
861 | #undef AVSC_STRINGIFY |
||
862 | #undef AVSC_LOAD_FUNC |
||
863 | |||
864 | return library; |
||
865 | |||
866 | fail: |
||
867 | free(library); |
||
868 | return NULL; |
||
869 | } |
||
870 | |||
871 | AVSC_INLINE void avs_free_library(AVS_Library *library) { |
||
872 | if (library == NULL) |
||
873 | return; |
||
874 | FreeLibrary(library->handle); |
||
875 | free(library); |
||
876 | } |
||
877 | #endif |
||
878 | |||
879 | #endif=>>2}; |