Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --- a/libavformat/vapoursynth.c
- +++ b/libavformat/vapoursynth.c
- @@ -23,243 +23,157 @@
- * Synthesizes vapour (?)
- */
- -#include <limits.h>
- +#include <stdatomic.h>
- #include <VapourSynth.h>
- #include <VSScript.h>
- +#include <VSHelper.h>
- -#include "libavutil/avassert.h"
- -#include "libavutil/avstring.h"
- -#include "libavutil/eval.h"
- -#include "libavutil/imgutils.h"
- +#include "libavcodec/internal.h"
- +#include "libavutil/internal.h"
- #include "libavutil/opt.h"
- #include "libavutil/pixdesc.h"
- +#include "libavutil/time.h"
- #include "avformat.h"
- #include "internal.h"
- -struct VSState {
- - VSScript *vss;
- -};
- -
- typedef struct VSContext {
- const AVClass *class;
- -
- - AVBufferRef *vss_state;
- -
- const VSAPI *vsapi;
- - VSCore *vscore;
- -
- VSNodeRef *outnode;
- + VSScript *script;
- + int ncpu;
- int is_cfr;
- int current_frame;
- -
- - int c_order[4];
- -
- - /* options */
- - int64_t max_script_size;
- + int async_pending;
- } VSContext;
- -#define OFFSET(x) offsetof(VSContext, x)
- -#define A AV_OPT_FLAG_AUDIO_PARAM
- -#define D AV_OPT_FLAG_DECODING_PARAM
- static const AVOption options[] = {
- - {"max_script_size", "set max file size supported (in bytes)", OFFSET(max_script_size), AV_OPT_TYPE_INT64, {.i64 = 1 * 1024 * 1024}, 0, SIZE_MAX - 1, A|D},
- {NULL}
- };
- -static void free_vss_state(void *opaque, uint8_t *data)
- +static void async_callback(void *user_data, const VSFrameRef *f, int n, VSNodeRef *outnode, const char *error_msg)
- {
- - struct VSState *vss = opaque;
- + AVFormatContext *s = user_data;
- + VSContext *vs = s->priv_data;
- - if (vss->vss) {
- - vsscript_freeScript(vss->vss);
- - vsscript_finalize();
- - }
- + if (!f)
- + av_log(s, AV_LOG_WARNING, "Async frame request failed: %s\n", error_msg);
- +
- + vs->vsapi->freeFrame(f);
- + atomic_fetch_sub(&vs->async_pending, 1);
- }
- static av_cold int read_close_vs(AVFormatContext *s)
- {
- VSContext *vs = s->priv_data;
- - if (vs->outnode)
- - vs->vsapi->freeNode(vs->outnode);
- -
- - av_buffer_unref(&vs->vss_state);
- -
- - vs->vsapi = NULL;
- - vs->vscore = NULL;
- - vs->outnode = NULL;
- -
- + /* Wait for any async requests to complete. */
- + while (atomic_load(&vs->async_pending))
- + av_usleep(1000);
- +
- + vs->vsapi->freeNode(vs->outnode);
- + vsscript_freeScript(vs->script);
- + vsscript_finalize();
- return 0;
- }
- -static av_cold int is_native_endian(enum AVPixelFormat pixfmt)
- +static av_cold int map_vsformat(AVFormatContext *s, AVStream *st, const VSFormat *vsformat)
- {
- - enum AVPixelFormat other = av_pix_fmt_swap_endianness(pixfmt);
- - const AVPixFmtDescriptor *pd;
- - if (other == AV_PIX_FMT_NONE || other == pixfmt)
- - return 1; // not affected by byte order
- - pd = av_pix_fmt_desc_get(pixfmt);
- - return pd && (!!HAVE_BIGENDIAN == !!(pd->flags & AV_PIX_FMT_FLAG_BE));
- -}
- + if (vsformat->subSamplingW > 2 || vsformat->subSamplingH > 2)
- + return AV_PIX_FMT_NONE;
- -static av_cold enum AVPixelFormat match_pixfmt(const VSFormat *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};
- - const AVPixFmtDescriptor *pd;
- -
- - for (pd = av_pix_fmt_desc_next(NULL); pd; pd = av_pix_fmt_desc_next(pd)) {
- - int is_rgb, is_yuv, i;
- - const int *order;
- - enum AVPixelFormat pixfmt;
- -
- - pixfmt = av_pix_fmt_desc_get_id(pd);
- -
- - if (pd->flags & (AV_PIX_FMT_FLAG_BAYER | AV_PIX_FMT_FLAG_ALPHA |
- - AV_PIX_FMT_FLAG_HWACCEL | AV_PIX_FMT_FLAG_BITSTREAM))
- - continue;
- -
- - if (pd->log2_chroma_w != vsf->subSamplingW ||
- - pd->log2_chroma_h != vsf->subSamplingH)
- - continue;
- -
- - is_rgb = vsf->colorFamily == cmRGB;
- - if (is_rgb != !!(pd->flags & AV_PIX_FMT_FLAG_RGB))
- - continue;
- -
- - is_yuv = vsf->colorFamily == cmYUV ||
- - vsf->colorFamily == cmYCoCg ||
- - vsf->colorFamily == cmGray;
- - if (!is_rgb && !is_yuv)
- - continue;
- -
- - if (vsf->sampleType != ((pd->flags & AV_PIX_FMT_FLAG_FLOAT) ? stFloat : stInteger))
- - continue;
- -
- - if (av_pix_fmt_count_planes(pixfmt) != vsf->numPlanes)
- - continue;
- -
- - if (strncmp(pd->name, "xyz", 3) == 0)
- - continue;
- -
- - if (!is_native_endian(pixfmt))
- - continue;
- -
- - order = is_yuv ? yuv_order : rgb_order;
- -
- - for (i = 0; i < pd->nb_components; i++) {
- - const AVComponentDescriptor *c = &pd->comp[i];
- - if (order[c->plane] != i ||
- - c->offset != 0 || c->shift != 0 ||
- - c->step != vsf->bytesPerSample ||
- - c->depth != vsf->bitsPerSample)
- - goto cont;
- + switch (vsformat->colorFamily) {
- + case cmYUV:
- + case cmYCoCg:
- + switch ((vsformat->subSamplingW << 2) | vsformat->subSamplingH) {
- + case ((1 << 2) | 1): /* 4:2:0 */
- + switch (vsformat->bitsPerSample) {
- + case 8: return AV_PIX_FMT_YUV420P;
- + case 9: return AV_PIX_FMT_YUV420P9;
- + case 10: return AV_PIX_FMT_YUV420P10;
- + case 12: return AV_PIX_FMT_YUV420P12;
- + case 14: return AV_PIX_FMT_YUV420P14;
- + case 16: return AV_PIX_FMT_YUV420P16;
- + default: return AV_PIX_FMT_NONE;
- + }
- + case ((0 << 2) | 0): /* 4:4:4 */
- + switch (vsformat->bitsPerSample) {
- + case 8: return AV_PIX_FMT_YUV444P;
- + case 9: return AV_PIX_FMT_YUV444P9;
- + case 10: return AV_PIX_FMT_YUV444P10;
- + case 12: return AV_PIX_FMT_YUV444P12;
- + case 14: return AV_PIX_FMT_YUV444P14;
- + case 16: return AV_PIX_FMT_YUV444P16;
- + default: return AV_PIX_FMT_NONE;
- + }
- + case ((1 << 2) | 0): /* 4:2:2 */
- + switch (vsformat->bitsPerSample) {
- + case 8: return AV_PIX_FMT_YUV422P;
- + case 9: return AV_PIX_FMT_YUV422P9;
- + case 10: return AV_PIX_FMT_YUV422P10;
- + case 12: return AV_PIX_FMT_YUV422P12;
- + case 14: return AV_PIX_FMT_YUV422P14;
- + case 16: return AV_PIX_FMT_YUV422P16;
- + default: return AV_PIX_FMT_NONE;
- + }
- + case ((0 << 2) | 1): /* 4:4:0 */
- + switch (vsformat->bitsPerSample) {
- + case 8: return AV_PIX_FMT_YUV440P;
- + case 10: return AV_PIX_FMT_YUV440P10;
- + case 12: return AV_PIX_FMT_YUV440P12;
- + default: return AV_PIX_FMT_NONE;
- + }
- + case ((2 << 2) | 0): /* 4:1:1 */
- + return vsformat->bitsPerSample == 8 ? AV_PIX_FMT_YUV411P : AV_PIX_FMT_NONE;
- + case ((2 << 2) | 2): /* 4:1:0 */
- + return vsformat->bitsPerSample == 8 ? AV_PIX_FMT_YUV410P : AV_PIX_FMT_NONE;
- }
- -
- - // Use it.
- - memcpy(c_order, order, sizeof(int[4]));
- - return pixfmt;
- -
- - cont: ;
- + case cmRGB:
- + switch (vsformat->bitsPerSample) {
- + case 8: return AV_PIX_FMT_GBRP;
- + case 9: return AV_PIX_FMT_GBRP9;
- + case 10: return AV_PIX_FMT_GBRP10;
- + case 12: return AV_PIX_FMT_GBRP12;
- + case 14: return AV_PIX_FMT_GBRP14;
- + case 16: return AV_PIX_FMT_GBRP16;
- + case 32: return AV_PIX_FMT_GBRPF32;
- + default: return AV_PIX_FMT_NONE;
- + }
- + case cmGray:
- + switch (vsformat->bitsPerSample) {
- + case 8: return AV_PIX_FMT_GRAY8;
- + case 9: return AV_PIX_FMT_GRAY9;
- + case 10: return AV_PIX_FMT_GRAY10;
- + case 12: return AV_PIX_FMT_GRAY12;
- + case 14: return AV_PIX_FMT_GRAY14;
- + case 16: return AV_PIX_FMT_GRAY16;
- + case 32: return AV_PIX_FMT_GRAYF32;
- + default: return AV_PIX_FMT_NONE;
- + }
- + case cmCompat:
- + switch (vsformat->id) {
- + case pfCompatBGR32: return AV_PIX_FMT_RGB32;
- + case pfCompatYUY2: return AV_PIX_FMT_YUYV422;
- + default: return AV_PIX_FMT_NONE;
- + }
- + default:
- + return AV_PIX_FMT_NONE;
- }
- -
- - return AV_PIX_FMT_NONE;
- }
- -static av_cold int read_header_vs(AVFormatContext *s)
- +static av_cold int create_video_stream(AVFormatContext *s)
- {
- AVStream *st;
- - AVIOContext *pb = s->pb;
- VSContext *vs = s->priv_data;
- - int64_t sz = avio_size(pb);
- - char *buf = NULL;
- - char dummy;
- const VSVideoInfo *info;
- - struct VSState *vss_state;
- int err = 0;
- - vss_state = av_mallocz(sizeof(*vss_state));
- - if (!vss_state) {
- - err = AVERROR(ENOMEM);
- - goto done;
- - }
- -
- - vs->vss_state = av_buffer_create(NULL, 0, free_vss_state, vss_state, 0);
- - if (!vs->vss_state) {
- - err = AVERROR(ENOMEM);
- - av_free(vss_state);
- - 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)) {
- - av_log(s, AV_LOG_ERROR, "Failed to create script instance.\n");
- - err = AVERROR_EXTERNAL;
- - vsscript_finalize();
- - goto done;
- - }
- -
- - if (sz < 0 || sz > vs->max_script_size) {
- - if (sz < 0)
- - av_log(s, AV_LOG_WARNING, "Could not determine file size\n");
- - sz = vs->max_script_size;
- - }
- -
- - buf = av_malloc(sz + 1);
- - if (!buf) {
- - err = AVERROR(ENOMEM);
- - goto done;
- - }
- - sz = avio_read(pb, buf, sz);
- -
- - if (sz < 0) {
- - av_log(s, AV_LOG_ERROR, "Could not read script.\n");
- - err = sz;
- - goto done;
- - }
- -
- - // Data left means our buffer (the max_script_size option) is too small
- - if (avio_read(pb, &dummy, 1) == 1) {
- - av_log(s, AV_LOG_ERROR, "File size is larger than max_script_size option "
- - "value %"PRIi64", consider increasing the max_script_size option\n",
- - vs->max_script_size);
- - err = AVERROR_BUFFER_TOO_SMALL;
- - goto done;
- - }
- -
- - buf[sz] = '\0';
- - if (vsscript_evaluateScript(&vss_state->vss, buf, s->url, 0)) {
- - const char *msg = vsscript_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);
- - if (!vs->outnode) {
- - av_log(s, AV_LOG_ERROR, "Could not get script output node.\n");
- - err = AVERROR_EXTERNAL;
- - goto done;
- - }
- -
- - st = avformat_new_stream(s, NULL);
- - if (!st) {
- - err = AVERROR(ENOMEM);
- - goto done;
- - }
- -
- info = vs->vsapi->getVideoInfo(vs->outnode);
- + if (!(st = avformat_new_stream(s, NULL)))
- + return AVERROR_UNKNOWN;
- - if (!info->format || !info->width || !info->height) {
- + if (!isConstantFormat(info)) {
- av_log(s, AV_LOG_ERROR, "Non-constant input format not supported.\n");
- err = AVERROR_PATCHWELCOME;
- goto done;
- @@ -267,8 +181,11 @@ static av_cold int read_header_vs(AVForm
- if (info->fpsDen) {
- vs->is_cfr = 1;
- + st->avg_frame_rate = (AVRational) { info->fpsNum, info->fpsDen };
- + st->duration = info->numFrames;
- + st->nb_frames = info->numFrames;
- + st->start_time = 0;
- avpriv_set_pts_info(st, 64, info->fpsDen, info->fpsNum);
- - st->duration = info->numFrames;
- } else {
- // VFR. Just set "something".
- avpriv_set_pts_info(st, 64, 1, AV_TIME_BASE);
- @@ -276,10 +193,10 @@ static av_cold int read_header_vs(AVForm
- }
- st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
- - 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->codec_id = AV_CODEC_ID_RAWVIDEO;
- + st->codecpar->width = info->width;
- + st->codecpar->height = info->height;
- + st->codecpar->format = map_vsformat(s, st, info->format);
- if (st->codecpar->format == AV_PIX_FMT_NONE) {
- av_log(s, AV_LOG_ERROR, "Unsupported VS pixel format %s\n", info->format->name);
- @@ -292,78 +209,87 @@ static av_cold int read_header_vs(AVForm
- if (info->format->colorFamily == cmYCoCg)
- st->codecpar->color_space = AVCOL_SPC_YCGCO;
- + return 0;
- done:
- - av_free(buf);
- if (err < 0)
- read_close_vs(s);
- return err;
- }
- -static void free_frame(void *opaque, uint8_t *data)
- -{
- - AVFrame *frame = (AVFrame *)data;
- -
- - av_frame_free(&frame);
- -}
- -
- -static int get_vs_prop_int(AVFormatContext *s, const VSMap *map, const char *name, int def)
- +static av_cold int open_script(AVFormatContext *s)
- {
- VSContext *vs = s->priv_data;
- - int64_t res;
- - int err = 1;
- -
- - res = vs->vsapi->propGetInt(map, name, 0, &err);
- - return err || res < INT_MIN || res > INT_MAX ? def : res;
- -}
- + int err;
- -struct vsframe_ref_data {
- - const VSAPI *vsapi;
- - const VSFrameRef *frame;
- - AVBufferRef *vss_state;
- -};
- -
- -static void free_vsframe_ref(void *opaque, uint8_t *data)
- -{
- - struct vsframe_ref_data *d = opaque;
- + // Locking is required, because vsscript_evaluateScript changes the process directory internally.
- + if (err = ff_lock_avformat())
- + return err;
- +
- + if (vsscript_evaluateFile(&vs->script, s->url, efSetWorkingDir)) {
- + ff_unlock_avformat();
- + av_log(s, AV_LOG_ERROR, "VapourSynth script evaluation failed\n");
- + return AVERROR_EXTERNAL;
- + }
- +
- + ff_unlock_avformat();
- - if (d->frame)
- - d->vsapi->freeFrame(d->frame);
- + if (!(vs->outnode = vsscript_getOutput(vs->script, 0))) {
- + av_log(s, AV_LOG_ERROR, "Failed to get the script output node\n");
- + err = AVERROR_EXTERNAL;
- + goto end;
- + }
- - av_buffer_unref(&d->vss_state);
- + if (err = create_video_stream(s))
- + goto end;
- - av_free(d);
- + return 0;
- +end:
- + vs->vsapi->freeNode(vs->outnode);
- + vsscript_freeScript(vs->script);
- + return err;
- }
- static int read_packet_vs(AVFormatContext *s, AVPacket *pkt)
- {
- + static const int gbr_order[3] = { 1, 2, 0 };
- +
- VSContext *vs = s->priv_data;
- AVStream *st = s->streams[0];
- - AVFrame *frame = NULL;
- - char vserr[80];
- const VSFrameRef *vsframe;
- const VSVideoInfo *info = vs->vsapi->getVideoInfo(vs->outnode);
- - const VSMap *props;
- - const AVPixFmtDescriptor *desc;
- - AVBufferRef *vsframe_ref = NULL;
- - struct vsframe_ref_data *ref_data;
- - int err = 0;
- + int err, plane;
- int i;
- + uint8_t *dst_ptr;
- + char vserr[256];
- if (vs->current_frame >= info->numFrames)
- return AVERROR_EOF;
- - ref_data = av_mallocz(sizeof(*ref_data));
- - if (!ref_data) {
- - err = AVERROR(ENOMEM);
- - goto end;
- + vs->current_frame++;
- + if (st->discard == AVDISCARD_ALL)
- + return 0;
- +
- + pkt->size = 0;
- + for (plane = 0; plane < info->format->numPlanes; ++plane) {
- + int width = info->width;
- + int height = info->height;
- +
- + if (plane == 1 || plane == 2) {
- + width >>= info->format->subSamplingW;
- + height >>= info->format->subSamplingH;
- + }
- +
- + pkt->size += (int64_t)width * height * info->format->bytesPerSample;
- }
- - // (the READONLY flag is important because the ref is reused for plane data)
- - vsframe_ref = av_buffer_create(NULL, 0, free_vsframe_ref, ref_data, AV_BUFFER_FLAG_READONLY);
- - if (!vsframe_ref) {
- - err = AVERROR(ENOMEM);
- - av_free(ref_data);
- - goto end;
- + if ((err = av_new_packet(pkt, pkt->size)) < 0)
- + return err;
- +
- + if (vs->is_cfr) {
- + pkt->pts = vs->current_frame;
- + pkt->dts = vs->current_frame;
- + pkt->duration = 1;
- + pkt->stream_index = 0;
- }
- vsframe = vs->vsapi->getFrame(vs->current_frame, vs->outnode, vserr, sizeof(vserr));
- @@ -373,88 +299,69 @@ static int read_packet_vs(AVFormatContex
- goto end;
- }
- - ref_data->vsapi = vs->vsapi;
- - ref_data->frame = vsframe;
- + /* Prefetch the subsequent frames. */
- + for (i = 0; i < vs->ncpu; ++i) {
- + if (i >= (info->numFrames - vs->current_frame))
- + break;
- + vs->vsapi->getFrameAsync(vs->current_frame + i, vs->outnode, async_callback, s);
- + atomic_fetch_add(&vs->async_pending, 1);
- + }
- +
- + dst_ptr = pkt->data;
- + for (plane = 0; plane < info->format->numPlanes; ++plane) {
- + int src_plane = info->format->colorFamily == cmRGB ? gbr_order[plane] : plane;
- + const uint8_t *src_ptr = vs->vsapi->getReadPtr(vsframe, src_plane);
- + int width = vs->vsapi->getFrameWidth(vsframe, src_plane);
- + int height = vs->vsapi->getFrameHeight(vsframe, src_plane);
- + int stride = vs->vsapi->getStride(vsframe, src_plane);
- + int row_size = width * info->format->bytesPerSample;
- +
- + if (info->format->id == pfCompatBGR32) {
- + src_ptr += (int64_t)(height - 1) * stride;
- + stride = -stride;
- + }
- - ref_data->vss_state = av_buffer_ref(vs->vss_state);
- - if (!ref_data->vss_state) {
- - err = AVERROR(ENOMEM);
- - goto end;
- + vs_bitblt(dst_ptr, row_size, src_ptr, stride, row_size, height);
- + dst_ptr += (int64_t)row_size * height;
- }
- - props = vs->vsapi->getFramePropsRO(vsframe);
- -
- - frame = av_frame_alloc();
- - if (!frame) {
- - err = AVERROR(ENOMEM);
- - goto end;
- - }
- + vs->vsapi->freeFrame(vsframe);
- + return 0;
- +end:
- + vs->vsapi->freeFrame(vsframe);
- + av_packet_unref(pkt);
- + return err;
- +}
- - frame->format = st->codecpar->format;
- - frame->width = st->codecpar->width;
- - frame->height = st->codecpar->height;
- - frame->colorspace = st->codecpar->color_space;
- -
- - // Values according to ISO/IEC 14496-10.
- - frame->colorspace = get_vs_prop_int(s, props, "_Matrix", frame->colorspace);
- - frame->color_primaries = get_vs_prop_int(s, props, "_Primaries", frame->color_primaries);
- - frame->color_trc = get_vs_prop_int(s, props, "_Transfer", frame->color_trc);
- -
- - if (get_vs_prop_int(s, props, "_ColorRange", 1) == 0)
- - frame->color_range = AVCOL_RANGE_JPEG;
- -
- - frame->sample_aspect_ratio.num = get_vs_prop_int(s, props, "_SARNum", 0);
- - frame->sample_aspect_ratio.den = get_vs_prop_int(s, props, "_SARDen", 1);
- -
- - av_assert0(vs->vsapi->getFrameWidth(vsframe, 0) == frame->width);
- - av_assert0(vs->vsapi->getFrameHeight(vsframe, 0) == frame->height);
- -
- - desc = av_pix_fmt_desc_get(frame->format);
- -
- - for (i = 0; i < info->format->numPlanes; i++) {
- - int p = vs->c_order[i];
- - ptrdiff_t plane_h = frame->height;
- -
- - frame->data[i] = (void *)vs->vsapi->getReadPtr(vsframe, p);
- - frame->linesize[i] = vs->vsapi->getStride(vsframe, p);
- -
- - frame->buf[i] = av_buffer_ref(vsframe_ref);
- - if (!frame->buf[i]) {
- - err = AVERROR(ENOMEM);
- - goto end;
- - }
- +static av_cold int read_header_vs(AVFormatContext *s)
- +{
- + VSContext *vs = s->priv_data;
- + int err;
- - // Each plane needs an AVBufferRef that indicates the correct plane
- - // memory range. VapourSynth doesn't even give us the memory range,
- - // so make up a bad guess to make FFmpeg happy (even if almost nothing
- - // checks the memory range).
- - if (i == 1 || i == 2)
- - plane_h = AV_CEIL_RSHIFT(plane_h, desc->log2_chroma_h);
- - frame->buf[i]->data = frame->data[i];
- - frame->buf[i]->size = frame->linesize[i] * plane_h;
- + if (!vsscript_init()) {
- + av_log(s, AV_LOG_ERROR, "Failed to initialize VapourSynth environment\n");
- + return AVERROR_EXTERNAL;
- }
- - pkt->buf = av_buffer_create((uint8_t*)frame, sizeof(*frame),
- - free_frame, NULL, 0);
- - if (!pkt->buf) {
- - err = AVERROR(ENOMEM);
- + if ((err = vsscript_getApiVersion()) < VSSCRIPT_API_VERSION) {
- + av_log(s, AV_LOG_ERROR, "VSScript API too old: %d versus %d\n", err, VSSCRIPT_API_VERSION);
- + err = AVERROR_EXTERNAL;
- goto end;
- }
- - frame = NULL; // pkt owns it now
- -
- - pkt->data = pkt->buf->data;
- - pkt->size = pkt->buf->size;
- - pkt->flags |= AV_PKT_FLAG_TRUSTED;
- -
- - if (vs->is_cfr)
- - pkt->pts = vs->current_frame;
- + if (!(vs->vsapi = vsscript_getVSApi2(VAPOURSYNTH_API_VERSION))) {
- + av_log(s, AV_LOG_ERROR, "VapourSynth API too old: %d required\n", VAPOURSYNTH_API_VERSION);
- + err = AVERROR_EXTERNAL;
- + goto end;
- + }
- - vs->current_frame++;
- + if (err = open_script(s))
- + goto end;
- + vs->ncpu = av_cpu_count();
- + return 0;
- end:
- - av_frame_free(&frame);
- - av_buffer_unref(&vsframe_ref);
- + vsscript_finalize();
- return err;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement