• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * AviSynth(+) support
3  * Copyright (c) 2012 AvxSynth Team
4  *
5  * This file is part of FFmpeg
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/attributes.h"
23 #include "libavutil/internal.h"
24 
25 #include "libavcodec/internal.h"
26 
27 #include "avformat.h"
28 #include "internal.h"
29 #include "config.h"
30 
31 /* Enable function pointer definitions for runtime loading. */
32 #define AVSC_NO_DECLSPEC
33 
34 /* Platform-specific directives. */
35 #ifdef _WIN32
36   #include "compat/w32dlfcn.h"
37   #undef EXTERN_C
38   #define AVISYNTH_LIB "avisynth"
39 #else
40   #include <dlfcn.h>
41   #define AVISYNTH_NAME "libavisynth"
42   #define AVISYNTH_LIB AVISYNTH_NAME SLIBSUF
43 #endif
44 
45 /* Endianness guards for audio */
46 #if HAVE_BIGENDIAN
47     #define PCM(format) (AV_CODEC_ID_PCM_ ## format ## BE)
48 #else
49     #define PCM(format) (AV_CODEC_ID_PCM_ ## format ## LE)
50 #endif
51 
52 #include <avisynth/avisynth_c.h>
53 
54 typedef struct AviSynthLibrary {
55     void *library;
56 #define AVSC_DECLARE_FUNC(name) name ## _func name
57     AVSC_DECLARE_FUNC(avs_bit_blt);
58     AVSC_DECLARE_FUNC(avs_clip_get_error);
59     AVSC_DECLARE_FUNC(avs_create_script_environment);
60     AVSC_DECLARE_FUNC(avs_delete_script_environment);
61     AVSC_DECLARE_FUNC(avs_get_audio);
62     AVSC_DECLARE_FUNC(avs_get_error);
63     AVSC_DECLARE_FUNC(avs_get_frame);
64     AVSC_DECLARE_FUNC(avs_get_version);
65     AVSC_DECLARE_FUNC(avs_get_video_info);
66     AVSC_DECLARE_FUNC(avs_invoke);
67     AVSC_DECLARE_FUNC(avs_is_color_space);
68     AVSC_DECLARE_FUNC(avs_release_clip);
69     AVSC_DECLARE_FUNC(avs_release_value);
70     AVSC_DECLARE_FUNC(avs_release_video_frame);
71     AVSC_DECLARE_FUNC(avs_take_clip);
72     AVSC_DECLARE_FUNC(avs_bits_per_pixel);
73     AVSC_DECLARE_FUNC(avs_get_height_p);
74     AVSC_DECLARE_FUNC(avs_get_pitch_p);
75     AVSC_DECLARE_FUNC(avs_get_read_ptr_p);
76     AVSC_DECLARE_FUNC(avs_get_row_size_p);
77     AVSC_DECLARE_FUNC(avs_is_planar_rgb);
78     AVSC_DECLARE_FUNC(avs_is_planar_rgba);
79 #undef AVSC_DECLARE_FUNC
80 } AviSynthLibrary;
81 
82 typedef struct AviSynthContext {
83     AVS_ScriptEnvironment *env;
84     AVS_Clip *clip;
85     const AVS_VideoInfo *vi;
86 
87     /* avisynth_read_packet_video() iterates over this. */
88     int n_planes;
89     const int *planes;
90 
91     int curr_stream;
92     int curr_frame;
93     int64_t curr_sample;
94 
95     int error;
96 
97     /* Linked list pointers. */
98     struct AviSynthContext *next;
99 } AviSynthContext;
100 
101 static const int avs_planes_packed[1] = { 0 };
102 static const int avs_planes_grey[1]   = { AVS_PLANAR_Y };
103 static const int avs_planes_yuv[3]    = { AVS_PLANAR_Y, AVS_PLANAR_U,
104                                           AVS_PLANAR_V };
105 static const int avs_planes_rgb[3]    = { AVS_PLANAR_G, AVS_PLANAR_B,
106                                           AVS_PLANAR_R };
107 static const int avs_planes_yuva[4]   = { AVS_PLANAR_Y, AVS_PLANAR_U,
108                                           AVS_PLANAR_V, AVS_PLANAR_A };
109 static const int avs_planes_rgba[4]   = { AVS_PLANAR_G, AVS_PLANAR_B,
110                                           AVS_PLANAR_R, AVS_PLANAR_A };
111 
112 /* A conflict between C++ global objects, atexit, and dynamic loading requires
113  * us to register our own atexit handler to prevent double freeing. */
114 static AviSynthLibrary avs_library;
115 static int avs_atexit_called        = 0;
116 
117 /* Linked list of AviSynthContexts. An atexit handler destroys this list. */
118 static AviSynthContext *avs_ctx_list = NULL;
119 
120 static av_cold void avisynth_atexit_handler(void);
121 
avisynth_load_library(void)122 static av_cold int avisynth_load_library(void)
123 {
124     avs_library.library = dlopen(AVISYNTH_LIB, RTLD_NOW | RTLD_LOCAL);
125     if (!avs_library.library)
126         return AVERROR_UNKNOWN;
127 
128 #define LOAD_AVS_FUNC(name, continue_on_fail)                          \
129         avs_library.name = (name ## _func)                             \
130                            dlsym(avs_library.library, #name);          \
131         if (!continue_on_fail && !avs_library.name)                    \
132             goto fail;
133 
134     LOAD_AVS_FUNC(avs_bit_blt, 0);
135     LOAD_AVS_FUNC(avs_clip_get_error, 0);
136     LOAD_AVS_FUNC(avs_create_script_environment, 0);
137     LOAD_AVS_FUNC(avs_delete_script_environment, 0);
138     LOAD_AVS_FUNC(avs_get_audio, 0);
139     LOAD_AVS_FUNC(avs_get_error, 1); // New to AviSynth 2.6
140     LOAD_AVS_FUNC(avs_get_frame, 0);
141     LOAD_AVS_FUNC(avs_get_version, 0);
142     LOAD_AVS_FUNC(avs_get_video_info, 0);
143     LOAD_AVS_FUNC(avs_invoke, 0);
144     LOAD_AVS_FUNC(avs_is_color_space, 1);
145     LOAD_AVS_FUNC(avs_release_clip, 0);
146     LOAD_AVS_FUNC(avs_release_value, 0);
147     LOAD_AVS_FUNC(avs_release_video_frame, 0);
148     LOAD_AVS_FUNC(avs_take_clip, 0);
149     LOAD_AVS_FUNC(avs_bits_per_pixel, 1);
150     LOAD_AVS_FUNC(avs_get_height_p, 1);
151     LOAD_AVS_FUNC(avs_get_pitch_p, 1);
152     LOAD_AVS_FUNC(avs_get_read_ptr_p, 1);
153     LOAD_AVS_FUNC(avs_get_row_size_p, 1);
154     LOAD_AVS_FUNC(avs_is_planar_rgb, 1);
155     LOAD_AVS_FUNC(avs_is_planar_rgba, 1);
156 #undef LOAD_AVS_FUNC
157 
158     atexit(avisynth_atexit_handler);
159     return 0;
160 
161 fail:
162     dlclose(avs_library.library);
163     return AVERROR_UNKNOWN;
164 }
165 
166 /* Note that avisynth_context_create and avisynth_context_destroy
167  * do not allocate or free the actual context! That is taken care of
168  * by libavformat. */
avisynth_context_create(AVFormatContext * s)169 static av_cold int avisynth_context_create(AVFormatContext *s)
170 {
171     AviSynthContext *avs = s->priv_data;
172     int ret;
173 
174     if (!avs_library.library)
175         if (ret = avisynth_load_library())
176             return ret;
177 
178     avs->env = avs_library.avs_create_script_environment(3);
179     if (avs_library.avs_get_error) {
180         const char *error = avs_library.avs_get_error(avs->env);
181         if (error) {
182             av_log(s, AV_LOG_ERROR, "%s\n", error);
183             return AVERROR_UNKNOWN;
184         }
185     }
186 
187     if (!avs_ctx_list) {
188         avs_ctx_list = avs;
189     } else {
190         avs->next    = avs_ctx_list;
191         avs_ctx_list = avs;
192     }
193 
194     return 0;
195 }
196 
avisynth_context_destroy(AviSynthContext * avs)197 static av_cold void avisynth_context_destroy(AviSynthContext *avs)
198 {
199     if (avs_atexit_called)
200         return;
201 
202     if (avs == avs_ctx_list) {
203         avs_ctx_list = avs->next;
204     } else {
205         AviSynthContext *prev = avs_ctx_list;
206         while (prev->next != avs)
207             prev = prev->next;
208         prev->next = avs->next;
209     }
210 
211     if (avs->clip) {
212         avs_library.avs_release_clip(avs->clip);
213         avs->clip = NULL;
214     }
215     if (avs->env) {
216         avs_library.avs_delete_script_environment(avs->env);
217         avs->env = NULL;
218     }
219 }
220 
avisynth_atexit_handler(void)221 static av_cold void avisynth_atexit_handler(void)
222 {
223     AviSynthContext *avs = avs_ctx_list;
224 
225     while (avs) {
226         AviSynthContext *next = avs->next;
227         avisynth_context_destroy(avs);
228         avs = next;
229     }
230     dlclose(avs_library.library);
231 
232     avs_atexit_called = 1;
233 }
234 
235 /* Create AVStream from audio and video data. */
avisynth_create_stream_video(AVFormatContext * s,AVStream * st)236 static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
237 {
238     AviSynthContext *avs = s->priv_data;
239     int planar = 0; // 0: packed, 1: YUV, 2: Y8, 3: Planar RGB, 4: YUVA, 5: Planar RGBA
240 
241     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
242     st->codecpar->codec_id   = AV_CODEC_ID_RAWVIDEO;
243     st->codecpar->width      = avs->vi->width;
244     st->codecpar->height     = avs->vi->height;
245 
246     st->avg_frame_rate    = (AVRational) { avs->vi->fps_numerator,
247                                            avs->vi->fps_denominator };
248     st->start_time        = 0;
249     st->duration          = avs->vi->num_frames;
250     st->nb_frames         = avs->vi->num_frames;
251     avpriv_set_pts_info(st, 32, avs->vi->fps_denominator, avs->vi->fps_numerator);
252 
253     av_log(s, AV_LOG_TRACE, "avs_is_field_based: %d\n", avs_is_field_based(avs->vi));
254     av_log(s, AV_LOG_TRACE, "avs_is_parity_known: %d\n", avs_is_parity_known(avs->vi));
255 
256     /* The following typically only works when assumetff (-bff) and
257      * assumefieldbased is used in-script. Additional
258      * logic using GetParity() could deliver more accurate results
259      * but also decodes a frame which we want to avoid. */
260     st->codecpar->field_order = AV_FIELD_UNKNOWN;
261     if (avs_is_field_based(avs->vi)) {
262         if (avs_is_tff(avs->vi)) {
263             st->codecpar->field_order = AV_FIELD_TT;
264         }
265         else if (avs_is_bff(avs->vi)) {
266             st->codecpar->field_order = AV_FIELD_BB;
267         }
268     }
269 
270     switch (avs->vi->pixel_type) {
271     /* 10~16-bit YUV pix_fmts (AviSynth+) */
272     case AVS_CS_YUV444P10:
273         st->codecpar->format = AV_PIX_FMT_YUV444P10;
274         planar               = 1;
275         break;
276     case AVS_CS_YUV422P10:
277         st->codecpar->format = AV_PIX_FMT_YUV422P10;
278         planar               = 1;
279         break;
280     case AVS_CS_YUV420P10:
281         st->codecpar->format = AV_PIX_FMT_YUV420P10;
282         planar               = 1;
283         break;
284     case AVS_CS_YUV444P12:
285         st->codecpar->format = AV_PIX_FMT_YUV444P12;
286         planar               = 1;
287         break;
288     case AVS_CS_YUV422P12:
289         st->codecpar->format = AV_PIX_FMT_YUV422P12;
290         planar               = 1;
291         break;
292     case AVS_CS_YUV420P12:
293         st->codecpar->format = AV_PIX_FMT_YUV420P12;
294         planar               = 1;
295         break;
296     case AVS_CS_YUV444P14:
297         st->codecpar->format = AV_PIX_FMT_YUV444P14;
298         planar               = 1;
299         break;
300     case AVS_CS_YUV422P14:
301         st->codecpar->format = AV_PIX_FMT_YUV422P14;
302         planar               = 1;
303         break;
304     case AVS_CS_YUV420P14:
305         st->codecpar->format = AV_PIX_FMT_YUV420P14;
306         planar               = 1;
307         break;
308     case AVS_CS_YUV444P16:
309         st->codecpar->format = AV_PIX_FMT_YUV444P16;
310         planar               = 1;
311         break;
312     case AVS_CS_YUV422P16:
313         st->codecpar->format = AV_PIX_FMT_YUV422P16;
314         planar               = 1;
315         break;
316     case AVS_CS_YUV420P16:
317         st->codecpar->format = AV_PIX_FMT_YUV420P16;
318         planar               = 1;
319         break;
320     /* 8~16-bit YUV pix_fmts with Alpha (AviSynth+) */
321     case AVS_CS_YUVA444:
322         st->codecpar->format = AV_PIX_FMT_YUVA444P;
323         planar               = 4;
324         break;
325     case AVS_CS_YUVA422:
326         st->codecpar->format = AV_PIX_FMT_YUVA422P;
327         planar               = 4;
328         break;
329     case AVS_CS_YUVA420:
330         st->codecpar->format = AV_PIX_FMT_YUVA420P;
331         planar               = 4;
332         break;
333     case AVS_CS_YUVA444P10:
334         st->codecpar->format = AV_PIX_FMT_YUVA444P10;
335         planar               = 4;
336         break;
337     case AVS_CS_YUVA422P10:
338         st->codecpar->format = AV_PIX_FMT_YUVA422P10;
339         planar               = 4;
340         break;
341     case AVS_CS_YUVA420P10:
342         st->codecpar->format = AV_PIX_FMT_YUVA420P10;
343         planar               = 4;
344         break;
345     case AVS_CS_YUVA422P12:
346         st->codecpar->format = AV_PIX_FMT_YUVA422P12;
347         planar               = 4;
348         break;
349     case AVS_CS_YUVA444P16:
350         st->codecpar->format = AV_PIX_FMT_YUVA444P16;
351         planar               = 4;
352         break;
353     case AVS_CS_YUVA422P16:
354         st->codecpar->format = AV_PIX_FMT_YUVA422P16;
355         planar               = 4;
356         break;
357     case AVS_CS_YUVA420P16:
358         st->codecpar->format = AV_PIX_FMT_YUVA420P16;
359         planar               = 4;
360         break;
361     /* Planar RGB pix_fmts (AviSynth+) */
362     case AVS_CS_RGBP:
363         st->codecpar->format = AV_PIX_FMT_GBRP;
364         planar               = 3;
365         break;
366     case AVS_CS_RGBP10:
367         st->codecpar->format = AV_PIX_FMT_GBRP10;
368         planar               = 3;
369         break;
370     case AVS_CS_RGBP12:
371         st->codecpar->format = AV_PIX_FMT_GBRP12;
372         planar               = 3;
373         break;
374     case AVS_CS_RGBP14:
375         st->codecpar->format = AV_PIX_FMT_GBRP14;
376         planar               = 3;
377         break;
378     case AVS_CS_RGBP16:
379         st->codecpar->format = AV_PIX_FMT_GBRP16;
380         planar               = 3;
381         break;
382     /* Single precision floating point Planar RGB (AviSynth+) */
383     case AVS_CS_RGBPS:
384         st->codecpar->format = AV_PIX_FMT_GBRPF32;
385         planar               = 3;
386         break;
387     /* Planar RGB pix_fmts with Alpha (AviSynth+) */
388     case AVS_CS_RGBAP:
389         st->codecpar->format = AV_PIX_FMT_GBRAP;
390         planar               = 5;
391         break;
392     case AVS_CS_RGBAP10:
393         st->codecpar->format = AV_PIX_FMT_GBRAP10;
394         planar               = 5;
395         break;
396     case AVS_CS_RGBAP12:
397         st->codecpar->format = AV_PIX_FMT_GBRAP12;
398         planar               = 5;
399         break;
400     case AVS_CS_RGBAP16:
401         st->codecpar->format = AV_PIX_FMT_GBRAP16;
402         planar               = 5;
403         break;
404     /* Single precision floating point Planar RGB with Alpha (AviSynth+) */
405     case AVS_CS_RGBAPS:
406         st->codecpar->format = AV_PIX_FMT_GBRAPF32;
407         planar               = 5;
408         break;
409     /* 10~16-bit gray pix_fmts (AviSynth+) */
410     case AVS_CS_Y10:
411         st->codecpar->format = AV_PIX_FMT_GRAY10;
412         planar               = 2;
413         break;
414     case AVS_CS_Y12:
415         st->codecpar->format = AV_PIX_FMT_GRAY12;
416         planar               = 2;
417         break;
418     case AVS_CS_Y14:
419         st->codecpar->format = AV_PIX_FMT_GRAY14;
420         planar               = 2;
421         break;
422     case AVS_CS_Y16:
423         st->codecpar->format = AV_PIX_FMT_GRAY16;
424         planar               = 2;
425         break;
426     /* Single precision floating point gray (AviSynth+) */
427     case AVS_CS_Y32:
428         st->codecpar->format = AV_PIX_FMT_GRAYF32;
429         planar               = 2;
430         break;
431     /* pix_fmts added in AviSynth 2.6 */
432     case AVS_CS_YV24:
433         st->codecpar->format = AV_PIX_FMT_YUV444P;
434         planar               = 1;
435         break;
436     case AVS_CS_YV16:
437         st->codecpar->format = AV_PIX_FMT_YUV422P;
438         planar               = 1;
439         break;
440     case AVS_CS_YV411:
441         st->codecpar->format = AV_PIX_FMT_YUV411P;
442         planar               = 1;
443         break;
444     case AVS_CS_Y8:
445         st->codecpar->format = AV_PIX_FMT_GRAY8;
446         planar               = 2;
447         break;
448     /* 16-bit packed RGB pix_fmts (AviSynth+) */
449     case AVS_CS_BGR48:
450         st->codecpar->format = AV_PIX_FMT_BGR48;
451         break;
452     case AVS_CS_BGR64:
453         st->codecpar->format = AV_PIX_FMT_BGRA64;
454         break;
455     /* AviSynth 2.5 pix_fmts */
456     case AVS_CS_BGR24:
457         st->codecpar->format = AV_PIX_FMT_BGR24;
458         break;
459     case AVS_CS_BGR32:
460         st->codecpar->format = AV_PIX_FMT_RGB32;
461         break;
462     case AVS_CS_YUY2:
463         st->codecpar->format = AV_PIX_FMT_YUYV422;
464         break;
465     case AVS_CS_YV12:
466         st->codecpar->format = AV_PIX_FMT_YUV420P;
467         planar               = 1;
468         break;
469     case AVS_CS_I420: // Is this even used anywhere?
470         st->codecpar->format = AV_PIX_FMT_YUV420P;
471         planar               = 1;
472         break;
473     default:
474         av_log(s, AV_LOG_ERROR,
475                "unknown AviSynth colorspace %d\n", avs->vi->pixel_type);
476         avs->error = 1;
477         return AVERROR_UNKNOWN;
478     }
479 
480     switch (planar) {
481     case 5: // Planar RGB + Alpha
482         avs->n_planes = 4;
483         avs->planes   = avs_planes_rgba;
484         break;
485     case 4: // YUV + Alpha
486         avs->n_planes = 4;
487         avs->planes   = avs_planes_yuva;
488         break;
489     case 3: // Planar RGB
490         avs->n_planes = 3;
491         avs->planes   = avs_planes_rgb;
492         break;
493     case 2: // Y8
494         avs->n_planes = 1;
495         avs->planes   = avs_planes_grey;
496         break;
497     case 1: // YUV
498         avs->n_planes = 3;
499         avs->planes   = avs_planes_yuv;
500         break;
501     default:
502         avs->n_planes = 1;
503         avs->planes   = avs_planes_packed;
504     }
505     return 0;
506 }
507 
avisynth_create_stream_audio(AVFormatContext * s,AVStream * st)508 static int avisynth_create_stream_audio(AVFormatContext *s, AVStream *st)
509 {
510     AviSynthContext *avs = s->priv_data;
511 
512     st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
513     st->codecpar->sample_rate = avs->vi->audio_samples_per_second;
514     st->codecpar->channels    = avs->vi->nchannels;
515     st->duration              = avs->vi->num_audio_samples;
516     avpriv_set_pts_info(st, 64, 1, avs->vi->audio_samples_per_second);
517 
518     switch (avs->vi->sample_type) {
519     case AVS_SAMPLE_INT8:
520         st->codecpar->codec_id = AV_CODEC_ID_PCM_U8;
521         break;
522     case AVS_SAMPLE_INT16:
523         st->codecpar->codec_id = PCM(S16);
524         break;
525     case AVS_SAMPLE_INT24:
526         st->codecpar->codec_id = PCM(S24);
527         break;
528     case AVS_SAMPLE_INT32:
529         st->codecpar->codec_id = PCM(S32);
530         break;
531     case AVS_SAMPLE_FLOAT:
532         st->codecpar->codec_id = PCM(F32);
533         break;
534     default:
535         av_log(s, AV_LOG_ERROR,
536                "unknown AviSynth sample type %d\n", avs->vi->sample_type);
537         avs->error = 1;
538         return AVERROR_UNKNOWN;
539     }
540     return 0;
541 }
542 
avisynth_create_stream(AVFormatContext * s)543 static int avisynth_create_stream(AVFormatContext *s)
544 {
545     AviSynthContext *avs = s->priv_data;
546     AVStream *st;
547     int ret;
548     int id = 0;
549 
550     if (avs_has_video(avs->vi)) {
551         st = avformat_new_stream(s, NULL);
552         if (!st)
553             return AVERROR_UNKNOWN;
554         st->id = id++;
555         if (ret = avisynth_create_stream_video(s, st))
556             return ret;
557     }
558     if (avs_has_audio(avs->vi)) {
559         st = avformat_new_stream(s, NULL);
560         if (!st)
561             return AVERROR_UNKNOWN;
562         st->id = id++;
563         if (ret = avisynth_create_stream_audio(s, st))
564             return ret;
565     }
566     return 0;
567 }
568 
avisynth_open_file(AVFormatContext * s)569 static int avisynth_open_file(AVFormatContext *s)
570 {
571     AviSynthContext *avs = s->priv_data;
572     AVS_Value arg, val;
573     int ret;
574 #ifdef _WIN32
575     char filename_ansi[MAX_PATH * 4];
576     wchar_t filename_wc[MAX_PATH * 4];
577 #endif
578 
579     if (ret = avisynth_context_create(s))
580         return ret;
581 
582 #ifdef _WIN32
583     /* Convert UTF-8 to ANSI code page */
584     MultiByteToWideChar(CP_UTF8, 0, s->url, -1, filename_wc, MAX_PATH * 4);
585     WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wc, -1, filename_ansi,
586                         MAX_PATH * 4, NULL, NULL);
587     arg = avs_new_value_string(filename_ansi);
588 #else
589     arg = avs_new_value_string(s->url);
590 #endif
591     val = avs_library.avs_invoke(avs->env, "Import", arg, 0);
592     if (avs_is_error(val)) {
593         av_log(s, AV_LOG_ERROR, "%s\n", avs_as_error(val));
594         ret = AVERROR_UNKNOWN;
595         goto fail;
596     }
597     if (!avs_is_clip(val)) {
598         av_log(s, AV_LOG_ERROR, "AviSynth script did not return a clip\n");
599         ret = AVERROR_UNKNOWN;
600         goto fail;
601     }
602 
603     avs->clip = avs_library.avs_take_clip(val, avs->env);
604     avs->vi   = avs_library.avs_get_video_info(avs->clip);
605 
606     /* On Windows, FFmpeg supports AviSynth interface version 6 or higher.
607      * This includes AviSynth 2.6 RC1 or higher, and AviSynth+ r1718 or higher,
608      * and excludes 2.5 and the 2.6 alphas. */
609 
610     if (avs_library.avs_get_version(avs->clip) < 6) {
611         av_log(s, AV_LOG_ERROR,
612                "AviSynth version is too old. Please upgrade to either AviSynth 2.6 >= RC1 or AviSynth+ >= r1718.\n");
613         ret = AVERROR_UNKNOWN;
614         goto fail;
615     }
616 
617     /* Release the AVS_Value as it will go out of scope. */
618     avs_library.avs_release_value(val);
619 
620     if (ret = avisynth_create_stream(s))
621         goto fail;
622 
623     return 0;
624 
625 fail:
626     avisynth_context_destroy(avs);
627     return ret;
628 }
629 
avisynth_next_stream(AVFormatContext * s,AVStream ** st,AVPacket * pkt,int * discard)630 static void avisynth_next_stream(AVFormatContext *s, AVStream **st,
631                                  AVPacket *pkt, int *discard)
632 {
633     AviSynthContext *avs = s->priv_data;
634 
635     avs->curr_stream++;
636     avs->curr_stream %= s->nb_streams;
637 
638     *st = s->streams[avs->curr_stream];
639     if ((*st)->discard == AVDISCARD_ALL)
640         *discard = 1;
641     else
642         *discard = 0;
643 
644     return;
645 }
646 
647 /* Copy AviSynth clip data into an AVPacket. */
avisynth_read_packet_video(AVFormatContext * s,AVPacket * pkt,int discard)648 static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt,
649                                       int discard)
650 {
651     AviSynthContext *avs = s->priv_data;
652     AVS_VideoFrame *frame;
653     unsigned char *dst_p;
654     const unsigned char *src_p;
655     int n, i, plane, rowsize, planeheight, pitch, bits, ret;
656     const char *error;
657 
658     if (avs->curr_frame >= avs->vi->num_frames)
659         return AVERROR_EOF;
660 
661     /* This must happen even if the stream is discarded to prevent desync. */
662     n = avs->curr_frame++;
663     if (discard)
664         return 0;
665 
666     bits = avs_library.avs_bits_per_pixel(avs->vi);
667 
668     /* Without the cast to int64_t, calculation overflows at about 9k x 9k
669      * resolution. */
670     pkt->size = (((int64_t)avs->vi->width *
671                   (int64_t)avs->vi->height) * bits) / 8;
672     if (!pkt->size)
673         return AVERROR_UNKNOWN;
674 
675     if ((ret = av_new_packet(pkt, pkt->size)) < 0)
676         return ret;
677 
678     pkt->pts      = n;
679     pkt->dts      = n;
680     pkt->duration = 1;
681     pkt->stream_index = avs->curr_stream;
682 
683     frame = avs_library.avs_get_frame(avs->clip, n);
684     error = avs_library.avs_clip_get_error(avs->clip);
685     if (error) {
686         av_log(s, AV_LOG_ERROR, "%s\n", error);
687         avs->error = 1;
688         av_packet_unref(pkt);
689         return AVERROR_UNKNOWN;
690     }
691 
692     dst_p = pkt->data;
693     for (i = 0; i < avs->n_planes; i++) {
694         plane = avs->planes[i];
695         src_p = avs_library.avs_get_read_ptr_p(frame, plane);
696         pitch = avs_library.avs_get_pitch_p(frame, plane);
697 
698         rowsize     = avs_library.avs_get_row_size_p(frame, plane);
699         planeheight = avs_library.avs_get_height_p(frame, plane);
700 
701         /* Flip RGB video. */
702         if (avs_library.avs_is_color_space(avs->vi, AVS_CS_BGR)   ||
703             avs_library.avs_is_color_space(avs->vi, AVS_CS_BGR48) ||
704             avs_library.avs_is_color_space(avs->vi, AVS_CS_BGR64)) {
705             src_p = src_p + (planeheight - 1) * pitch;
706             pitch = -pitch;
707         }
708 
709         avs_library.avs_bit_blt(avs->env, dst_p, rowsize, src_p, pitch,
710                                  rowsize, planeheight);
711         dst_p += rowsize * planeheight;
712     }
713 
714     avs_library.avs_release_video_frame(frame);
715     return 0;
716 }
717 
avisynth_read_packet_audio(AVFormatContext * s,AVPacket * pkt,int discard)718 static int avisynth_read_packet_audio(AVFormatContext *s, AVPacket *pkt,
719                                       int discard)
720 {
721     AviSynthContext *avs = s->priv_data;
722     AVRational fps, samplerate;
723     int samples, ret;
724     int64_t n;
725     const char *error;
726 
727     if (avs->curr_sample >= avs->vi->num_audio_samples)
728         return AVERROR_EOF;
729 
730     fps.num        = avs->vi->fps_numerator;
731     fps.den        = avs->vi->fps_denominator;
732     samplerate.num = avs->vi->audio_samples_per_second;
733     samplerate.den = 1;
734 
735     if (avs_has_video(avs->vi)) {
736         if (avs->curr_frame < avs->vi->num_frames)
737             samples = av_rescale_q(avs->curr_frame, samplerate, fps) -
738                       avs->curr_sample;
739         else
740             samples = av_rescale_q(1, samplerate, fps);
741     } else {
742         samples = 1000;
743     }
744 
745     /* After seeking, audio may catch up with video. */
746     if (samples <= 0) {
747         pkt->size = 0;
748         pkt->data = NULL;
749         return 0;
750     }
751 
752     if (avs->curr_sample + samples > avs->vi->num_audio_samples)
753         samples = avs->vi->num_audio_samples - avs->curr_sample;
754 
755     /* This must happen even if the stream is discarded to prevent desync. */
756     n                 = avs->curr_sample;
757     avs->curr_sample += samples;
758     if (discard)
759         return 0;
760 
761     pkt->size = avs_bytes_per_channel_sample(avs->vi) *
762                 samples * avs->vi->nchannels;
763     if (!pkt->size)
764         return AVERROR_UNKNOWN;
765 
766     if ((ret = av_new_packet(pkt, pkt->size)) < 0)
767         return ret;
768 
769     pkt->pts      = n;
770     pkt->dts      = n;
771     pkt->duration = samples;
772     pkt->stream_index = avs->curr_stream;
773 
774     avs_library.avs_get_audio(avs->clip, pkt->data, n, samples);
775     error = avs_library.avs_clip_get_error(avs->clip);
776     if (error) {
777         av_log(s, AV_LOG_ERROR, "%s\n", error);
778         avs->error = 1;
779         av_packet_unref(pkt);
780         return AVERROR_UNKNOWN;
781     }
782     return 0;
783 }
784 
avisynth_read_header(AVFormatContext * s)785 static av_cold int avisynth_read_header(AVFormatContext *s)
786 {
787     int ret;
788 
789     // Calling library must implement a lock for thread-safe opens.
790     if (ret = ff_lock_avformat())
791         return ret;
792 
793     if (ret = avisynth_open_file(s)) {
794         ff_unlock_avformat();
795         return ret;
796     }
797 
798     ff_unlock_avformat();
799     return 0;
800 }
801 
avisynth_read_packet(AVFormatContext * s,AVPacket * pkt)802 static int avisynth_read_packet(AVFormatContext *s, AVPacket *pkt)
803 {
804     AviSynthContext *avs = s->priv_data;
805     AVStream *st;
806     int discard = 0;
807     int ret;
808 
809     if (avs->error)
810         return AVERROR_UNKNOWN;
811 
812     /* If either stream reaches EOF, try to read the other one before
813      * giving up. */
814     avisynth_next_stream(s, &st, pkt, &discard);
815     if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
816         ret = avisynth_read_packet_video(s, pkt, discard);
817         if (ret == AVERROR_EOF && avs_has_audio(avs->vi)) {
818             avisynth_next_stream(s, &st, pkt, &discard);
819             return avisynth_read_packet_audio(s, pkt, discard);
820         }
821     } else {
822         ret = avisynth_read_packet_audio(s, pkt, discard);
823         if (ret == AVERROR_EOF && avs_has_video(avs->vi)) {
824             avisynth_next_stream(s, &st, pkt, &discard);
825             return avisynth_read_packet_video(s, pkt, discard);
826         }
827     }
828 
829     return ret;
830 }
831 
avisynth_read_close(AVFormatContext * s)832 static av_cold int avisynth_read_close(AVFormatContext *s)
833 {
834     if (ff_lock_avformat())
835         return AVERROR_UNKNOWN;
836 
837     avisynth_context_destroy(s->priv_data);
838     ff_unlock_avformat();
839     return 0;
840 }
841 
avisynth_read_seek(AVFormatContext * s,int stream_index,int64_t timestamp,int flags)842 static int avisynth_read_seek(AVFormatContext *s, int stream_index,
843                               int64_t timestamp, int flags)
844 {
845     AviSynthContext *avs = s->priv_data;
846     AVStream *st;
847     AVRational fps, samplerate;
848 
849     if (avs->error)
850         return AVERROR_UNKNOWN;
851 
852     fps        = (AVRational) { avs->vi->fps_numerator,
853                                 avs->vi->fps_denominator };
854     samplerate = (AVRational) { avs->vi->audio_samples_per_second, 1 };
855 
856     st = s->streams[stream_index];
857     if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
858         /* AviSynth frame counts are signed int. */
859         if ((timestamp >= avs->vi->num_frames) ||
860             (timestamp > INT_MAX)              ||
861             (timestamp < 0))
862             return AVERROR_EOF;
863         avs->curr_frame = timestamp;
864         if (avs_has_audio(avs->vi))
865             avs->curr_sample = av_rescale_q(timestamp, samplerate, fps);
866     } else {
867         if ((timestamp >= avs->vi->num_audio_samples) || (timestamp < 0))
868             return AVERROR_EOF;
869         /* Force frame granularity for seeking. */
870         if (avs_has_video(avs->vi)) {
871             avs->curr_frame  = av_rescale_q(timestamp, fps, samplerate);
872             avs->curr_sample = av_rescale_q(avs->curr_frame, samplerate, fps);
873         } else {
874             avs->curr_sample = timestamp;
875         }
876     }
877 
878     return 0;
879 }
880 
881 AVInputFormat ff_avisynth_demuxer = {
882     .name           = "avisynth",
883     .long_name      = NULL_IF_CONFIG_SMALL("AviSynth script"),
884     .priv_data_size = sizeof(AviSynthContext),
885     .read_header    = avisynth_read_header,
886     .read_packet    = avisynth_read_packet,
887     .read_close     = avisynth_read_close,
888     .read_seek      = avisynth_read_seek,
889     .extensions     = "avs",
890 };
891