FFmpeg
avisynth.c
Go to the documentation of this file.
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 #include <avisynth/avisynth_c.h>
46 
47 typedef struct AviSynthLibrary {
48  void *library;
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
73 
74 typedef struct AviSynthContext {
75  AVS_ScriptEnvironment *env;
76  AVS_Clip *clip;
77  const AVS_VideoInfo *vi;
78 
79  /* avisynth_read_packet_video() iterates over this. */
80  int n_planes;
81  const int *planes;
82 
85  int64_t curr_sample;
86 
87  int error;
88 
89  /* Linked list pointers. */
92 
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,
96  AVS_PLANAR_V };
97 static const int avs_planes_rgb[3] = { AVS_PLANAR_G, AVS_PLANAR_B,
98  AVS_PLANAR_R };
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 };
103 
104 /* A conflict between C++ global objects, atexit, and dynamic loading requires
105  * us to register our own atexit handler to prevent double freeing. */
107 static int avs_atexit_called = 0;
108 
109 /* Linked list of AviSynthContexts. An atexit handler destroys this list. */
111 
112 static av_cold void avisynth_atexit_handler(void);
113 
115 {
116  avs_library.library = dlopen(AVISYNTH_LIB, RTLD_NOW | RTLD_LOCAL);
117  if (!avs_library.library)
118  return AVERROR_UNKNOWN;
119 
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) \
124  goto fail;
125 
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);
147 #undef LOAD_AVS_FUNC
148 
149  atexit(avisynth_atexit_handler);
150  return 0;
151 
152 fail:
153  dlclose(avs_library.library);
154  return AVERROR_UNKNOWN;
155 }
156 
157 /* Note that avisynth_context_create and avisynth_context_destroy
158  * do not allocate or free the actual context! That is taken care of
159  * by libavformat. */
161 {
162  AviSynthContext *avs = s->priv_data;
163  int ret;
164 
165  if (!avs_library.library)
166  if (ret = avisynth_load_library())
167  return ret;
168 
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);
172  if (error) {
173  av_log(s, AV_LOG_ERROR, "%s\n", error);
174  return AVERROR_UNKNOWN;
175  }
176  }
177 
178  if (!avs_ctx_list) {
179  avs_ctx_list = avs;
180  } else {
181  avs->next = avs_ctx_list;
182  avs_ctx_list = avs;
183  }
184 
185  return 0;
186 }
187 
189 {
190  if (avs_atexit_called)
191  return;
192 
193  if (avs == avs_ctx_list) {
194  avs_ctx_list = avs->next;
195  } else {
197  while (prev->next != avs)
198  prev = prev->next;
199  prev->next = avs->next;
200  }
201 
202  if (avs->clip) {
203  avs_library.avs_release_clip(avs->clip);
204  avs->clip = NULL;
205  }
206  if (avs->env) {
207  avs_library.avs_delete_script_environment(avs->env);
208  avs->env = NULL;
209  }
210 }
211 
213 {
215 
216  while (avs) {
217  AviSynthContext *next = avs->next;
219  avs = next;
220  }
221  dlclose(avs_library.library);
222 
223  avs_atexit_called = 1;
224 }
225 
226 /* Create AVStream from audio and video data. */
228 {
229  AviSynthContext *avs = s->priv_data;
230  int planar = 0; // 0: packed, 1: YUV, 2: Y8, 3: Planar RGB, 4: YUVA, 5: Planar RGBA
231 
234  st->codecpar->width = avs->vi->width;
235  st->codecpar->height = avs->vi->height;
236 
237  st->avg_frame_rate = (AVRational) { avs->vi->fps_numerator,
238  avs->vi->fps_denominator };
239  st->start_time = 0;
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);
243 
244  switch (avs->vi->pixel_type) {
245  /* 10~16-bit YUV pix_fmts (AviSynth+) */
246  case AVS_CS_YUV444P10:
248  planar = 1;
249  break;
250  case AVS_CS_YUV422P10:
252  planar = 1;
253  break;
254  case AVS_CS_YUV420P10:
256  planar = 1;
257  break;
258  case AVS_CS_YUV444P12:
260  planar = 1;
261  break;
262  case AVS_CS_YUV422P12:
264  planar = 1;
265  break;
266  case AVS_CS_YUV420P12:
268  planar = 1;
269  break;
270  case AVS_CS_YUV444P14:
272  planar = 1;
273  break;
274  case AVS_CS_YUV422P14:
276  planar = 1;
277  break;
278  case AVS_CS_YUV420P14:
280  planar = 1;
281  break;
282  case AVS_CS_YUV444P16:
284  planar = 1;
285  break;
286  case AVS_CS_YUV422P16:
288  planar = 1;
289  break;
290  case AVS_CS_YUV420P16:
292  planar = 1;
293  break;
294  /* 8~16-bit YUV pix_fmts with Alpha (AviSynth+) */
295  case AVS_CS_YUVA444:
297  planar = 4;
298  break;
299  case AVS_CS_YUVA422:
301  planar = 4;
302  break;
303  case AVS_CS_YUVA420:
305  planar = 4;
306  break;
307  case AVS_CS_YUVA444P10:
309  planar = 4;
310  break;
311  case AVS_CS_YUVA422P10:
313  planar = 4;
314  break;
315  case AVS_CS_YUVA420P10:
317  planar = 4;
318  break;
319  case AVS_CS_YUVA422P12:
321  planar = 4;
322  break;
323  case AVS_CS_YUVA444P16:
325  planar = 4;
326  break;
327  case AVS_CS_YUVA422P16:
329  planar = 4;
330  break;
331  case AVS_CS_YUVA420P16:
333  planar = 4;
334  break;
335  /* Planar RGB pix_fmts (AviSynth+) */
336  case AVS_CS_RGBP:
338  planar = 3;
339  break;
340  case AVS_CS_RGBP10:
342  planar = 3;
343  break;
344  case AVS_CS_RGBP12:
346  planar = 3;
347  break;
348  case AVS_CS_RGBP14:
350  planar = 3;
351  break;
352  case AVS_CS_RGBP16:
354  planar = 3;
355  break;
356  /* Single precision floating point Planar RGB (AviSynth+) */
357  case AVS_CS_RGBPS:
359  planar = 3;
360  break;
361  /* Planar RGB pix_fmts with Alpha (AviSynth+) */
362  case AVS_CS_RGBAP:
364  planar = 5;
365  break;
366  case AVS_CS_RGBAP10:
368  planar = 5;
369  break;
370  case AVS_CS_RGBAP12:
372  planar = 5;
373  break;
374  case AVS_CS_RGBAP16:
376  planar = 5;
377  break;
378  /* Single precision floating point Planar RGB with Alpha (AviSynth+) */
379  case AVS_CS_RGBAPS:
381  planar = 5;
382  break;
383  /* 10~16-bit gray pix_fmts (AviSynth+) */
384  case AVS_CS_Y10:
386  planar = 2;
387  break;
388  case AVS_CS_Y12:
390  planar = 2;
391  break;
392  case AVS_CS_Y14:
394  planar = 2;
395  break;
396  case AVS_CS_Y16:
398  planar = 2;
399  break;
400  /* Single precision floating point gray (AviSynth+) */
401  case AVS_CS_Y32:
403  planar = 2;
404  break;
405  /* pix_fmts added in AviSynth 2.6 */
406  case AVS_CS_YV24:
408  planar = 1;
409  break;
410  case AVS_CS_YV16:
412  planar = 1;
413  break;
414  case AVS_CS_YV411:
416  planar = 1;
417  break;
418  case AVS_CS_Y8:
420  planar = 2;
421  break;
422  /* 16-bit packed RGB pix_fmts (AviSynth+) */
423  case AVS_CS_BGR48:
425  break;
426  case AVS_CS_BGR64:
428  break;
429  /* AviSynth 2.5 pix_fmts */
430  case AVS_CS_BGR24:
432  break;
433  case AVS_CS_BGR32:
435  break;
436  case AVS_CS_YUY2:
438  break;
439  case AVS_CS_YV12:
441  planar = 1;
442  break;
443  case AVS_CS_I420: // Is this even used anywhere?
445  planar = 1;
446  break;
447  default:
449  "unknown AviSynth colorspace %d\n", avs->vi->pixel_type);
450  avs->error = 1;
451  return AVERROR_UNKNOWN;
452  }
453 
454  switch (planar) {
455  case 5: // Planar RGB + Alpha
456  avs->n_planes = 4;
457  avs->planes = avs_planes_rgba;
458  break;
459  case 4: // YUV + Alpha
460  avs->n_planes = 4;
461  avs->planes = avs_planes_yuva;
462  break;
463  case 3: // Planar RGB
464  avs->n_planes = 3;
465  avs->planes = avs_planes_rgb;
466  break;
467  case 2: // Y8
468  avs->n_planes = 1;
469  avs->planes = avs_planes_grey;
470  break;
471  case 1: // YUV
472  avs->n_planes = 3;
473  avs->planes = avs_planes_yuv;
474  break;
475  default:
476  avs->n_planes = 1;
477  avs->planes = avs_planes_packed;
478  }
479  return 0;
480 }
481 
483 {
484  AviSynthContext *avs = s->priv_data;
485 
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);
491 
492  switch (avs->vi->sample_type) {
493  case AVS_SAMPLE_INT8:
495  break;
496  case AVS_SAMPLE_INT16:
498  break;
499  case AVS_SAMPLE_INT24:
501  break;
502  case AVS_SAMPLE_INT32:
504  break;
505  case AVS_SAMPLE_FLOAT:
507  break;
508  default:
510  "unknown AviSynth sample type %d\n", avs->vi->sample_type);
511  avs->error = 1;
512  return AVERROR_UNKNOWN;
513  }
514  return 0;
515 }
516 
518 {
519  AviSynthContext *avs = s->priv_data;
520  AVStream *st;
521  int ret;
522  int id = 0;
523 
524  if (avs_has_video(avs->vi)) {
525  st = avformat_new_stream(s, NULL);
526  if (!st)
527  return AVERROR_UNKNOWN;
528  st->id = id++;
530  return ret;
531  }
532  if (avs_has_audio(avs->vi)) {
533  st = avformat_new_stream(s, NULL);
534  if (!st)
535  return AVERROR_UNKNOWN;
536  st->id = id++;
538  return ret;
539  }
540  return 0;
541 }
542 
544 {
545  AviSynthContext *avs = s->priv_data;
546  AVS_Value arg, val;
547  int ret;
548 #ifdef _WIN32
549  char filename_ansi[MAX_PATH * 4];
550  wchar_t filename_wc[MAX_PATH * 4];
551 #endif
552 
554  return ret;
555 
556 #ifdef _WIN32
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);
562 #else
563  arg = avs_new_value_string(s->url);
564 #endif
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));
569  goto fail;
570  }
571  if (!avs_is_clip(val)) {
572  av_log(s, AV_LOG_ERROR, "AviSynth script did not return a clip\n");
574  goto fail;
575  }
576 
577  avs->clip = avs_library.avs_take_clip(val, avs->env);
578  avs->vi = avs_library.avs_get_video_info(avs->clip);
579 
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. */
583 
584  if (avs_library.avs_get_version(avs->clip) < 6) {
586  "AviSynth version is too old. Please upgrade to either AviSynth 2.6 >= RC1 or AviSynth+ >= r1718.\n");
588  goto fail;
589  }
590 
591  /* Release the AVS_Value as it will go out of scope. */
592  avs_library.avs_release_value(val);
593 
595  goto fail;
596 
597  return 0;
598 
599 fail:
601  return ret;
602 }
603 
605  AVPacket *pkt, int *discard)
606 {
607  AviSynthContext *avs = s->priv_data;
608 
609  avs->curr_stream++;
610  avs->curr_stream %= s->nb_streams;
611 
612  *st = s->streams[avs->curr_stream];
613  if ((*st)->discard == AVDISCARD_ALL)
614  *discard = 1;
615  else
616  *discard = 0;
617 
618  return;
619 }
620 
621 /* Copy AviSynth clip data into an AVPacket. */
623  int discard)
624 {
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;
630  const char *error;
631  int avsplus av_unused;
632 
633  if (avs->curr_frame >= avs->vi->num_frames)
634  return AVERROR_EOF;
635 
636  /* This must happen even if the stream is discarded to prevent desync. */
637  n = avs->curr_frame++;
638  if (discard)
639  return 0;
640 
641 #ifdef _WIN32
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)
645  avsplus = 0;
646  else
647  avsplus = 1;
648 #else
649  /* AviSynth+ is now the only variant of AviSynth we support
650  * on Linux and macOS. */
651  avsplus = 1;
652 #endif
653 
654  bits = avs_library.avs_bits_per_pixel(avs->vi);
655 
656  /* Without the cast to int64_t, calculation overflows at about 9k x 9k
657  * resolution. */
658  pkt->size = (((int64_t)avs->vi->width *
659  (int64_t)avs->vi->height) * bits) / 8;
660  if (!pkt->size)
661  return AVERROR_UNKNOWN;
662 
663  if ((ret = av_new_packet(pkt, pkt->size)) < 0)
664  return ret;
665 
666  pkt->pts = n;
667  pkt->dts = n;
668  pkt->duration = 1;
669  pkt->stream_index = avs->curr_stream;
670 
671  frame = avs_library.avs_get_frame(avs->clip, n);
672  error = avs_library.avs_clip_get_error(avs->clip);
673  if (error) {
674  av_log(s, AV_LOG_ERROR, "%s\n", error);
675  avs->error = 1;
677  return AVERROR_UNKNOWN;
678  }
679 
680  dst_p = pkt->data;
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);
685 
686  rowsize = avs_library.avs_get_row_size_p(frame, plane);
687  planeheight = avs_library.avs_get_height_p(frame, plane);
688 
689  /* Flip RGB video. */
690  if (avs_is_rgb24(avs->vi) || avs_is_rgb(avs->vi)) {
691  src_p = src_p + (planeheight - 1) * pitch;
692  pitch = -pitch;
693  }
694 
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;
699  pitch = -pitch;
700  }
701 
702  avs_library.avs_bit_blt(avs->env, dst_p, rowsize, src_p, pitch,
703  rowsize, planeheight);
704  dst_p += rowsize * planeheight;
705  }
706 
707  avs_library.avs_release_video_frame(frame);
708  return 0;
709 }
710 
712  int discard)
713 {
714  AviSynthContext *avs = s->priv_data;
715  AVRational fps, samplerate;
716  int samples, ret;
717  int64_t n;
718  const char *error;
719 
720  if (avs->curr_sample >= avs->vi->num_audio_samples)
721  return AVERROR_EOF;
722 
723  fps.num = avs->vi->fps_numerator;
724  fps.den = avs->vi->fps_denominator;
725  samplerate.num = avs->vi->audio_samples_per_second;
726  samplerate.den = 1;
727 
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) -
731  avs->curr_sample;
732  else
733  samples = av_rescale_q(1, samplerate, fps);
734  } else {
735  samples = 1000;
736  }
737 
738  /* After seeking, audio may catch up with video. */
739  if (samples <= 0) {
740  pkt->size = 0;
741  pkt->data = NULL;
742  return 0;
743  }
744 
745  if (avs->curr_sample + samples > avs->vi->num_audio_samples)
746  samples = avs->vi->num_audio_samples - avs->curr_sample;
747 
748  /* This must happen even if the stream is discarded to prevent desync. */
749  n = avs->curr_sample;
750  avs->curr_sample += samples;
751  if (discard)
752  return 0;
753 
754  pkt->size = avs_bytes_per_channel_sample(avs->vi) *
755  samples * avs->vi->nchannels;
756  if (!pkt->size)
757  return AVERROR_UNKNOWN;
758 
759  if ((ret = av_new_packet(pkt, pkt->size)) < 0)
760  return ret;
761 
762  pkt->pts = n;
763  pkt->dts = n;
764  pkt->duration = samples;
765  pkt->stream_index = avs->curr_stream;
766 
767  avs_library.avs_get_audio(avs->clip, pkt->data, n, samples);
768  error = avs_library.avs_clip_get_error(avs->clip);
769  if (error) {
770  av_log(s, AV_LOG_ERROR, "%s\n", error);
771  avs->error = 1;
773  return AVERROR_UNKNOWN;
774  }
775  return 0;
776 }
777 
779 {
780  int ret;
781 
782  // Calling library must implement a lock for thread-safe opens.
783  if (ret = ff_lock_avformat())
784  return ret;
785 
786  if (ret = avisynth_open_file(s)) {
788  return ret;
789  }
790 
792  return 0;
793 }
794 
796 {
797  AviSynthContext *avs = s->priv_data;
798  AVStream *st;
799  int discard = 0;
800  int ret;
801 
802  if (avs->error)
803  return AVERROR_UNKNOWN;
804 
805  /* If either stream reaches EOF, try to read the other one before
806  * giving up. */
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);
813  }
814  } else {
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);
819  }
820  }
821 
822  return ret;
823 }
824 
826 {
827  if (ff_lock_avformat())
828  return AVERROR_UNKNOWN;
829 
830  avisynth_context_destroy(s->priv_data);
832  return 0;
833 }
834 
835 static int avisynth_read_seek(AVFormatContext *s, int stream_index,
836  int64_t timestamp, int flags)
837 {
838  AviSynthContext *avs = s->priv_data;
839  AVStream *st;
840  AVRational fps, samplerate;
841 
842  if (avs->error)
843  return AVERROR_UNKNOWN;
844 
845  fps = (AVRational) { avs->vi->fps_numerator,
846  avs->vi->fps_denominator };
847  samplerate = (AVRational) { avs->vi->audio_samples_per_second, 1 };
848 
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) ||
854  (timestamp < 0))
855  return AVERROR_EOF;
856  avs->curr_frame = timestamp;
857  if (avs_has_audio(avs->vi))
858  avs->curr_sample = av_rescale_q(timestamp, samplerate, fps);
859  } else {
860  if ((timestamp >= avs->vi->num_audio_samples) || (timestamp < 0))
861  return AVERROR_EOF;
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);
866  } else {
867  avs->curr_sample = timestamp;
868  }
869  }
870 
871  return 0;
872 }
873 
875  .name = "avisynth",
876  .long_name = NULL_IF_CONFIG_SMALL("AviSynth script"),
877  .priv_data_size = sizeof(AviSynthContext),
882  .extensions = "avs",
883 };
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:29
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:301
AV_PIX_FMT_YUVA422P16
#define AV_PIX_FMT_YUVA422P16
Definition: pixfmt.h:440
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:605
AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:419
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4526
avisynth_atexit_handler
static av_cold void avisynth_atexit_handler(void)
Definition: avisynth.c:212
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:56
avisynth_load_library
static av_cold int avisynth_load_library(void)
Definition: avisynth.c:114
ff_avisynth_demuxer
AVInputFormat ff_avisynth_demuxer
Definition: avisynth.c:874
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
avisynth_read_seek
static int avisynth_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: avisynth.c:835
avisynth_read_packet
static int avisynth_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: avisynth.c:795
AV_CODEC_ID_RAWVIDEO
@ AV_CODEC_ID_RAWVIDEO
Definition: codec_id.h:62
av_unused
#define av_unused
Definition: attributes.h:131
AviSynthContext::curr_sample
int64_t curr_sample
Definition: avisynth.c:85
AV_PIX_FMT_YUVA420P16
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:439
avs_atexit_called
static int avs_atexit_called
Definition: avisynth.c:107
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:355
AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:434
AviSynthLibrary::library
void * library
Definition: avisynth.c:48
avs_planes_yuv
static const int avs_planes_yuv[3]
Definition: avisynth.c:95
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:938
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:397
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:373
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:71
AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:435
AviSynthContext::curr_stream
int curr_stream
Definition: avisynth.c:83
ff_unlock_avformat
int ff_unlock_avformat(void)
Definition: utils.c:83
AviSynthLibrary
Definition: avisynth.c:47
AVCodecParameters::channels
int channels
Audio only.
Definition: codec_par.h:166
AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:415
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
fail
#define fail()
Definition: checkasm.h:123
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:413
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:153
AV_PIX_FMT_YUVA444P16
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:441
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
val
static double val(void *priv, double ch)
Definition: aeval.c:76
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:381
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:914
AVISYNTH_LIB
#define AVISYNTH_LIB
Definition: avisynth.c:42
AVRational::num
int num
Numerator.
Definition: rational.h:59
avisynth_create_stream_video
static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
Definition: avisynth.c:227
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:400
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AVInputFormat
Definition: avformat.h:636
av_cold
#define av_cold
Definition: attributes.h:90
AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:409
AV_PIX_FMT_GBRAP10
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:417
s
#define s(width, name)
Definition: cbs_vp9.c:257
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:88
AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:418
LOAD_AVS_FUNC
#define LOAD_AVS_FUNC(name, continue_on_fail)
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:410
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:641
avisynth_read_close
static av_cold int avisynth_read_close(AVFormatContext *s)
Definition: avisynth.c:825
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:126
bits
uint8_t bits
Definition: vp3data.h:202
avs_ctx_list
static AviSynthContext * avs_ctx_list
Definition: avisynth.c:110
AV_PIX_FMT_YUV420P16
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:408
avs_planes_rgba
static const int avs_planes_rgba[4]
Definition: avisynth.c:101
AV_PIX_FMT_GRAY14
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:380
AviSynthContext::error
int error
Definition: avisynth.c:87
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
avisynth_next_stream
static void avisynth_next_stream(AVFormatContext *s, AVStream **st, AVPacket *pkt, int *discard)
Definition: avisynth.c:604
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
AV_PIX_FMT_GRAYF32
#define AV_PIX_FMT_GRAYF32
Definition: pixfmt.h:429
arg
const char * arg
Definition: jacosubdec.c:66
AV_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:378
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: avcodec.h:236
AVFormatContext
Format I/O context.
Definition: avformat.h:1335
AviSynthContext::env
AVS_ScriptEnvironment * env
Definition: avisynth.c:75
AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:416
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1012
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:527
AviSynthContext::planes
const int * planes
Definition: avisynth.c:81
AV_PIX_FMT_BGR48
#define AV_PIX_FMT_BGR48
Definition: pixfmt.h:388
NULL
#define NULL
Definition: coverity.c:32
avisynth_context_destroy
static av_cold void avisynth_context_destroy(AviSynthContext *avs)
Definition: avisynth.c:188
AV_PIX_FMT_YUYV422
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:67
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
avisynth_read_packet_audio
static int avisynth_read_packet_audio(AVFormatContext *s, AVPacket *pkt, int discard)
Definition: avisynth.c:711
avisynth_read_header
static av_cold int avisynth_read_header(AVFormatContext *s)
Definition: avisynth.c:778
avs_library
static AviSynthLibrary avs_library
Definition: avisynth.c:106
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:398
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:170
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:916
AviSynthContext::clip
AVS_Clip * clip
Definition: avisynth.c:76
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:313
AVPacket::size
int size
Definition: packet.h:356
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
avisynth_read_packet_video
static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, int discard)
Definition: avisynth.c:622
avisynth_create_stream
static int avisynth_create_stream(AVFormatContext *s)
Definition: avisynth.c:517
AviSynthContext
Definition: avisynth.c:74
AV_PIX_FMT_GBRPF32
#define AV_PIX_FMT_GBRPF32
Definition: pixfmt.h:426
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4948
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:402
ff_lock_avformat
int ff_lock_avformat(void)
Definition: utils.c:78
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:404
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:354
AV_PIX_FMT_RGB32
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:370
AV_PIX_FMT_YUVA444P
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:436
attributes.h
AviSynthContext::curr_frame
int curr_frame
Definition: avisynth.c:84
avs_planes_grey
static const int avs_planes_grey[1]
Definition: avisynth.c:94
AV_PIX_FMT_BGRA64
#define AV_PIX_FMT_BGRA64
Definition: pixfmt.h:392
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:348
internal.h
AVCodecParameters::height
int height
Definition: codec_par.h:127
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:414
avisynth_create_stream_audio
static int avisynth_create_stream_audio(AVFormatContext *s, AVStream *st)
Definition: avisynth.c:482
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:872
ret
ret
Definition: filter_design.txt:187
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
AVStream
Stream structure.
Definition: avformat.h:865
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
avformat.h
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:401
AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:406
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_YUVA422P12
#define AV_PIX_FMT_YUVA422P12
Definition: pixfmt.h:437
AV_PIX_FMT_GBRAPF32
#define AV_PIX_FMT_GBRAPF32
Definition: pixfmt.h:427
avs_planes_rgb
static const int avs_planes_rgb[3]
Definition: avisynth.c:97
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
AVPacket::stream_index
int stream_index
Definition: packet.h:357
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:309
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
avs_planes_yuva
static const int avs_planes_yuva[4]
Definition: avisynth.c:99
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:306
AVCodecParameters::format
int format
Definition: codec_par.h:84
AviSynthContext::n_planes
int n_planes
Definition: avisynth.c:80
AviSynthContext::vi
const AVS_VideoInfo * vi
Definition: avisynth.c:77
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:60
AVPacket
This structure stores compressed data.
Definition: packet.h:332
AV_PIX_FMT_YUV411P
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
AviSynthContext::next
struct AviSynthContext * next
Definition: avisynth.c:90
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
AviSynthLibrary::AVSC_DECLARE_FUNC
AVSC_DECLARE_FUNC(avs_bit_blt)
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:322
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
avisynth_context_create
static av_cold int avisynth_context_create(AVFormatContext *s)
Definition: avisynth.c:160
AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:407
avisynth_open_file
static int avisynth_open_file(AVFormatContext *s)
Definition: avisynth.c:543
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:904
AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:379
planar
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi - 0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1<< 16)) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0f/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(UINT64_C(1)<< 63))) #define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={ FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), };static void cpy1(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, len);} static void cpy2(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 2 *len);} static void cpy4(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 4 *len);} static void cpy8(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 8 *len);} AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags) { AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){ in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);} ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map) { switch(av_get_bytes_per_sample(in_fmt)){ case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;} } if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;} void swri_audio_convert_free(AudioConvert **ctx) { av_freep(ctx);} int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) { int ch;int off=0;const int os=(out->planar ? 1 :out->ch_count) *out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask) { int planes=in->planar ? in->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;} if(ctx->out_simd_align_mask) { int planes=out->planar ? out->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;} if(ctx->simd_f &&!ctx->ch_map &&!misaligned){ off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){ if(out->planar==in->planar){ int planes=out->planar ? out->ch_count :1;for(ch=0;ch< planes;ch++){ ctx->simd_f(out->ch+ch,(const uint8_t **) in->ch+ch, off *(out-> planar
Definition: audioconvert.c:56
avs_planes_packed
static const int avs_planes_packed[1]
Definition: avisynth.c:93
AV_PIX_FMT_YUVA422P
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
AV_PIX_FMT_YUV420P14
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:405
w32dlfcn.h