Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Avi/AvxSynth support
  3.  * Copyright (c) 2012 AvxSynth Team.
  4.  *
  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.
  10.  *
  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.
  15.  *
  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
  19.  */
  20.  
  21. #include "libavutil/internal.h"
  22. #include "avformat.h"
  23. #include "internal.h"
  24. #include "libavcodec/internal.h"
  25.  
  26. // Enable function pointer definitions for runtime loading.
  27. #define AVSC_NO_DECLSPEC
  28.  
  29. // Shut up ffmpeg error messages.
  30. // avisynth_c.h contains inline functions that call these functions.
  31. #undef malloc
  32. #undef free
  33. #undef printf
  34.  
  35. // Platform-specific directives for AviSynth vs AvxSynth.
  36. #ifdef _WIN32
  37.   #include <windows.h>
  38.   #undef EXTERN_C
  39.   #include "compat/avisynth/avisynth_c.h"
  40.   #include "compat/avisynth/avisynth_c_25.h"
  41.   #define AVISYNTH_LIB "avisynth"
  42. #else
  43.   #include <dlfcn.h>
  44.   #include "compat/avisynth/avxsynth_c.h"
  45.    #if defined (__APPLE__)
  46.      #define AVISYNTH_LIB "libavxsynth.dylib"
  47.    #else
  48.      #define AVISYNTH_LIB "libavxsynth.so"
  49.    #endif
  50.  
  51.   #define LoadLibrary(x) dlopen(x, RTLD_NOW | RTLD_GLOBAL)
  52.   #define GetProcAddress dlsym
  53.   #define FreeLibrary dlclose
  54. #endif
  55.  
  56. // AvxSynth doesn't have these colorspaces, so disable them
  57. #ifndef _WIN32
  58. #define avs_is_yv24(vi) 0
  59. #define avs_is_yv16(vi) 0
  60. #define avs_is_yv411(vi) 0
  61. #define avs_is_y8(vi) 0
  62. #endif
  63.  
  64. typedef struct {
  65.     void *library;
  66. #define AVSC_DECLARE_FUNC(name) name##_func name
  67.     AVSC_DECLARE_FUNC(avs_bit_blt);
  68.     AVSC_DECLARE_FUNC(avs_clip_get_error);
  69.     AVSC_DECLARE_FUNC(avs_create_script_environment);
  70.     AVSC_DECLARE_FUNC(avs_delete_script_environment);
  71.     AVSC_DECLARE_FUNC(avs_get_audio);
  72.     AVSC_DECLARE_FUNC(avs_get_error);
  73.     AVSC_DECLARE_FUNC(avs_get_frame);
  74.     AVSC_DECLARE_FUNC(avs_get_version);
  75.     AVSC_DECLARE_FUNC(avs_get_video_info);
  76.     AVSC_DECLARE_FUNC(avs_invoke);
  77.     AVSC_DECLARE_FUNC(avs_release_clip);
  78.     AVSC_DECLARE_FUNC(avs_release_value);
  79.     AVSC_DECLARE_FUNC(avs_release_video_frame);
  80.     AVSC_DECLARE_FUNC(avs_take_clip);
  81. #undef AVSC_DECLARE_FUNC
  82. } AviSynthLibrary;
  83.  
  84. struct AviSynthContext {
  85.     AVS_ScriptEnvironment *env;
  86.     AVS_Clip *clip;
  87.     const AVS_VideoInfo *vi;
  88.  
  89.     // avisynth_read_packet_video() iterates over this.
  90.     int n_planes;
  91.     const int *planes;
  92.  
  93.     int curr_stream;
  94.     int curr_frame;
  95.     int64_t curr_sample;
  96.  
  97.     int error;
  98.  
  99.     // Linked list pointers.
  100.     struct AviSynthContext *next;
  101. };
  102. typedef struct AviSynthContext AviSynthContext;
  103.  
  104. static const int avs_planes_packed[1] = {0};
  105. static const int avs_planes_grey[1] = {AVS_PLANAR_Y};
  106. static const int avs_planes_yuv[3] = {AVS_PLANAR_Y, AVS_PLANAR_U, AVS_PLANAR_V};
  107.  
  108. // A conflict between C++ global objects, atexit, and dynamic loading requires
  109. // us to register our own atexit handler to prevent double freeing.
  110. static AviSynthLibrary *avs_library = NULL;
  111. static int avs_atexit_called = 0;
  112.  
  113. // Linked list of AviSynthContexts. An atexit handler destroys this list.
  114. static AviSynthContext *avs_ctx_list = NULL;
  115.  
  116. static av_cold void avisynth_atexit_handler(void);
  117.  
  118. static av_cold int avisynth_load_library(void) {
  119.     avs_library = av_mallocz(sizeof(AviSynthLibrary));
  120.     if (!avs_library)
  121.         return AVERROR_UNKNOWN;
  122.  
  123.     avs_library->library = LoadLibrary(AVISYNTH_LIB);
  124.     if (!avs_library->library)
  125.         goto init_fail;
  126.  
  127. #define LOAD_AVS_FUNC(name, continue_on_fail) \
  128. { \
  129.     avs_library->name = (void*)GetProcAddress(avs_library->library, #name); \
  130.     if(!continue_on_fail && !avs_library->name) \
  131.         goto fail; \
  132. }
  133.     LOAD_AVS_FUNC(avs_bit_blt, 0);
  134.     LOAD_AVS_FUNC(avs_clip_get_error, 0);
  135.     LOAD_AVS_FUNC(avs_create_script_environment, 0);
  136.     LOAD_AVS_FUNC(avs_delete_script_environment, 0);
  137.     LOAD_AVS_FUNC(avs_get_audio, 0);
  138.     LOAD_AVS_FUNC(avs_get_error, 1); // New to AviSynth 2.6
  139.     LOAD_AVS_FUNC(avs_get_frame, 0);
  140.     LOAD_AVS_FUNC(avs_get_version, 0);
  141.     LOAD_AVS_FUNC(avs_get_video_info, 0);
  142.     LOAD_AVS_FUNC(avs_invoke, 0);
  143.     LOAD_AVS_FUNC(avs_release_clip, 0);
  144.     LOAD_AVS_FUNC(avs_release_value, 0);
  145.     LOAD_AVS_FUNC(avs_release_video_frame, 0);
  146.     LOAD_AVS_FUNC(avs_take_clip, 0);
  147. #undef LOAD_AVS_FUNC
  148.  
  149.     atexit(avisynth_atexit_handler);
  150.     return 0;
  151.  
  152. fail:
  153.     FreeLibrary(avs_library->library);
  154. init_fail:
  155.     av_freep(&avs_library);
  156.     return AVERROR_UNKNOWN;
  157. }
  158.  
  159. // Note that avisynth_context_create and avisynth_context_destroy
  160. // do not allocate or free the actual context! That is taken care of
  161. // by libavformat.
  162. static av_cold int avisynth_context_create(AVFormatContext *s) {
  163.     AviSynthContext *avs = (AviSynthContext *)s->priv_data;
  164.     int ret;
  165.  
  166.     if (!avs_library) {
  167.         if (ret = avisynth_load_library())
  168.             return ret;
  169.     }
  170.  
  171.     avs->env = avs_library->avs_create_script_environment(3);
  172.     if (avs_library->avs_get_error) {
  173.         const char *error = avs_library->avs_get_error(avs->env);
  174.         if (error) {
  175.             av_log(s, AV_LOG_ERROR, "%s\n", error);
  176.             return AVERROR_UNKNOWN;
  177.         }
  178.     }
  179.  
  180.     if (!avs_ctx_list) {
  181.         avs_ctx_list = avs;
  182.     } else {
  183.         avs->next = avs_ctx_list;
  184.         avs_ctx_list = avs;
  185.     }
  186.  
  187.     return 0;
  188. }
  189.  
  190. static av_cold void avisynth_context_destroy(AviSynthContext *avs) {
  191.     if (avs_atexit_called)
  192.        return;
  193.  
  194.     if (avs == avs_ctx_list) {
  195.         avs_ctx_list = avs->next;
  196.     } else {
  197.         AviSynthContext *prev = avs_ctx_list;
  198.         while (prev->next != avs)
  199.             prev = prev->next;
  200.         prev->next = avs->next;
  201.     }
  202.  
  203.     if (avs->clip) {
  204.         avs_library->avs_release_clip(avs->clip);
  205.         avs->clip = NULL;
  206.     }
  207.     if (avs->env) {
  208.         avs_library->avs_delete_script_environment(avs->env);
  209.         avs->env = NULL;
  210.     }
  211. }
  212.  
  213. static av_cold void avisynth_atexit_handler(void) {
  214.     AviSynthContext *avs = avs_ctx_list;
  215.  
  216.     while (avs) {
  217.         AviSynthContext *next = avs->next;
  218.         avisynth_context_destroy(avs);
  219.         avs = next;
  220.     }
  221.     FreeLibrary(avs_library->library);
  222.     av_freep(&avs_library);
  223.  
  224.     avs_atexit_called = 1;
  225. }
  226.  
  227. // Create AVStream from audio and video data.
  228. static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) {
  229.     AviSynthContext *avs = s->priv_data;
  230.     int planar = 0; // 0: packed, 1: YUV, 2: Y8
  231.  
  232.     st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
  233.     st->codec->codec_id = CODEC_ID_RAWVIDEO;
  234.     st->codec->width = avs->vi->width;
  235.     st->codec->height = avs->vi->height;
  236.  
  237.     st->time_base = (AVRational) {avs->vi->fps_denominator, avs->vi->fps_numerator};
  238.     st->avg_frame_rate = (AVRational) {avs->vi->fps_numerator, 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.  
  243.     switch (avs->vi->pixel_type) {
  244. #ifdef _WIN32
  245.     case AVS_CS_YV24:
  246.         st->codec->pix_fmt = AV_PIX_FMT_YUV444P;
  247.         planar = 1;
  248.         break;
  249.     case AVS_CS_YV16:
  250.         st->codec->pix_fmt = AV_PIX_FMT_YUV422P;
  251.         planar = 1;
  252.         break;
  253.     case AVS_CS_YV411:
  254.         st->codec->pix_fmt = AV_PIX_FMT_YUV411P;
  255.         planar = 1;
  256.         break;
  257.     case AVS_CS_Y8:
  258.         st->codec->pix_fmt = AV_PIX_FMT_GRAY8;
  259.         planar = 2;
  260.         break;
  261. #endif
  262.     case AVS_CS_BGR24:
  263.         st->codec->pix_fmt = AV_PIX_FMT_BGR24;
  264.         break;
  265.     case AVS_CS_BGR32:
  266.         st->codec->pix_fmt = AV_PIX_FMT_RGB32;
  267.         break;
  268.     case AVS_CS_YUY2:
  269.         st->codec->pix_fmt = AV_PIX_FMT_YUYV422;
  270.         break;
  271.     case AVS_CS_YV12:
  272.         st->codec->pix_fmt = AV_PIX_FMT_YUV420P;
  273.         planar = 1;
  274.         break;
  275.     case AVS_CS_I420: // Is this even used anywhere?
  276.         st->codec->pix_fmt = AV_PIX_FMT_YUV420P;
  277.         planar = 1;
  278.         break;
  279.     default:
  280.         av_log(s, AV_LOG_ERROR, "unknown AviSynth colorspace %d\n", avs->vi->pixel_type);
  281.         avs->error = 1;
  282.         return AVERROR_UNKNOWN;
  283.     }
  284.  
  285.     switch (planar) {
  286.     case 2: // Y8
  287.         avs->n_planes = 1;
  288.         avs->planes = avs_planes_grey;
  289.         break;
  290.     case 1: // YUV
  291.         avs->n_planes = 3;
  292.         avs->planes = avs_planes_yuv;
  293.         break;
  294.     default:
  295.         avs->n_planes = 1;
  296.         avs->planes = avs_planes_packed;
  297.     }
  298.     return 0;
  299. }
  300.  
  301. static int avisynth_create_stream_audio(AVFormatContext *s, AVStream *st) {
  302.     AviSynthContext *avs = s->priv_data;
  303.  
  304.     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
  305.     st->codec->sample_rate = avs->vi->audio_samples_per_second;
  306.     st->codec->channels = avs->vi->nchannels;
  307.     st->time_base = (AVRational) {1, avs->vi->audio_samples_per_second};
  308.  
  309.     switch (avs->vi->sample_type) {
  310.     case AVS_SAMPLE_INT8:
  311.         st->codec->codec_id = CODEC_ID_PCM_U8;
  312.         break;
  313.     case AVS_SAMPLE_INT16:
  314.         st->codec->codec_id = CODEC_ID_PCM_S16LE;
  315.         break;
  316.     case AVS_SAMPLE_INT24:
  317.         st->codec->codec_id = CODEC_ID_PCM_S24LE;
  318.         break;
  319.     case AVS_SAMPLE_INT32:
  320.         st->codec->codec_id = CODEC_ID_PCM_S32LE;
  321.         break;
  322.     case AVS_SAMPLE_FLOAT:
  323.         st->codec->codec_id = CODEC_ID_PCM_F32LE;
  324.         break;
  325.     default:
  326.         av_log(s, AV_LOG_ERROR, "unknown AviSynth sample type %d\n", avs->vi->sample_type);
  327.         avs->error = 1;
  328.         return AVERROR_UNKNOWN;
  329.     }
  330.     return 0;
  331. }
  332.  
  333. static int avisynth_create_stream(AVFormatContext *s) {
  334.     AviSynthContext *avs = s->priv_data;
  335.     AVStream *st;
  336.     int ret;
  337.     int id = 0;
  338.  
  339.     if (avs_has_video(avs->vi)) {
  340.         st = avformat_new_stream(s, NULL);
  341.         if (!st)
  342.             return AVERROR_UNKNOWN;
  343.         st->id = id++;
  344.         if (ret = avisynth_create_stream_video(s, st))
  345.             return ret;
  346.     }
  347.     if (avs_has_audio(avs->vi)) {
  348.         st = avformat_new_stream(s, NULL);
  349.         if (!st)
  350.             return AVERROR_UNKNOWN;
  351.         st->id = id++;
  352.         if (ret = avisynth_create_stream_audio(s, st))
  353.             return ret;
  354.     }
  355.     return 0;
  356. }
  357.  
  358. static int avisynth_open_file(AVFormatContext *s) {
  359.     AviSynthContext *avs = (AviSynthContext *)s->priv_data;
  360.     AVS_Value arg, val;
  361.     int ret;
  362. #ifdef _WIN32
  363.     char filename_ansi[MAX_PATH * 4];
  364.     wchar_t filename_wc[MAX_PATH * 4];
  365. #endif
  366.  
  367.     if (ret = avisynth_context_create(s))
  368.         return ret;
  369.  
  370. #ifdef _WIN32
  371.     // Convert UTF-8 to ANSI code page
  372.     MultiByteToWideChar(CP_UTF8, 0, s->filename, -1, filename_wc, MAX_PATH * 4);
  373.     WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wc, -1, filename_ansi, MAX_PATH * 4, NULL, NULL);
  374.     arg = avs_new_value_string(filename_ansi);
  375. #else
  376.     arg = avs_new_value_string(s->filename);
  377. #endif
  378.     val = avs_library->avs_invoke(avs->env, "Import", arg, 0);
  379.     if (avs_is_error(val)) {
  380.         av_log(s, AV_LOG_ERROR, "%s\n", avs_as_error(val));
  381.         ret = AVERROR_UNKNOWN;
  382.         goto fail;
  383.     }
  384.     if (!avs_is_clip(val)) {
  385.         av_log(s, AV_LOG_ERROR, "%s\n", "AviSynth script did not return a clip");
  386.         ret = AVERROR_UNKNOWN;
  387.         goto fail;
  388.     }
  389.  
  390.     avs->clip = avs_library->avs_take_clip(val, avs->env);
  391.     avs->vi = avs_library->avs_get_video_info(avs->clip);
  392.  
  393.     // Release the AVS_Value as it will go out of scope.
  394.     avs_library->avs_release_value(val);
  395.  
  396.     if (ret = avisynth_create_stream(s))
  397.         goto fail;
  398.  
  399.     return 0;
  400.  
  401. fail:
  402.     avisynth_context_destroy(avs);
  403.     return ret;
  404. }
  405.  
  406. static void avisynth_next_stream(AVFormatContext *s, AVStream **st, AVPacket *pkt, int *discard) {
  407.     AviSynthContext *avs = s->priv_data;
  408.  
  409.     pkt->stream_index = avs->curr_stream++;
  410.     avs->curr_stream %= s->nb_streams;
  411.  
  412.     *st = s->streams[pkt->stream_index];
  413.     if ((*st)->discard == AVDISCARD_ALL)
  414.         *discard = 1;
  415.     else
  416.         *discard = 0;
  417.  
  418.     return;
  419. }
  420.  
  421. // Copy AviSynth clip data into an AVPacket.
  422. static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, int discard) {
  423.     AviSynthContext *avs = s->priv_data;
  424.     AVS_VideoFrame *frame;
  425.     unsigned char *dst_p;
  426.     const unsigned char *src_p;
  427.     int n, i, plane, rowsize, planeheight, pitch, bits;
  428.     const char *error;
  429.  
  430.     if (avs->curr_frame >= avs->vi->num_frames)
  431.         return AVERROR_EOF;
  432.  
  433.     // This must happen even if the stream is discarded to prevent desync.
  434.     n = avs->curr_frame++;
  435.     if (discard)
  436.         return 0;
  437.  
  438.     pkt->pts = n;
  439.     pkt->dts = n;
  440.     pkt->duration = 1;
  441.  
  442.     // Define the bpp values for the new AviSynth 2.6 colorspaces
  443.     if (avs_is_yv24(avs->vi)) {
  444.         bits = 24;
  445.     } else if (avs_is_yv16(avs->vi)) {
  446.         bits = 16;
  447.     } else if (avs_is_yv411(avs->vi)) {
  448.         bits = 12;
  449.     } else if (avs_is_y8(avs->vi)) {
  450.         bits = 8;
  451.     } else {
  452.         bits = avs_bits_per_pixel(avs->vi);
  453.     }
  454.  
  455.     // Without cast to int64_t, calculation overflows at about 9k x 9k resolution.
  456.     pkt->size = (((int64_t)avs->vi->width * (int64_t)avs->vi->height) * bits) / 8;
  457.     if (!pkt->size)
  458.         return AVERROR_UNKNOWN;
  459.     pkt->data = av_malloc(pkt->size);
  460.     if (!pkt->data)
  461.         return AVERROR_UNKNOWN;
  462.  
  463.     frame = avs_library->avs_get_frame(avs->clip, n);
  464.     error = avs_library->avs_clip_get_error(avs->clip);
  465.     if (error) {
  466.         av_log(s, AV_LOG_ERROR, "%s\n", error);
  467.         avs->error = 1;
  468.         av_freep(&pkt->data);
  469.         return AVERROR_UNKNOWN;
  470.     }
  471.  
  472.     dst_p = pkt->data;
  473.     for (i = 0; i < avs->n_planes; i++) {
  474.         plane = avs->planes[i];
  475.         src_p = avs_get_read_ptr_p(frame, plane);
  476.         pitch = avs_get_pitch_p(frame, plane);
  477.  
  478. #ifdef _WIN32
  479.         if (avs_library->avs_get_version(avs->clip) == 3) {
  480.             rowsize = avs_get_row_size_p_25(frame, plane);
  481.             planeheight = avs_get_height_p_25(frame, plane);
  482.         } else {
  483.             rowsize = avs_get_row_size_p(frame, plane);
  484.             planeheight = avs_get_height_p(frame, plane);
  485.         }
  486. #else
  487.         rowsize = avs_get_row_size_p(frame, plane);
  488.         planeheight = avs_get_height_p(frame, plane);
  489. #endif
  490.  
  491.         // Flip RGB video.
  492.         if (avs_is_rgb24(avs->vi) || avs_is_rgb(avs->vi)) {
  493.             src_p = src_p + (planeheight - 1) * pitch;
  494.             pitch = -pitch;
  495.         }
  496.  
  497.         avs_library->avs_bit_blt(avs->env, dst_p, rowsize, src_p, pitch, rowsize, planeheight);
  498.         dst_p += rowsize * planeheight;
  499.     }
  500.  
  501.     avs_library->avs_release_video_frame(frame);
  502.     return 0;
  503. }
  504.  
  505. static int avisynth_read_packet_audio(AVFormatContext *s, AVPacket *pkt, int discard) {
  506.     AviSynthContext *avs = s->priv_data;
  507.     AVRational fps, samplerate;
  508.     int samples;
  509.     int64_t n;
  510.     const char *error;
  511.  
  512.     if (avs->curr_sample >= avs->vi->num_audio_samples)
  513.         return AVERROR_EOF;
  514.  
  515.     fps.num = avs->vi->fps_numerator;
  516.     fps.den = avs->vi->fps_denominator;
  517.     samplerate.num = avs->vi->audio_samples_per_second;
  518.     samplerate.den = 1;
  519.  
  520.     if (avs_has_video(avs->vi)) {
  521.         if (avs->curr_frame < avs->vi->num_frames)
  522.             samples = av_rescale_q(avs->curr_frame, samplerate, fps) - avs->curr_sample;
  523.         else
  524.             samples = av_rescale_q(1, samplerate, fps);
  525.     } else {
  526.         samples = 1000;
  527.     }
  528.  
  529.     // After seeking, audio may catch up with video.
  530.     if (samples <= 0) {
  531.         pkt->size = 0;
  532.         pkt->data = NULL;
  533.         return 0;
  534.     }
  535.  
  536.     if (avs->curr_sample + samples > avs->vi->num_audio_samples)
  537.         samples = avs->vi->num_audio_samples - avs->curr_sample;
  538.  
  539.     // This must happen even if the stream is discarded to prevent desync.
  540.     n = avs->curr_sample;
  541.     avs->curr_sample += samples;
  542.     if (discard)
  543.         return 0;
  544.  
  545.     pkt->pts = n;
  546.     pkt->dts = n;
  547.     pkt->duration = samples;
  548.  
  549.     pkt->size = avs_bytes_per_channel_sample(avs->vi) * samples * avs->vi->nchannels;
  550.     if (!pkt->size)
  551.         return AVERROR_UNKNOWN;
  552.     pkt->data = av_malloc(pkt->size);
  553.     if (!pkt->data)
  554.         return AVERROR_UNKNOWN;
  555.  
  556.     avs_library->avs_get_audio(avs->clip, pkt->data, n, samples);
  557.     error = avs_library->avs_clip_get_error(avs->clip);
  558.     if (error) {
  559.         av_log(s, AV_LOG_ERROR, "%s\n", error);
  560.         avs->error = 1;
  561.         av_freep(&pkt->data);
  562.         return AVERROR_UNKNOWN;
  563.     }
  564.     return 0;
  565. }
  566.  
  567. static av_cold int avisynth_read_header(AVFormatContext *s) {
  568.     int ret;
  569.  
  570.     // Calling library must implement a lock for thread-safe opens.
  571.     if (ret = avpriv_lock_avformat())
  572.         return ret;
  573.  
  574.     if (ret = avisynth_open_file(s)) {
  575.         avpriv_unlock_avformat();
  576.         return ret;
  577.     }
  578.  
  579.     avpriv_unlock_avformat();
  580.     return 0;
  581. }
  582.  
  583. static int avisynth_read_packet(AVFormatContext *s, AVPacket *pkt) {
  584.     AviSynthContext *avs = s->priv_data;
  585.     AVStream *st;
  586.     int discard = 0;
  587.     int ret;
  588.  
  589.     if (avs->error)
  590.         return AVERROR_UNKNOWN;
  591.  
  592.     pkt->destruct = av_destruct_packet;
  593.  
  594.     // If either stream reaches EOF, try to read the other one before giving up.
  595.     avisynth_next_stream(s, &st, pkt, &discard);
  596.     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
  597.         ret = avisynth_read_packet_video(s, pkt, discard);
  598.         if (ret == AVERROR_EOF && avs_has_audio(avs->vi)) {
  599.             avisynth_next_stream(s, &st, pkt, &discard);
  600.             return avisynth_read_packet_audio(s, pkt, discard);
  601.         }
  602.         return ret;
  603.     } else {
  604.         ret = avisynth_read_packet_audio(s, pkt, discard);
  605.         if (ret == AVERROR_EOF && avs_has_video(avs->vi)) {
  606.             avisynth_next_stream(s, &st, pkt, &discard);
  607.             return avisynth_read_packet_video(s, pkt, discard);
  608.         }
  609.         return ret;
  610.     }
  611. }
  612.  
  613. static av_cold int avisynth_read_close(AVFormatContext *s) {
  614.     if (avpriv_lock_avformat())
  615.         return AVERROR_UNKNOWN;
  616.  
  617.     avisynth_context_destroy(s->priv_data);
  618.     avpriv_unlock_avformat();
  619.     return 0;
  620. }
  621.  
  622. static int avisynth_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) {
  623.     AviSynthContext *avs = s->priv_data;
  624.     AVStream *st;
  625.     AVRational fps, samplerate;
  626.  
  627.     if (avs->error)
  628.         return AVERROR_UNKNOWN;
  629.  
  630.     fps = (AVRational) {avs->vi->fps_numerator, avs->vi->fps_denominator};
  631.     samplerate = (AVRational) {avs->vi->audio_samples_per_second, 1};
  632.  
  633.     st = s->streams[stream_index];
  634.     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
  635.         // AviSynth frame counts are signed int.
  636.         if ((timestamp >= avs->vi->num_frames) || (timestamp > INT_MAX) || (timestamp < 0))
  637.             return AVERROR_EOF;
  638.         avs->curr_frame = timestamp;
  639.         if (avs_has_audio(avs->vi))
  640.             avs->curr_sample = av_rescale_q(timestamp, samplerate, fps);
  641.     } else {
  642.         if ((timestamp >= avs->vi->num_audio_samples) || (timestamp < 0))
  643.             return AVERROR_EOF;
  644.         // Force frame granularity for seeking.
  645.         if (avs_has_video(avs->vi)) {
  646.             avs->curr_frame = av_rescale_q(timestamp, fps, samplerate);
  647.             avs->curr_sample = av_rescale_q(avs->curr_frame, samplerate, fps);
  648.         } else {
  649.             avs->curr_sample = timestamp;
  650.         }
  651.     }
  652.  
  653.     return 0;
  654. }
  655.  
  656. AVInputFormat ff_avisynth_demuxer = {
  657.     .name           = "avisynth",
  658.     .long_name      = NULL_IF_CONFIG_SMALL("AviSynth script"),
  659.     .priv_data_size = sizeof(AviSynthContext),
  660.     .read_header    = avisynth_read_header,
  661.     .read_packet    = avisynth_read_packet,
  662.     .read_close     = avisynth_read_close,
  663.     .read_seek      = avisynth_read_seek,
  664.     .extensions     = "avs",
  665. };
  666.