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