3 * Copyright (c) 2012 AvxSynth Team
5 * This file is part of FFmpeg
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.
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.
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
22 #include "libavutil/attributes.h"
23 #include "libavutil/internal.h"
25 #include "libavcodec/internal.h"
31 /* Enable function pointer definitions for runtime loading. */
32 #define AVSC_NO_DECLSPEC
34 /* Platform-specific directives. */
36 #include "compat/w32dlfcn.h"
38 #define AVISYNTH_LIB "avisynth"
41 #define AVISYNTH_NAME "libavisynth"
42 #define AVISYNTH_LIB AVISYNTH_NAME SLIBSUF
45 #include <avisynth/avisynth_c.h>
47 typedef struct AviSynthLibrary
{
49 #define AVSC_DECLARE_FUNC(name) name ## _func name
50 AVSC_DECLARE_FUNC(avs_bit_blt
);
51 AVSC_DECLARE_FUNC(avs_clip_get_error
);
52 AVSC_DECLARE_FUNC(avs_create_script_environment
);
53 AVSC_DECLARE_FUNC(avs_delete_script_environment
);
54 AVSC_DECLARE_FUNC(avs_get_audio
);
55 AVSC_DECLARE_FUNC(avs_get_error
);
56 AVSC_DECLARE_FUNC(avs_get_frame
);
57 AVSC_DECLARE_FUNC(avs_get_version
);
58 AVSC_DECLARE_FUNC(avs_get_video_info
);
59 AVSC_DECLARE_FUNC(avs_invoke
);
60 AVSC_DECLARE_FUNC(avs_release_clip
);
61 AVSC_DECLARE_FUNC(avs_release_value
);
62 AVSC_DECLARE_FUNC(avs_release_video_frame
);
63 AVSC_DECLARE_FUNC(avs_take_clip
);
64 AVSC_DECLARE_FUNC(avs_bits_per_pixel
);
65 AVSC_DECLARE_FUNC(avs_get_height_p
);
66 AVSC_DECLARE_FUNC(avs_get_pitch_p
);
67 AVSC_DECLARE_FUNC(avs_get_read_ptr_p
);
68 AVSC_DECLARE_FUNC(avs_get_row_size_p
);
69 AVSC_DECLARE_FUNC(avs_is_planar_rgb
);
70 AVSC_DECLARE_FUNC(avs_is_planar_rgba
);
71 #undef AVSC_DECLARE_FUNC
74 typedef struct AviSynthContext
{
75 AVS_ScriptEnvironment
*env
;
77 const AVS_VideoInfo
*vi
;
79 /* avisynth_read_packet_video() iterates over this. */
89 /* Linked list pointers. */
90 struct AviSynthContext
*next
;
93 static const int avs_planes_packed
[1] = { 0 };
94 static const int avs_planes_grey
[1] = { AVS_PLANAR_Y
};
95 static const int avs_planes_yuv
[3] = { AVS_PLANAR_Y
, AVS_PLANAR_U
,
97 static const int avs_planes_rgb
[3] = { AVS_PLANAR_G
, AVS_PLANAR_B
,
99 static const int avs_planes_yuva
[4] = { AVS_PLANAR_Y
, AVS_PLANAR_U
,
100 AVS_PLANAR_V
, AVS_PLANAR_A
};
101 static const int avs_planes_rgba
[4] = { AVS_PLANAR_G
, AVS_PLANAR_B
,
102 AVS_PLANAR_R
, AVS_PLANAR_A
};
104 /* A conflict between C++ global objects, atexit, and dynamic loading requires
105 * us to register our own atexit handler to prevent double freeing. */
106 static AviSynthLibrary avs_library
;
107 static int avs_atexit_called
= 0;
109 /* Linked list of AviSynthContexts. An atexit handler destroys this list. */
110 static AviSynthContext
*avs_ctx_list
= NULL
;
112 static av_cold
void avisynth_atexit_handler(void);
114 static av_cold
int avisynth_load_library(void)
116 avs_library
.library
= dlopen(AVISYNTH_LIB
, RTLD_NOW
| RTLD_LOCAL
);
117 if (!avs_library
.library
)
118 return AVERROR_UNKNOWN
;
120 #define LOAD_AVS_FUNC(name, continue_on_fail) \
121 avs_library.name = (name ## _func) \
122 dlsym(avs_library.library, #name); \
123 if (!continue_on_fail && !avs_library.name) \
126 LOAD_AVS_FUNC(avs_bit_blt
, 0);
127 LOAD_AVS_FUNC(avs_clip_get_error
, 0);
128 LOAD_AVS_FUNC(avs_create_script_environment
, 0);
129 LOAD_AVS_FUNC(avs_delete_script_environment
, 0);
130 LOAD_AVS_FUNC(avs_get_audio
, 0);
131 LOAD_AVS_FUNC(avs_get_error
, 1); // New to AviSynth 2.6
132 LOAD_AVS_FUNC(avs_get_frame
, 0);
133 LOAD_AVS_FUNC(avs_get_version
, 0);
134 LOAD_AVS_FUNC(avs_get_video_info
, 0);
135 LOAD_AVS_FUNC(avs_invoke
, 0);
136 LOAD_AVS_FUNC(avs_release_clip
, 0);
137 LOAD_AVS_FUNC(avs_release_value
, 0);
138 LOAD_AVS_FUNC(avs_release_video_frame
, 0);
139 LOAD_AVS_FUNC(avs_take_clip
, 0);
140 LOAD_AVS_FUNC(avs_bits_per_pixel
, 1);
141 LOAD_AVS_FUNC(avs_get_height_p
, 1);
142 LOAD_AVS_FUNC(avs_get_pitch_p
, 1);
143 LOAD_AVS_FUNC(avs_get_read_ptr_p
, 1);
144 LOAD_AVS_FUNC(avs_get_row_size_p
, 1);
145 LOAD_AVS_FUNC(avs_is_planar_rgb
, 1);
146 LOAD_AVS_FUNC(avs_is_planar_rgba
, 1);
149 atexit(avisynth_atexit_handler
);
153 dlclose(avs_library
.library
);
154 return AVERROR_UNKNOWN
;
157 /* Note that avisynth_context_create and avisynth_context_destroy
158 * do not allocate or free the actual context! That is taken care of
160 static av_cold
int avisynth_context_create(AVFormatContext
*s
)
162 AviSynthContext
*avs
= s
->priv_data
;
165 if (!avs_library
.library
)
166 if (ret
= avisynth_load_library())
169 avs
->env
= avs_library
.avs_create_script_environment(3);
170 if (avs_library
.avs_get_error
) {
171 const char *error
= avs_library
.avs_get_error(avs
->env
);
173 av_log(s
, AV_LOG_ERROR
, "%s\n", error
);
174 return AVERROR_UNKNOWN
;
181 avs
->next
= avs_ctx_list
;
188 static av_cold
void avisynth_context_destroy(AviSynthContext
*avs
)
190 if (avs_atexit_called
)
193 if (avs
== avs_ctx_list
) {
194 avs_ctx_list
= avs
->next
;
196 AviSynthContext
*prev
= avs_ctx_list
;
197 while (prev
->next
!= avs
)
199 prev
->next
= avs
->next
;
203 avs_library
.avs_release_clip(avs
->clip
);
207 avs_library
.avs_delete_script_environment(avs
->env
);
212 static av_cold
void avisynth_atexit_handler(void)
214 AviSynthContext
*avs
= avs_ctx_list
;
217 AviSynthContext
*next
= avs
->next
;
218 avisynth_context_destroy(avs
);
221 dlclose(avs_library
.library
);
223 avs_atexit_called
= 1;
226 /* Create AVStream from audio and video data. */
227 static int avisynth_create_stream_video(AVFormatContext
*s
, AVStream
*st
)
229 AviSynthContext
*avs
= s
->priv_data
;
230 int planar
= 0; // 0: packed, 1: YUV, 2: Y8, 3: Planar RGB, 4: YUVA, 5: Planar RGBA
232 st
->codecpar
->codec_type
= AVMEDIA_TYPE_VIDEO
;
233 st
->codecpar
->codec_id
= AV_CODEC_ID_RAWVIDEO
;
234 st
->codecpar
->width
= avs
->vi
->width
;
235 st
->codecpar
->height
= avs
->vi
->height
;
237 st
->avg_frame_rate
= (AVRational
) { avs
->vi
->fps_numerator
,
238 avs
->vi
->fps_denominator
};
240 st
->duration
= avs
->vi
->num_frames
;
241 st
->nb_frames
= avs
->vi
->num_frames
;
242 avpriv_set_pts_info(st
, 32, avs
->vi
->fps_denominator
, avs
->vi
->fps_numerator
);
244 switch (avs
->vi
->pixel_type
) {
245 /* 10~16-bit YUV pix_fmts (AviSynth+) */
246 case AVS_CS_YUV444P10
:
247 st
->codecpar
->format
= AV_PIX_FMT_YUV444P10
;
250 case AVS_CS_YUV422P10
:
251 st
->codecpar
->format
= AV_PIX_FMT_YUV422P10
;
254 case AVS_CS_YUV420P10
:
255 st
->codecpar
->format
= AV_PIX_FMT_YUV420P10
;
258 case AVS_CS_YUV444P12
:
259 st
->codecpar
->format
= AV_PIX_FMT_YUV444P12
;
262 case AVS_CS_YUV422P12
:
263 st
->codecpar
->format
= AV_PIX_FMT_YUV422P12
;
266 case AVS_CS_YUV420P12
:
267 st
->codecpar
->format
= AV_PIX_FMT_YUV420P12
;
270 case AVS_CS_YUV444P14
:
271 st
->codecpar
->format
= AV_PIX_FMT_YUV444P14
;
274 case AVS_CS_YUV422P14
:
275 st
->codecpar
->format
= AV_PIX_FMT_YUV422P14
;
278 case AVS_CS_YUV420P14
:
279 st
->codecpar
->format
= AV_PIX_FMT_YUV420P14
;
282 case AVS_CS_YUV444P16
:
283 st
->codecpar
->format
= AV_PIX_FMT_YUV444P16
;
286 case AVS_CS_YUV422P16
:
287 st
->codecpar
->format
= AV_PIX_FMT_YUV422P16
;
290 case AVS_CS_YUV420P16
:
291 st
->codecpar
->format
= AV_PIX_FMT_YUV420P16
;
294 /* 8~16-bit YUV pix_fmts with Alpha (AviSynth+) */
296 st
->codecpar
->format
= AV_PIX_FMT_YUVA444P
;
300 st
->codecpar
->format
= AV_PIX_FMT_YUVA422P
;
304 st
->codecpar
->format
= AV_PIX_FMT_YUVA420P
;
307 case AVS_CS_YUVA444P10
:
308 st
->codecpar
->format
= AV_PIX_FMT_YUVA444P10
;
311 case AVS_CS_YUVA422P10
:
312 st
->codecpar
->format
= AV_PIX_FMT_YUVA422P10
;
315 case AVS_CS_YUVA420P10
:
316 st
->codecpar
->format
= AV_PIX_FMT_YUVA420P10
;
319 case AVS_CS_YUVA422P12
:
320 st
->codecpar
->format
= AV_PIX_FMT_YUVA422P12
;
323 case AVS_CS_YUVA444P16
:
324 st
->codecpar
->format
= AV_PIX_FMT_YUVA444P16
;
327 case AVS_CS_YUVA422P16
:
328 st
->codecpar
->format
= AV_PIX_FMT_YUVA422P16
;
331 case AVS_CS_YUVA420P16
:
332 st
->codecpar
->format
= AV_PIX_FMT_YUVA420P16
;
335 /* Planar RGB pix_fmts (AviSynth+) */
337 st
->codecpar
->format
= AV_PIX_FMT_GBRP
;
341 st
->codecpar
->format
= AV_PIX_FMT_GBRP10
;
345 st
->codecpar
->format
= AV_PIX_FMT_GBRP12
;
349 st
->codecpar
->format
= AV_PIX_FMT_GBRP14
;
353 st
->codecpar
->format
= AV_PIX_FMT_GBRP16
;
356 /* Single precision floating point Planar RGB (AviSynth+) */
358 st
->codecpar
->format
= AV_PIX_FMT_GBRPF32
;
361 /* Planar RGB pix_fmts with Alpha (AviSynth+) */
363 st
->codecpar
->format
= AV_PIX_FMT_GBRAP
;
367 st
->codecpar
->format
= AV_PIX_FMT_GBRAP10
;
371 st
->codecpar
->format
= AV_PIX_FMT_GBRAP12
;
375 st
->codecpar
->format
= AV_PIX_FMT_GBRAP16
;
378 /* Single precision floating point Planar RGB with Alpha (AviSynth+) */
380 st
->codecpar
->format
= AV_PIX_FMT_GBRAPF32
;
383 /* 10~16-bit gray pix_fmts (AviSynth+) */
385 st
->codecpar
->format
= AV_PIX_FMT_GRAY10
;
389 st
->codecpar
->format
= AV_PIX_FMT_GRAY12
;
393 st
->codecpar
->format
= AV_PIX_FMT_GRAY14
;
397 st
->codecpar
->format
= AV_PIX_FMT_GRAY16
;
400 /* Single precision floating point gray (AviSynth+) */
402 st
->codecpar
->format
= AV_PIX_FMT_GRAYF32
;
405 /* pix_fmts added in AviSynth 2.6 */
407 st
->codecpar
->format
= AV_PIX_FMT_YUV444P
;
411 st
->codecpar
->format
= AV_PIX_FMT_YUV422P
;
415 st
->codecpar
->format
= AV_PIX_FMT_YUV411P
;
419 st
->codecpar
->format
= AV_PIX_FMT_GRAY8
;
422 /* 16-bit packed RGB pix_fmts (AviSynth+) */
424 st
->codecpar
->format
= AV_PIX_FMT_BGR48
;
427 st
->codecpar
->format
= AV_PIX_FMT_BGRA64
;
429 /* AviSynth 2.5 pix_fmts */
431 st
->codecpar
->format
= AV_PIX_FMT_BGR24
;
434 st
->codecpar
->format
= AV_PIX_FMT_RGB32
;
437 st
->codecpar
->format
= AV_PIX_FMT_YUYV422
;
440 st
->codecpar
->format
= AV_PIX_FMT_YUV420P
;
443 case AVS_CS_I420
: // Is this even used anywhere?
444 st
->codecpar
->format
= AV_PIX_FMT_YUV420P
;
448 av_log(s
, AV_LOG_ERROR
,
449 "unknown AviSynth colorspace %d\n", avs
->vi
->pixel_type
);
451 return AVERROR_UNKNOWN
;
455 case 5: // Planar RGB + Alpha
457 avs
->planes
= avs_planes_rgba
;
459 case 4: // YUV + Alpha
461 avs
->planes
= avs_planes_yuva
;
463 case 3: // Planar RGB
465 avs
->planes
= avs_planes_rgb
;
469 avs
->planes
= avs_planes_grey
;
473 avs
->planes
= avs_planes_yuv
;
477 avs
->planes
= avs_planes_packed
;
482 static int avisynth_create_stream_audio(AVFormatContext
*s
, AVStream
*st
)
484 AviSynthContext
*avs
= s
->priv_data
;
486 st
->codecpar
->codec_type
= AVMEDIA_TYPE_AUDIO
;
487 st
->codecpar
->sample_rate
= avs
->vi
->audio_samples_per_second
;
488 st
->codecpar
->channels
= avs
->vi
->nchannels
;
489 st
->duration
= avs
->vi
->num_audio_samples
;
490 avpriv_set_pts_info(st
, 64, 1, avs
->vi
->audio_samples_per_second
);
492 switch (avs
->vi
->sample_type
) {
493 case AVS_SAMPLE_INT8
:
494 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_U8
;
496 case AVS_SAMPLE_INT16
:
497 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_S16LE
;
499 case AVS_SAMPLE_INT24
:
500 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_S24LE
;
502 case AVS_SAMPLE_INT32
:
503 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_S32LE
;
505 case AVS_SAMPLE_FLOAT
:
506 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_F32LE
;
509 av_log(s
, AV_LOG_ERROR
,
510 "unknown AviSynth sample type %d\n", avs
->vi
->sample_type
);
512 return AVERROR_UNKNOWN
;
517 static int avisynth_create_stream(AVFormatContext
*s
)
519 AviSynthContext
*avs
= s
->priv_data
;
524 if (avs_has_video(avs
->vi
)) {
525 st
= avformat_new_stream(s
, NULL
);
527 return AVERROR_UNKNOWN
;
529 if (ret
= avisynth_create_stream_video(s
, st
))
532 if (avs_has_audio(avs
->vi
)) {
533 st
= avformat_new_stream(s
, NULL
);
535 return AVERROR_UNKNOWN
;
537 if (ret
= avisynth_create_stream_audio(s
, st
))
543 static int avisynth_open_file(AVFormatContext
*s
)
545 AviSynthContext
*avs
= s
->priv_data
;
549 char filename_ansi
[MAX_PATH
* 4];
550 wchar_t filename_wc
[MAX_PATH
* 4];
553 if (ret
= avisynth_context_create(s
))
557 /* Convert UTF-8 to ANSI code page */
558 MultiByteToWideChar(CP_UTF8
, 0, s
->url
, -1, filename_wc
, MAX_PATH
* 4);
559 WideCharToMultiByte(CP_THREAD_ACP
, 0, filename_wc
, -1, filename_ansi
,
560 MAX_PATH
* 4, NULL
, NULL
);
561 arg
= avs_new_value_string(filename_ansi
);
563 arg
= avs_new_value_string(s
->url
);
565 val
= avs_library
.avs_invoke(avs
->env
, "Import", arg
, 0);
566 if (avs_is_error(val
)) {
567 av_log(s
, AV_LOG_ERROR
, "%s\n", avs_as_error(val
));
568 ret
= AVERROR_UNKNOWN
;
571 if (!avs_is_clip(val
)) {
572 av_log(s
, AV_LOG_ERROR
, "AviSynth script did not return a clip\n");
573 ret
= AVERROR_UNKNOWN
;
577 avs
->clip
= avs_library
.avs_take_clip(val
, avs
->env
);
578 avs
->vi
= avs_library
.avs_get_video_info(avs
->clip
);
580 /* On Windows, FFmpeg supports AviSynth interface version 6 or higher.
581 * This includes AviSynth 2.6 RC1 or higher, and AviSynth+ r1718 or higher,
582 * and excludes 2.5 and the 2.6 alphas. */
584 if (avs_library
.avs_get_version(avs
->clip
) < 6) {
585 av_log(s
, AV_LOG_ERROR
,
586 "AviSynth version is too old. Please upgrade to either AviSynth 2.6 >= RC1 or AviSynth+ >= r1718.\n");
587 ret
= AVERROR_UNKNOWN
;
591 /* Release the AVS_Value as it will go out of scope. */
592 avs_library
.avs_release_value(val
);
594 if (ret
= avisynth_create_stream(s
))
600 avisynth_context_destroy(avs
);
604 static void avisynth_next_stream(AVFormatContext
*s
, AVStream
**st
,
605 AVPacket
*pkt
, int *discard
)
607 AviSynthContext
*avs
= s
->priv_data
;
610 avs
->curr_stream
%= s
->nb_streams
;
612 *st
= s
->streams
[avs
->curr_stream
];
613 if ((*st
)->discard
== AVDISCARD_ALL
)
621 /* Copy AviSynth clip data into an AVPacket. */
622 static int avisynth_read_packet_video(AVFormatContext
*s
, AVPacket
*pkt
,
625 AviSynthContext
*avs
= s
->priv_data
;
626 AVS_VideoFrame
*frame
;
627 unsigned char *dst_p
;
628 const unsigned char *src_p
;
629 int n
, i
, plane
, rowsize
, planeheight
, pitch
, bits
, ret
;
631 int avsplus av_unused
;
633 if (avs
->curr_frame
>= avs
->vi
->num_frames
)
636 /* This must happen even if the stream is discarded to prevent desync. */
637 n
= avs
->curr_frame
++;
642 /* Detect whether we're using AviSynth 2.6 or AviSynth+ by
643 * looking for whether avs_is_planar_rgb exists. */
644 if (GetProcAddress(avs_library
.library
, "avs_is_planar_rgb") == NULL
)
649 /* AviSynth+ is now the only variant of AviSynth we support
650 * on Linux and macOS. */
654 bits
= avs_library
.avs_bits_per_pixel(avs
->vi
);
656 /* Without the cast to int64_t, calculation overflows at about 9k x 9k
658 pkt
->size
= (((int64_t)avs
->vi
->width
*
659 (int64_t)avs
->vi
->height
) * bits
) / 8;
661 return AVERROR_UNKNOWN
;
663 if ((ret
= av_new_packet(pkt
, pkt
->size
)) < 0)
669 pkt
->stream_index
= avs
->curr_stream
;
671 frame
= avs_library
.avs_get_frame(avs
->clip
, n
);
672 error
= avs_library
.avs_clip_get_error(avs
->clip
);
674 av_log(s
, AV_LOG_ERROR
, "%s\n", error
);
676 av_packet_unref(pkt
);
677 return AVERROR_UNKNOWN
;
681 for (i
= 0; i
< avs
->n_planes
; i
++) {
682 plane
= avs
->planes
[i
];
683 src_p
= avs_library
.avs_get_read_ptr_p(frame
, plane
);
684 pitch
= avs_library
.avs_get_pitch_p(frame
, plane
);
686 rowsize
= avs_library
.avs_get_row_size_p(frame
, plane
);
687 planeheight
= avs_library
.avs_get_height_p(frame
, plane
);
689 /* Flip RGB video. */
690 if (avs_is_rgb24(avs
->vi
) || avs_is_rgb(avs
->vi
)) {
691 src_p
= src_p
+ (planeheight
- 1) * pitch
;
695 /* Flip Planar RGB video */
696 if (avsplus
&& (avs_library
.avs_is_planar_rgb(avs
->vi
) ||
697 avs_library
.avs_is_planar_rgba(avs
->vi
))) {
698 src_p
= src_p
+ (planeheight
- 1) * pitch
;
702 avs_library
.avs_bit_blt(avs
->env
, dst_p
, rowsize
, src_p
, pitch
,
703 rowsize
, planeheight
);
704 dst_p
+= rowsize
* planeheight
;
707 avs_library
.avs_release_video_frame(frame
);
711 static int avisynth_read_packet_audio(AVFormatContext
*s
, AVPacket
*pkt
,
714 AviSynthContext
*avs
= s
->priv_data
;
715 AVRational fps
, samplerate
;
720 if (avs
->curr_sample
>= avs
->vi
->num_audio_samples
)
723 fps
.num
= avs
->vi
->fps_numerator
;
724 fps
.den
= avs
->vi
->fps_denominator
;
725 samplerate
.num
= avs
->vi
->audio_samples_per_second
;
728 if (avs_has_video(avs
->vi
)) {
729 if (avs
->curr_frame
< avs
->vi
->num_frames
)
730 samples
= av_rescale_q(avs
->curr_frame
, samplerate
, fps
) -
733 samples
= av_rescale_q(1, samplerate
, fps
);
738 /* After seeking, audio may catch up with video. */
745 if (avs
->curr_sample
+ samples
> avs
->vi
->num_audio_samples
)
746 samples
= avs
->vi
->num_audio_samples
- avs
->curr_sample
;
748 /* This must happen even if the stream is discarded to prevent desync. */
749 n
= avs
->curr_sample
;
750 avs
->curr_sample
+= samples
;
754 pkt
->size
= avs_bytes_per_channel_sample(avs
->vi
) *
755 samples
* avs
->vi
->nchannels
;
757 return AVERROR_UNKNOWN
;
759 if ((ret
= av_new_packet(pkt
, pkt
->size
)) < 0)
764 pkt
->duration
= samples
;
765 pkt
->stream_index
= avs
->curr_stream
;
767 avs_library
.avs_get_audio(avs
->clip
, pkt
->data
, n
, samples
);
768 error
= avs_library
.avs_clip_get_error(avs
->clip
);
770 av_log(s
, AV_LOG_ERROR
, "%s\n", error
);
772 av_packet_unref(pkt
);
773 return AVERROR_UNKNOWN
;
778 static av_cold
int avisynth_read_header(AVFormatContext
*s
)
782 // Calling library must implement a lock for thread-safe opens.
783 if (ret
= ff_lock_avformat())
786 if (ret
= avisynth_open_file(s
)) {
787 ff_unlock_avformat();
791 ff_unlock_avformat();
795 static int avisynth_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
797 AviSynthContext
*avs
= s
->priv_data
;
803 return AVERROR_UNKNOWN
;
805 /* If either stream reaches EOF, try to read the other one before
807 avisynth_next_stream(s
, &st
, pkt
, &discard
);
808 if (st
->codecpar
->codec_type
== AVMEDIA_TYPE_VIDEO
) {
809 ret
= avisynth_read_packet_video(s
, pkt
, discard
);
810 if (ret
== AVERROR_EOF
&& avs_has_audio(avs
->vi
)) {
811 avisynth_next_stream(s
, &st
, pkt
, &discard
);
812 return avisynth_read_packet_audio(s
, pkt
, discard
);
815 ret
= avisynth_read_packet_audio(s
, pkt
, discard
);
816 if (ret
== AVERROR_EOF
&& avs_has_video(avs
->vi
)) {
817 avisynth_next_stream(s
, &st
, pkt
, &discard
);
818 return avisynth_read_packet_video(s
, pkt
, discard
);
825 static av_cold
int avisynth_read_close(AVFormatContext
*s
)
827 if (ff_lock_avformat())
828 return AVERROR_UNKNOWN
;
830 avisynth_context_destroy(s
->priv_data
);
831 ff_unlock_avformat();
835 static int avisynth_read_seek(AVFormatContext
*s
, int stream_index
,
836 int64_t timestamp
, int flags
)
838 AviSynthContext
*avs
= s
->priv_data
;
840 AVRational fps
, samplerate
;
843 return AVERROR_UNKNOWN
;
845 fps
= (AVRational
) { avs
->vi
->fps_numerator
,
846 avs
->vi
->fps_denominator
};
847 samplerate
= (AVRational
) { avs
->vi
->audio_samples_per_second
, 1 };
849 st
= s
->streams
[stream_index
];
850 if (st
->codecpar
->codec_type
== AVMEDIA_TYPE_VIDEO
) {
851 /* AviSynth frame counts are signed int. */
852 if ((timestamp
>= avs
->vi
->num_frames
) ||
853 (timestamp
> INT_MAX
) ||
856 avs
->curr_frame
= timestamp
;
857 if (avs_has_audio(avs
->vi
))
858 avs
->curr_sample
= av_rescale_q(timestamp
, samplerate
, fps
);
860 if ((timestamp
>= avs
->vi
->num_audio_samples
) || (timestamp
< 0))
862 /* Force frame granularity for seeking. */
863 if (avs_has_video(avs
->vi
)) {
864 avs
->curr_frame
= av_rescale_q(timestamp
, fps
, samplerate
);
865 avs
->curr_sample
= av_rescale_q(avs
->curr_frame
, samplerate
, fps
);
867 avs
->curr_sample
= timestamp
;
874 AVInputFormat ff_avisynth_demuxer
= {
876 .long_name
= NULL_IF_CONFIG_SMALL("AviSynth script"),
877 .priv_data_size
= sizeof(AviSynthContext
),
878 .read_header
= avisynth_read_header
,
879 .read_packet
= avisynth_read_packet
,
880 .read_close
= avisynth_read_close
,
881 .read_seek
= avisynth_read_seek
,