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