[FFmpeg-devel] [PATCH v3 1/2] libavformat/vapoursynth: Update to API version 4, load library at runtime

Ramiro Polla ramiro.polla at gmail.com
Sun Jul 28 16:09:00 EEST 2024


On 2024-07-23 16:51, Stefan Oltmanns via ffmpeg-devel wrote:
> this is revised patch, this is the first part that just updates to the
> API v4 of VapourSynth.
> 
> Changes in API v4:
> -All functions previously in header are now part of the "vssapi" object
> -Renames of different types and functions
> -YCoCg is not treated as different format to YUV anymore
> -Some pointers to arrays are now arrays inside a struct.


> From 164a440ffbb5951ca38bfff56e7b62bd677d1f52 Mon Sep 17 00:00:00 2001
> From: Stefan Oltmanns <stefan-oltmanns at gmx.net>
> Date: Tue, 23 Jul 2024 16:15:36 +0200
> Subject: [PATCH 1/2] avformat/vapoursynth: Update to API version 4
> 
> Signed-off-by: Stefan Oltmanns <stefan-oltmanns at gmx.net>
> ---
>  configure                 |  2 +-
>  libavformat/vapoursynth.c | 84 +++++++++++++++++++++------------------
>  2 files changed, 46 insertions(+), 40 deletions(-)
> 
> diff --git a/configure b/configure
> index f6f5c29fea..c50b5ad4b4 100755
> --- a/configure
> +++ b/configure
> @@ -7085,7 +7085,7 @@ enabled rkmpp             && { require_pkg_config rkmpp rockchip_mpp  rockchip/r
>                                 { enabled libdrm ||
>                                   die "ERROR: rkmpp requires --enable-libdrm"; }
>                               }
> -enabled vapoursynth       && require_pkg_config vapoursynth "vapoursynth-script >= 42" VSScript.h vsscript_init
> +enabled vapoursynth       && require_pkg_config vapoursynth "vapoursynth-script >= 55" VSScript4.h getVSScriptAPI
>  
>  
>  if enabled gcrypt; then
> diff --git a/libavformat/vapoursynth.c b/libavformat/vapoursynth.c
> index 8a2519e19a..ce15f68180 100644
> --- a/libavformat/vapoursynth.c
> +++ b/libavformat/vapoursynth.c
> @@ -25,8 +25,7 @@
>  
>  #include <limits.h>
>  
> -#include <VapourSynth.h>
> -#include <VSScript.h>
> +#include <VSScript4.h>
>  
>  #include "libavutil/avassert.h"
>  #include "libavutil/avstring.h"
> @@ -41,6 +40,7 @@
>  #include "internal.h"
>  
>  struct VSState {
> +    const VSSCRIPTAPI *vssapi;
>      VSScript *vss;
>  };
>  
> @@ -49,10 +49,10 @@ typedef struct VSContext {
>  
>      AVBufferRef *vss_state;
>  
> +    const VSSCRIPTAPI *vssapi;
>      const VSAPI *vsapi;
> -    VSCore *vscore;
>  
> -    VSNodeRef *outnode;
> +    VSNode *outnode;
>      int is_cfr;
>      int current_frame;
>  
> @@ -75,8 +75,7 @@ static void free_vss_state(void *opaque, uint8_t *data)
>      struct VSState *vss = opaque;
>  
>      if (vss->vss) {
> -        vsscript_freeScript(vss->vss);
> -        vsscript_finalize();
> +        vss->vssapi->freeScript(vss->vss);
>      }
>  }
>  
> @@ -90,7 +89,6 @@ static av_cold int read_close_vs(AVFormatContext *s)
>      av_buffer_unref(&vs->vss_state);
>  
>      vs->vsapi = NULL;
> -    vs->vscore = NULL;
>      vs->outnode = NULL;
>  
>      return 0;
> @@ -106,7 +104,7 @@ static av_cold int is_native_endian(enum AVPixelFormat pixfmt)
>      return pd && (!!HAVE_BIGENDIAN == !!(pd->flags & AV_PIX_FMT_FLAG_BE));
>  }
>  
> -static av_cold enum AVPixelFormat match_pixfmt(const VSFormat *vsf, int c_order[4])
> +static av_cold enum AVPixelFormat match_pixfmt(const VSVideoFormat *vsf, int c_order[4])
>  {
>      static const int yuv_order[4] = {0, 1, 2, 0};
>      static const int rgb_order[4] = {1, 2, 0, 0};
> @@ -128,13 +126,12 @@ static av_cold enum AVPixelFormat match_pixfmt(const VSFormat *vsf, int c_order[
>              pd->log2_chroma_h != vsf->subSamplingH)
>              continue;
>  
> -        is_rgb = vsf->colorFamily == cmRGB;
> +        is_rgb = vsf->colorFamily == cfRGB;
>          if (is_rgb != !!(pd->flags & AV_PIX_FMT_FLAG_RGB))
>              continue;
>  
> -        is_yuv = vsf->colorFamily == cmYUV ||
> -                 vsf->colorFamily == cmYCoCg ||
> -                 vsf->colorFamily == cmGray;
> +        is_yuv = vsf->colorFamily == cfYUV ||
> +                 vsf->colorFamily == cfGray;
>          if (!is_rgb && !is_yuv)
>              continue;
>  
> @@ -176,15 +173,30 @@ static av_cold int read_header_vs(AVFormatContext *s)
>      int64_t sz = avio_size(pb);
>      char *buf = NULL;
>      char dummy;
> +    char vsfmt[32];
>      const VSVideoInfo *info;
>      struct VSState *vss_state;
>      int err = 0;
>  
> +    if (!(vs->vssapi = getVSScriptAPI(VSSCRIPT_API_VERSION))) {
> +        av_log(s, AV_LOG_ERROR, "Failed to initialize VSScript (possibly PYTHONPATH not set).\n");
> +        err = AVERROR_EXTERNAL;
> +        goto done;
> +    }
> +
> +    if (!(vs->vsapi = vs->vssapi->getVSAPI(VAPOURSYNTH_API_VERSION))) {
> +        av_log(s, AV_LOG_ERROR, "Could not get VSAPI. "
> +                                "Check VapourSynth installation.\n");
> +        err = AVERROR_EXTERNAL;
> +        goto done;
> +    }
> +
>      vss_state = av_mallocz(sizeof(*vss_state));
>      if (!vss_state) {
>          err = AVERROR(ENOMEM);
>          goto done;
>      }
> +    vss_state->vssapi = vs->vssapi;
>  
>      vs->vss_state = av_buffer_create(NULL, 0, free_vss_state, vss_state, 0);
>      if (!vs->vss_state) {
> @@ -193,16 +205,9 @@ static av_cold int read_header_vs(AVFormatContext *s)
>          goto done;
>      }
>  
> -    if (!vsscript_init()) {
> -        av_log(s, AV_LOG_ERROR, "Failed to initialize VSScript (possibly PYTHONPATH not set).\n");
> -        err = AVERROR_EXTERNAL;
> -        goto done;
> -    }
> -
> -    if (vsscript_createScript(&vss_state->vss)) {
> +    if (!(vss_state->vss = vs->vssapi->createScript(NULL))) {
>          av_log(s, AV_LOG_ERROR, "Failed to create script instance.\n");
>          err = AVERROR_EXTERNAL;
> -        vsscript_finalize();
>          goto done;
>      }
>  
> @@ -235,17 +240,14 @@ static av_cold int read_header_vs(AVFormatContext *s)
>      }
>  
>      buf[sz] = '\0';
> -    if (vsscript_evaluateScript(&vss_state->vss, buf, s->url, 0)) {
> -        const char *msg = vsscript_getError(vss_state->vss);
> +    if (vs->vssapi->evaluateBuffer(vss_state->vss, buf, s->url)) {
> +        const char *msg = vs->vssapi->getError(vss_state->vss);
>          av_log(s, AV_LOG_ERROR, "Failed to parse script: %s\n", msg ? msg : "(unknown)");
>          err = AVERROR_EXTERNAL;
>          goto done;
>      }
>  
> -    vs->vsapi = vsscript_getVSApi();
> -    vs->vscore = vsscript_getCore(vss_state->vss);
> -
> -    vs->outnode = vsscript_getOutput(vss_state->vss, 0);
> +    vs->outnode = vs->vssapi->getOutputNode(vss_state->vss, 0);
>      if (!vs->outnode) {
>          av_log(s, AV_LOG_ERROR, "Could not get script output node.\n");
>          err = AVERROR_EXTERNAL;
> @@ -260,7 +262,7 @@ static av_cold int read_header_vs(AVFormatContext *s)
>  
>      info = vs->vsapi->getVideoInfo(vs->outnode);
>  
> -    if (!info->format || !info->width || !info->height) {
> +    if (!info->format.colorFamily || !info->width || !info->height) {
>          av_log(s, AV_LOG_ERROR, "Non-constant input format not supported.\n");
>          err = AVERROR_PATCHWELCOME;
>          goto done;
> @@ -280,18 +282,22 @@ static av_cold int read_header_vs(AVFormatContext *s)
>      st->codecpar->codec_id = AV_CODEC_ID_WRAPPED_AVFRAME;
>      st->codecpar->width = info->width;
>      st->codecpar->height = info->height;
> -    st->codecpar->format = match_pixfmt(info->format, vs->c_order);
> +    st->codecpar->format = match_pixfmt(&info->format, vs->c_order);
>  
>      if (st->codecpar->format == AV_PIX_FMT_NONE) {
> -        av_log(s, AV_LOG_ERROR, "Unsupported VS pixel format %s\n", info->format->name);
> +        if(vs->vsapi->getVideoFormatName(&info->format, vsfmt))
> +            av_log(s, AV_LOG_ERROR, "Unsupported VS pixel format %s\n", vsfmt);
> +        else
> +            av_log(s, AV_LOG_ERROR, "Unsupported VS pixel format\n");
>          err = AVERROR_EXTERNAL;
>          goto done;
>      }
> -    av_log(s, AV_LOG_VERBOSE, "VS format %s -> pixfmt %s\n", info->format->name,
> -           av_get_pix_fmt_name(st->codecpar->format));
> -
> -    if (info->format->colorFamily == cmYCoCg)
> -        st->codecpar->color_space = AVCOL_SPC_YCGCO;
> +    if (vs->vsapi->getVideoFormatName(&info->format, vsfmt))
> +        av_log(s, AV_LOG_VERBOSE, "VS format %s -> pixfmt %s\n",
> +               vsfmt, av_get_pix_fmt_name(st->codecpar->format));
> +    else
> +        av_log(s, AV_LOG_VERBOSE, "VS format -> pixfmt %s\n",
> +               av_get_pix_fmt_name(st->codecpar->format));

Could you change this to have a single call go av_log()? Possibly using 
a %s with a string for the unknown format. Same thing for the other 
av_log() above.

[...]

Also could you give us a very minimal test script to test this?

Regards,
Ramiro


More information about the ffmpeg-devel mailing list