2 * AviSynth/AvxSynth support
3 * Copyright (c) 2012 AvxSynth Team
5 * This file is part of FFmpeg
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "libavutil/internal.h"
22 #include "libavcodec/internal.h"
27 /* Enable function pointer definitions for runtime loading. */
28 #define AVSC_NO_DECLSPEC
30 /* Platform-specific directives for AviSynth vs AvxSynth. */
34 #include "compat/avisynth/avisynth_c.h"
35 #define AVISYNTH_LIB "avisynth"
36 #define USING_AVISYNTH
39 #include "compat/avisynth/avxsynth_c.h"
40 #define AVISYNTH_NAME "libavxsynth"
41 #define AVISYNTH_LIB AVISYNTH_NAME SLIBSUF
43 #define LoadLibrary(x) dlopen(x, RTLD_NOW | RTLD_LOCAL)
44 #define GetProcAddress dlsym
45 #define FreeLibrary dlclose
48 typedef struct AviSynthLibrary
{
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
);
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
);
74 #undef AVSC_DECLARE_FUNC
77 typedef struct AviSynthContext
{
78 AVS_ScriptEnvironment
*env
;
80 const AVS_VideoInfo
*vi
;
82 /* avisynth_read_packet_video() iterates over this. */
92 /* Linked list pointers. */
93 struct AviSynthContext
*next
;
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
,
100 #ifdef USING_AVISYNTH
101 static const int avs_planes_rgb
[3] = { AVS_PLANAR_G
, AVS_PLANAR_B
,
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
};
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;
114 /* Linked list of AviSynthContexts. An atexit handler destroys this list. */
115 static AviSynthContext
*avs_ctx_list
= NULL
;
117 static av_cold
void avisynth_atexit_handler(void);
119 static av_cold
int avisynth_load_library(void)
121 avs_library
.library
= LoadLibrary(AVISYNTH_LIB
);
122 if (!avs_library
.library
)
123 return AVERROR_UNKNOWN
;
125 #define LOAD_AVS_FUNC(name, continue_on_fail) \
127 (void *)GetProcAddress(avs_library.library, #name); \
128 if (!continue_on_fail && !avs_library.name) \
131 LOAD_AVS_FUNC(avs_bit_blt
, 0);
132 LOAD_AVS_FUNC(avs_clip_get_error
, 0);
133 LOAD_AVS_FUNC(avs_create_script_environment
, 0);
134 LOAD_AVS_FUNC(avs_delete_script_environment
, 0);
135 LOAD_AVS_FUNC(avs_get_audio
, 0);
136 LOAD_AVS_FUNC(avs_get_error
, 1); // New to AviSynth 2.6
137 LOAD_AVS_FUNC(avs_get_frame
, 0);
138 LOAD_AVS_FUNC(avs_get_version
, 0);
139 LOAD_AVS_FUNC(avs_get_video_info
, 0);
140 LOAD_AVS_FUNC(avs_invoke
, 0);
141 LOAD_AVS_FUNC(avs_release_clip
, 0);
142 LOAD_AVS_FUNC(avs_release_value
, 0);
143 LOAD_AVS_FUNC(avs_release_video_frame
, 0);
144 LOAD_AVS_FUNC(avs_take_clip
, 0);
145 #ifdef USING_AVISYNTH
146 LOAD_AVS_FUNC(avs_bits_per_pixel
, 1);
147 LOAD_AVS_FUNC(avs_get_height_p
, 1);
148 LOAD_AVS_FUNC(avs_get_pitch_p
, 1);
149 LOAD_AVS_FUNC(avs_get_read_ptr_p
, 1);
150 LOAD_AVS_FUNC(avs_get_row_size_p
, 1);
151 LOAD_AVS_FUNC(avs_is_planar_rgb
, 1);
152 LOAD_AVS_FUNC(avs_is_planar_rgba
, 1);
156 atexit(avisynth_atexit_handler
);
160 FreeLibrary(avs_library
.library
);
161 return AVERROR_UNKNOWN
;
164 /* Note that avisynth_context_create and avisynth_context_destroy
165 * do not allocate or free the actual context! That is taken care of
167 static av_cold
int avisynth_context_create(AVFormatContext
*s
)
169 AviSynthContext
*avs
= s
->priv_data
;
172 if (!avs_library
.library
)
173 if (ret
= avisynth_load_library())
176 avs
->env
= avs_library
.avs_create_script_environment(3);
177 if (avs_library
.avs_get_error
) {
178 const char *error
= avs_library
.avs_get_error(avs
->env
);
180 av_log(s
, AV_LOG_ERROR
, "%s\n", error
);
181 return AVERROR_UNKNOWN
;
188 avs
->next
= avs_ctx_list
;
195 static av_cold
void avisynth_context_destroy(AviSynthContext
*avs
)
197 if (avs_atexit_called
)
200 if (avs
== avs_ctx_list
) {
201 avs_ctx_list
= avs
->next
;
203 AviSynthContext
*prev
= avs_ctx_list
;
204 while (prev
->next
!= avs
)
206 prev
->next
= avs
->next
;
210 avs_library
.avs_release_clip(avs
->clip
);
214 avs_library
.avs_delete_script_environment(avs
->env
);
219 static av_cold
void avisynth_atexit_handler(void)
221 AviSynthContext
*avs
= avs_ctx_list
;
224 AviSynthContext
*next
= avs
->next
;
225 avisynth_context_destroy(avs
);
228 FreeLibrary(avs_library
.library
);
230 avs_atexit_called
= 1;
233 /* Create AVStream from audio and video data. */
234 static int avisynth_create_stream_video(AVFormatContext
*s
, AVStream
*st
)
236 AviSynthContext
*avs
= s
->priv_data
;
237 int planar
= 0; // 0: packed, 1: YUV, 2: Y8, 3: Planar RGB, 4: YUVA, 5: Planar RGBA
239 st
->codecpar
->codec_type
= AVMEDIA_TYPE_VIDEO
;
240 st
->codecpar
->codec_id
= AV_CODEC_ID_RAWVIDEO
;
241 st
->codecpar
->width
= avs
->vi
->width
;
242 st
->codecpar
->height
= avs
->vi
->height
;
244 st
->avg_frame_rate
= (AVRational
) { avs
->vi
->fps_numerator
,
245 avs
->vi
->fps_denominator
};
247 st
->duration
= avs
->vi
->num_frames
;
248 st
->nb_frames
= avs
->vi
->num_frames
;
249 avpriv_set_pts_info(st
, 32, avs
->vi
->fps_denominator
, avs
->vi
->fps_numerator
);
251 switch (avs
->vi
->pixel_type
) {
252 #ifdef USING_AVISYNTH
253 /* 10~16-bit YUV pix_fmts (AviSynth+) */
254 case AVS_CS_YUV444P10
:
255 st
->codecpar
->format
= AV_PIX_FMT_YUV444P10
;
258 case AVS_CS_YUV422P10
:
259 st
->codecpar
->format
= AV_PIX_FMT_YUV422P10
;
262 case AVS_CS_YUV420P10
:
263 st
->codecpar
->format
= AV_PIX_FMT_YUV420P10
;
266 case AVS_CS_YUV444P12
:
267 st
->codecpar
->format
= AV_PIX_FMT_YUV444P12
;
270 case AVS_CS_YUV422P12
:
271 st
->codecpar
->format
= AV_PIX_FMT_YUV422P12
;
274 case AVS_CS_YUV420P12
:
275 st
->codecpar
->format
= AV_PIX_FMT_YUV420P12
;
278 case AVS_CS_YUV444P14
:
279 st
->codecpar
->format
= AV_PIX_FMT_YUV444P14
;
282 case AVS_CS_YUV422P14
:
283 st
->codecpar
->format
= AV_PIX_FMT_YUV422P14
;
286 case AVS_CS_YUV420P14
:
287 st
->codecpar
->format
= AV_PIX_FMT_YUV420P14
;
290 case AVS_CS_YUV444P16
:
291 st
->codecpar
->format
= AV_PIX_FMT_YUV444P16
;
294 case AVS_CS_YUV422P16
:
295 st
->codecpar
->format
= AV_PIX_FMT_YUV422P16
;
298 case AVS_CS_YUV420P16
:
299 st
->codecpar
->format
= AV_PIX_FMT_YUV420P16
;
302 /* 8~16-bit YUV pix_fmts with Alpha (AviSynth+) */
304 st
->codecpar
->format
= AV_PIX_FMT_YUVA444P
;
308 st
->codecpar
->format
= AV_PIX_FMT_YUVA422P
;
312 st
->codecpar
->format
= AV_PIX_FMT_YUVA420P
;
315 case AVS_CS_YUVA444P10
:
316 st
->codecpar
->format
= AV_PIX_FMT_YUVA444P10
;
319 case AVS_CS_YUVA422P10
:
320 st
->codecpar
->format
= AV_PIX_FMT_YUVA422P10
;
323 case AVS_CS_YUVA420P10
:
324 st
->codecpar
->format
= AV_PIX_FMT_YUVA420P10
;
327 case AVS_CS_YUVA444P16
:
328 st
->codecpar
->format
= AV_PIX_FMT_YUVA444P16
;
331 case AVS_CS_YUVA422P16
:
332 st
->codecpar
->format
= AV_PIX_FMT_YUVA422P16
;
335 case AVS_CS_YUVA420P16
:
336 st
->codecpar
->format
= AV_PIX_FMT_YUVA420P16
;
339 /* Planar RGB pix_fmts (AviSynth+) */
341 st
->codecpar
->format
= AV_PIX_FMT_GBRP
;
345 st
->codecpar
->format
= AV_PIX_FMT_GBRP10
;
349 st
->codecpar
->format
= AV_PIX_FMT_GBRP12
;
353 st
->codecpar
->format
= AV_PIX_FMT_GBRP14
;
357 st
->codecpar
->format
= AV_PIX_FMT_GBRP16
;
360 /* Planar RGB pix_fmts with Alpha (AviSynth+) */
362 st
->codecpar
->format
= AV_PIX_FMT_GBRAP
;
366 st
->codecpar
->format
= AV_PIX_FMT_GBRAP10
;
370 st
->codecpar
->format
= AV_PIX_FMT_GBRAP12
;
374 st
->codecpar
->format
= AV_PIX_FMT_GBRAP16
;
377 /* GRAY16 (AviSynth+) */
379 st
->codecpar
->format
= AV_PIX_FMT_GRAY16
;
382 /* pix_fmts added in AviSynth 2.6 */
384 st
->codecpar
->format
= AV_PIX_FMT_YUV444P
;
388 st
->codecpar
->format
= AV_PIX_FMT_YUV422P
;
392 st
->codecpar
->format
= AV_PIX_FMT_YUV411P
;
396 st
->codecpar
->format
= AV_PIX_FMT_GRAY8
;
399 /* 16-bit packed RGB pix_fmts (AviSynth+) */
401 st
->codecpar
->format
= AV_PIX_FMT_BGR48
;
404 st
->codecpar
->format
= AV_PIX_FMT_BGRA64
;
407 /* AviSynth 2.5 and AvxSynth pix_fmts */
409 st
->codecpar
->format
= AV_PIX_FMT_BGR24
;
412 st
->codecpar
->format
= AV_PIX_FMT_RGB32
;
415 st
->codecpar
->format
= AV_PIX_FMT_YUYV422
;
418 st
->codecpar
->format
= AV_PIX_FMT_YUV420P
;
421 case AVS_CS_I420
: // Is this even used anywhere?
422 st
->codecpar
->format
= AV_PIX_FMT_YUV420P
;
426 av_log(s
, AV_LOG_ERROR
,
427 "unknown AviSynth colorspace %d\n", avs
->vi
->pixel_type
);
429 return AVERROR_UNKNOWN
;
433 #ifdef USING_AVISYNTH
434 case 5: // Planar RGB + Alpha
436 avs
->planes
= avs_planes_rgba
;
438 case 4: // YUV + Alpha
440 avs
->planes
= avs_planes_yuva
;
442 case 3: // Planar RGB
444 avs
->planes
= avs_planes_rgb
;
449 avs
->planes
= avs_planes_grey
;
453 avs
->planes
= avs_planes_yuv
;
457 avs
->planes
= avs_planes_packed
;
462 static int avisynth_create_stream_audio(AVFormatContext
*s
, AVStream
*st
)
464 AviSynthContext
*avs
= s
->priv_data
;
466 st
->codecpar
->codec_type
= AVMEDIA_TYPE_AUDIO
;
467 st
->codecpar
->sample_rate
= avs
->vi
->audio_samples_per_second
;
468 st
->codecpar
->channels
= avs
->vi
->nchannels
;
469 st
->duration
= avs
->vi
->num_audio_samples
;
470 avpriv_set_pts_info(st
, 64, 1, avs
->vi
->audio_samples_per_second
);
472 switch (avs
->vi
->sample_type
) {
473 case AVS_SAMPLE_INT8
:
474 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_U8
;
476 case AVS_SAMPLE_INT16
:
477 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_S16LE
;
479 case AVS_SAMPLE_INT24
:
480 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_S24LE
;
482 case AVS_SAMPLE_INT32
:
483 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_S32LE
;
485 case AVS_SAMPLE_FLOAT
:
486 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_F32LE
;
489 av_log(s
, AV_LOG_ERROR
,
490 "unknown AviSynth sample type %d\n", avs
->vi
->sample_type
);
492 return AVERROR_UNKNOWN
;
497 static int avisynth_create_stream(AVFormatContext
*s
)
499 AviSynthContext
*avs
= s
->priv_data
;
504 if (avs_has_video(avs
->vi
)) {
505 st
= avformat_new_stream(s
, NULL
);
507 return AVERROR_UNKNOWN
;
509 if (ret
= avisynth_create_stream_video(s
, st
))
512 if (avs_has_audio(avs
->vi
)) {
513 st
= avformat_new_stream(s
, NULL
);
515 return AVERROR_UNKNOWN
;
517 if (ret
= avisynth_create_stream_audio(s
, st
))
523 static int avisynth_open_file(AVFormatContext
*s
)
525 AviSynthContext
*avs
= s
->priv_data
;
528 #ifdef USING_AVISYNTH
529 char filename_ansi
[MAX_PATH
* 4];
530 wchar_t filename_wc
[MAX_PATH
* 4];
533 if (ret
= avisynth_context_create(s
))
536 #ifdef USING_AVISYNTH
537 /* Convert UTF-8 to ANSI code page */
538 MultiByteToWideChar(CP_UTF8
, 0, s
->filename
, -1, filename_wc
, MAX_PATH
* 4);
539 WideCharToMultiByte(CP_THREAD_ACP
, 0, filename_wc
, -1, filename_ansi
,
540 MAX_PATH
* 4, NULL
, NULL
);
541 arg
= avs_new_value_string(filename_ansi
);
543 arg
= avs_new_value_string(s
->filename
);
545 val
= avs_library
.avs_invoke(avs
->env
, "Import", arg
, 0);
546 if (avs_is_error(val
)) {
547 av_log(s
, AV_LOG_ERROR
, "%s\n", avs_as_error(val
));
548 ret
= AVERROR_UNKNOWN
;
551 if (!avs_is_clip(val
)) {
552 av_log(s
, AV_LOG_ERROR
, "AviSynth script did not return a clip\n");
553 ret
= AVERROR_UNKNOWN
;
557 avs
->clip
= avs_library
.avs_take_clip(val
, avs
->env
);
558 avs
->vi
= avs_library
.avs_get_video_info(avs
->clip
);
560 #ifdef USING_AVISYNTH
561 /* On Windows, FFmpeg supports AviSynth interface version 6 or higher.
562 * This includes AviSynth 2.6 RC1 or higher, and AviSynth+ r1718 or higher,
563 * and excludes 2.5 and the 2.6 alphas. Since AvxSynth identifies itself
564 * as interface version 3 like 2.5.8, this needs to be special-cased. */
566 if (avs_library
.avs_get_version(avs
->clip
) < 6) {
567 av_log(s
, AV_LOG_ERROR
,
568 "AviSynth version is too old. Please upgrade to either AviSynth 2.6 >= RC1 or AviSynth+ >= r1718.\n");
569 ret
= AVERROR_UNKNOWN
;
574 /* Release the AVS_Value as it will go out of scope. */
575 avs_library
.avs_release_value(val
);
577 if (ret
= avisynth_create_stream(s
))
583 avisynth_context_destroy(avs
);
587 static void avisynth_next_stream(AVFormatContext
*s
, AVStream
**st
,
588 AVPacket
*pkt
, int *discard
)
590 AviSynthContext
*avs
= s
->priv_data
;
593 avs
->curr_stream
%= s
->nb_streams
;
595 *st
= s
->streams
[avs
->curr_stream
];
596 if ((*st
)->discard
== AVDISCARD_ALL
)
604 /* Copy AviSynth clip data into an AVPacket. */
605 static int avisynth_read_packet_video(AVFormatContext
*s
, AVPacket
*pkt
,
608 AviSynthContext
*avs
= s
->priv_data
;
609 AVS_VideoFrame
*frame
;
610 unsigned char *dst_p
;
611 const unsigned char *src_p
;
612 int n
, i
, plane
, rowsize
, planeheight
, pitch
, bits
;
615 if (avs
->curr_frame
>= avs
->vi
->num_frames
)
618 /* This must happen even if the stream is discarded to prevent desync. */
619 n
= avs
->curr_frame
++;
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. */
629 if (GetProcAddress(avs_library
.library
, "avs_is_planar_rgb") == NULL
)
634 /* avs_bits_per_pixel changed to AVSC_API with AviSynth 2.6, which
635 * requires going through avs_library, while AvxSynth has it under
636 * the older AVSC_INLINE type, so special-case this. */
638 bits
= avs_library
.avs_bits_per_pixel(avs
->vi
);
640 bits
= avs_bits_per_pixel(avs
->vi
);
643 /* Without the cast to int64_t, calculation overflows at about 9k x 9k
645 pkt
->size
= (((int64_t)avs
->vi
->width
*
646 (int64_t)avs
->vi
->height
) * bits
) / 8;
648 return AVERROR_UNKNOWN
;
650 if (av_new_packet(pkt
, pkt
->size
) < 0)
651 return AVERROR(ENOMEM
);
656 pkt
->stream_index
= avs
->curr_stream
;
658 frame
= avs_library
.avs_get_frame(avs
->clip
, n
);
659 error
= avs_library
.avs_clip_get_error(avs
->clip
);
661 av_log(s
, AV_LOG_ERROR
, "%s\n", error
);
663 av_packet_unref(pkt
);
664 return AVERROR_UNKNOWN
;
668 for (i
= 0; i
< avs
->n_planes
; i
++) {
669 plane
= avs
->planes
[i
];
670 #ifdef USING_AVISYNTH
671 src_p
= avs_library
.avs_get_read_ptr_p(frame
, plane
);
672 pitch
= avs_library
.avs_get_pitch_p(frame
, plane
);
674 rowsize
= avs_library
.avs_get_row_size_p(frame
, plane
);
675 planeheight
= avs_library
.avs_get_height_p(frame
, plane
);
677 src_p
= avs_get_read_ptr_p(frame
, plane
);
678 pitch
= avs_get_pitch_p(frame
, plane
);
680 rowsize
= avs_get_row_size_p(frame
, plane
);
681 planeheight
= avs_get_height_p(frame
, plane
);
684 /* Flip RGB video. */
685 if (avs_is_rgb24(avs
->vi
) || avs_is_rgb(avs
->vi
)) {
686 src_p
= src_p
+ (planeheight
- 1) * pitch
;
690 #ifdef USING_AVISYNTH
691 /* Flip Planar RGB video. */
692 if (avsplus
&& (avs_library
.avs_is_planar_rgb(avs
->vi
) ||
693 avs_library
.avs_is_planar_rgba(avs
->vi
))) {
694 src_p
= src_p
+ (planeheight
- 1) * pitch
;
699 avs_library
.avs_bit_blt(avs
->env
, dst_p
, rowsize
, src_p
, pitch
,
700 rowsize
, planeheight
);
701 dst_p
+= rowsize
* planeheight
;
704 avs_library
.avs_release_video_frame(frame
);
708 static int avisynth_read_packet_audio(AVFormatContext
*s
, AVPacket
*pkt
,
711 AviSynthContext
*avs
= s
->priv_data
;
712 AVRational fps
, samplerate
;
717 if (avs
->curr_sample
>= avs
->vi
->num_audio_samples
)
720 fps
.num
= avs
->vi
->fps_numerator
;
721 fps
.den
= avs
->vi
->fps_denominator
;
722 samplerate
.num
= avs
->vi
->audio_samples_per_second
;
725 if (avs_has_video(avs
->vi
)) {
726 if (avs
->curr_frame
< avs
->vi
->num_frames
)
727 samples
= av_rescale_q(avs
->curr_frame
, samplerate
, fps
) -
730 samples
= av_rescale_q(1, samplerate
, fps
);
735 /* After seeking, audio may catch up with video. */
742 if (avs
->curr_sample
+ samples
> avs
->vi
->num_audio_samples
)
743 samples
= avs
->vi
->num_audio_samples
- avs
->curr_sample
;
745 /* This must happen even if the stream is discarded to prevent desync. */
746 n
= avs
->curr_sample
;
747 avs
->curr_sample
+= samples
;
751 pkt
->size
= avs_bytes_per_channel_sample(avs
->vi
) *
752 samples
* avs
->vi
->nchannels
;
754 return AVERROR_UNKNOWN
;
756 if (av_new_packet(pkt
, pkt
->size
) < 0)
757 return AVERROR(ENOMEM
);
761 pkt
->duration
= samples
;
762 pkt
->stream_index
= avs
->curr_stream
;
764 avs_library
.avs_get_audio(avs
->clip
, pkt
->data
, n
, samples
);
765 error
= avs_library
.avs_clip_get_error(avs
->clip
);
767 av_log(s
, AV_LOG_ERROR
, "%s\n", error
);
769 av_packet_unref(pkt
);
770 return AVERROR_UNKNOWN
;
775 static av_cold
int avisynth_read_header(AVFormatContext
*s
)
779 // Calling library must implement a lock for thread-safe opens.
780 if (ret
= avpriv_lock_avformat())
783 if (ret
= avisynth_open_file(s
)) {
784 avpriv_unlock_avformat();
788 avpriv_unlock_avformat();
792 static int avisynth_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
794 AviSynthContext
*avs
= s
->priv_data
;
800 return AVERROR_UNKNOWN
;
802 /* If either stream reaches EOF, try to read the other one before
804 avisynth_next_stream(s
, &st
, pkt
, &discard
);
805 if (st
->codecpar
->codec_type
== AVMEDIA_TYPE_VIDEO
) {
806 ret
= avisynth_read_packet_video(s
, pkt
, discard
);
807 if (ret
== AVERROR_EOF
&& avs_has_audio(avs
->vi
)) {
808 avisynth_next_stream(s
, &st
, pkt
, &discard
);
809 return avisynth_read_packet_audio(s
, pkt
, discard
);
812 ret
= avisynth_read_packet_audio(s
, pkt
, discard
);
813 if (ret
== AVERROR_EOF
&& avs_has_video(avs
->vi
)) {
814 avisynth_next_stream(s
, &st
, pkt
, &discard
);
815 return avisynth_read_packet_video(s
, pkt
, discard
);
822 static av_cold
int avisynth_read_close(AVFormatContext
*s
)
824 if (avpriv_lock_avformat())
825 return AVERROR_UNKNOWN
;
827 avisynth_context_destroy(s
->priv_data
);
828 avpriv_unlock_avformat();
832 static int avisynth_read_seek(AVFormatContext
*s
, int stream_index
,
833 int64_t timestamp
, int flags
)
835 AviSynthContext
*avs
= s
->priv_data
;
837 AVRational fps
, samplerate
;
840 return AVERROR_UNKNOWN
;
842 fps
= (AVRational
) { avs
->vi
->fps_numerator
,
843 avs
->vi
->fps_denominator
};
844 samplerate
= (AVRational
) { avs
->vi
->audio_samples_per_second
, 1 };
846 st
= s
->streams
[stream_index
];
847 if (st
->codecpar
->codec_type
== AVMEDIA_TYPE_VIDEO
) {
848 /* AviSynth frame counts are signed int. */
849 if ((timestamp
>= avs
->vi
->num_frames
) ||
850 (timestamp
> INT_MAX
) ||
853 avs
->curr_frame
= timestamp
;
854 if (avs_has_audio(avs
->vi
))
855 avs
->curr_sample
= av_rescale_q(timestamp
, samplerate
, fps
);
857 if ((timestamp
>= avs
->vi
->num_audio_samples
) || (timestamp
< 0))
859 /* Force frame granularity for seeking. */
860 if (avs_has_video(avs
->vi
)) {
861 avs
->curr_frame
= av_rescale_q(timestamp
, fps
, samplerate
);
862 avs
->curr_sample
= av_rescale_q(avs
->curr_frame
, samplerate
, fps
);
864 avs
->curr_sample
= timestamp
;
871 AVInputFormat ff_avisynth_demuxer
= {
873 .long_name
= NULL_IF_CONFIG_SMALL("AviSynth script"),
874 .priv_data_size
= sizeof(AviSynthContext
),
875 .read_header
= avisynth_read_header
,
876 .read_packet
= avisynth_read_packet
,
877 .read_close
= avisynth_read_close
,
878 .read_seek
= avisynth_read_seek
,