1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 /**
20 * @file
21 * VapourSynth demuxer
22 *
23 * Synthesizes vapour (?)
24 */
25
26 #include <limits.h>
27
28 #include <VapourSynth.h>
29 #include <VSScript.h>
30
31 #include "libavutil/avassert.h"
32 #include "libavutil/avstring.h"
33 #include "libavutil/eval.h"
34 #include "libavutil/imgutils.h"
35 #include "libavutil/opt.h"
36 #include "libavutil/pixdesc.h"
37 #include "avformat.h"
38 #include "internal.h"
39
40 struct VSState {
41 VSScript *vss;
42 };
43
44 typedef struct VSContext {
45 const AVClass *class;
46
47 AVBufferRef *vss_state;
48
49 const VSAPI *vsapi;
50 VSCore *vscore;
51
52 VSNodeRef *outnode;
53 int is_cfr;
54 int current_frame;
55
56 int c_order[4];
57
58 /* options */
59 int64_t max_script_size;
60 } VSContext;
61
62 #define OFFSET(x) offsetof(VSContext, x)
63 #define A AV_OPT_FLAG_AUDIO_PARAM
64 #define D AV_OPT_FLAG_DECODING_PARAM
65 static const AVOption options[] = {
66 {"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},
67 {NULL}
68 };
69
free_vss_state(void * opaque,uint8_t * data)70 static void free_vss_state(void *opaque, uint8_t *data)
71 {
72 struct VSState *vss = opaque;
73
74 if (vss->vss) {
75 vsscript_freeScript(vss->vss);
76 vsscript_finalize();
77 }
78 }
79
read_close_vs(AVFormatContext * s)80 static av_cold int read_close_vs(AVFormatContext *s)
81 {
82 VSContext *vs = s->priv_data;
83
84 if (vs->outnode)
85 vs->vsapi->freeNode(vs->outnode);
86
87 av_buffer_unref(&vs->vss_state);
88
89 vs->vsapi = NULL;
90 vs->vscore = NULL;
91 vs->outnode = NULL;
92
93 return 0;
94 }
95
is_native_endian(enum AVPixelFormat pixfmt)96 static av_cold int is_native_endian(enum AVPixelFormat pixfmt)
97 {
98 enum AVPixelFormat other = av_pix_fmt_swap_endianness(pixfmt);
99 const AVPixFmtDescriptor *pd;
100 if (other == AV_PIX_FMT_NONE || other == pixfmt)
101 return 1; // not affected by byte order
102 pd = av_pix_fmt_desc_get(pixfmt);
103 return pd && (!!HAVE_BIGENDIAN == !!(pd->flags & AV_PIX_FMT_FLAG_BE));
104 }
105
match_pixfmt(const VSFormat * vsf,int c_order[4])106 static av_cold enum AVPixelFormat match_pixfmt(const VSFormat *vsf, int c_order[4])
107 {
108 static const int yuv_order[4] = {0, 1, 2, 0};
109 static const int rgb_order[4] = {1, 2, 0, 0};
110 const AVPixFmtDescriptor *pd;
111
112 for (pd = av_pix_fmt_desc_next(NULL); pd; pd = av_pix_fmt_desc_next(pd)) {
113 int is_rgb, is_yuv, i;
114 const int *order;
115 enum AVPixelFormat pixfmt;
116
117 pixfmt = av_pix_fmt_desc_get_id(pd);
118
119 if (pd->flags & (AV_PIX_FMT_FLAG_BAYER | AV_PIX_FMT_FLAG_ALPHA |
120 AV_PIX_FMT_FLAG_HWACCEL | AV_PIX_FMT_FLAG_BITSTREAM))
121 continue;
122
123 if (pd->log2_chroma_w != vsf->subSamplingW ||
124 pd->log2_chroma_h != vsf->subSamplingH)
125 continue;
126
127 is_rgb = vsf->colorFamily == cmRGB;
128 if (is_rgb != !!(pd->flags & AV_PIX_FMT_FLAG_RGB))
129 continue;
130
131 is_yuv = vsf->colorFamily == cmYUV ||
132 vsf->colorFamily == cmYCoCg ||
133 vsf->colorFamily == cmGray;
134 if (!is_rgb && !is_yuv)
135 continue;
136
137 if (vsf->sampleType != ((pd->flags & AV_PIX_FMT_FLAG_FLOAT) ? stFloat : stInteger))
138 continue;
139
140 if (av_pix_fmt_count_planes(pixfmt) != vsf->numPlanes)
141 continue;
142
143 if (strncmp(pd->name, "xyz", 3) == 0)
144 continue;
145
146 if (!is_native_endian(pixfmt))
147 continue;
148
149 order = is_yuv ? yuv_order : rgb_order;
150
151 for (i = 0; i < pd->nb_components; i++) {
152 const AVComponentDescriptor *c = &pd->comp[i];
153 if (order[c->plane] != i ||
154 c->offset != 0 || c->shift != 0 ||
155 c->step != vsf->bytesPerSample ||
156 c->depth != vsf->bitsPerSample)
157 goto cont;
158 }
159
160 // Use it.
161 memcpy(c_order, order, sizeof(int[4]));
162 return pixfmt;
163
164 cont: ;
165 }
166
167 return AV_PIX_FMT_NONE;
168 }
169
read_header_vs(AVFormatContext * s)170 static av_cold int read_header_vs(AVFormatContext *s)
171 {
172 AVStream *st;
173 AVIOContext *pb = s->pb;
174 VSContext *vs = s->priv_data;
175 int64_t sz = avio_size(pb);
176 char *buf = NULL;
177 char dummy;
178 const VSVideoInfo *info;
179 struct VSState *vss_state;
180 int err = 0;
181
182 vss_state = av_mallocz(sizeof(*vss_state));
183 if (!vss_state) {
184 err = AVERROR(ENOMEM);
185 goto done;
186 }
187
188 vs->vss_state = av_buffer_create(NULL, 0, free_vss_state, vss_state, 0);
189 if (!vs->vss_state) {
190 err = AVERROR(ENOMEM);
191 av_free(vss_state);
192 goto done;
193 }
194
195 if (!vsscript_init()) {
196 av_log(s, AV_LOG_ERROR, "Failed to initialize VSScript (possibly PYTHONPATH not set).\n");
197 err = AVERROR_EXTERNAL;
198 goto done;
199 }
200
201 if (vsscript_createScript(&vss_state->vss)) {
202 av_log(s, AV_LOG_ERROR, "Failed to create script instance.\n");
203 err = AVERROR_EXTERNAL;
204 vsscript_finalize();
205 goto done;
206 }
207
208 if (sz < 0 || sz > vs->max_script_size) {
209 if (sz < 0)
210 av_log(s, AV_LOG_WARNING, "Could not determine file size\n");
211 sz = vs->max_script_size;
212 }
213
214 buf = av_malloc(sz + 1);
215 if (!buf) {
216 err = AVERROR(ENOMEM);
217 goto done;
218 }
219 sz = avio_read(pb, buf, sz);
220
221 if (sz < 0) {
222 av_log(s, AV_LOG_ERROR, "Could not read script.\n");
223 err = sz;
224 goto done;
225 }
226
227 // Data left means our buffer (the max_script_size option) is too small
228 if (avio_read(pb, &dummy, 1) == 1) {
229 av_log(s, AV_LOG_ERROR, "File size is larger than max_script_size option "
230 "value %"PRIi64", consider increasing the max_script_size option\n",
231 vs->max_script_size);
232 err = AVERROR_BUFFER_TOO_SMALL;
233 goto done;
234 }
235
236 buf[sz] = '\0';
237 if (vsscript_evaluateScript(&vss_state->vss, buf, s->url, 0)) {
238 const char *msg = vsscript_getError(vss_state->vss);
239 av_log(s, AV_LOG_ERROR, "Failed to parse script: %s\n", msg ? msg : "(unknown)");
240 err = AVERROR_EXTERNAL;
241 goto done;
242 }
243
244 vs->vsapi = vsscript_getVSApi();
245 vs->vscore = vsscript_getCore(vss_state->vss);
246
247 vs->outnode = vsscript_getOutput(vss_state->vss, 0);
248 if (!vs->outnode) {
249 av_log(s, AV_LOG_ERROR, "Could not get script output node.\n");
250 err = AVERROR_EXTERNAL;
251 goto done;
252 }
253
254 st = avformat_new_stream(s, NULL);
255 if (!st) {
256 err = AVERROR(ENOMEM);
257 goto done;
258 }
259
260 info = vs->vsapi->getVideoInfo(vs->outnode);
261
262 if (!info->format || !info->width || !info->height) {
263 av_log(s, AV_LOG_ERROR, "Non-constant input format not supported.\n");
264 err = AVERROR_PATCHWELCOME;
265 goto done;
266 }
267
268 if (info->fpsDen) {
269 vs->is_cfr = 1;
270 avpriv_set_pts_info(st, 64, info->fpsDen, info->fpsNum);
271 st->duration = info->numFrames;
272 } else {
273 // VFR. Just set "something".
274 avpriv_set_pts_info(st, 64, 1, AV_TIME_BASE);
275 s->ctx_flags |= AVFMTCTX_UNSEEKABLE;
276 }
277
278 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
279 st->codecpar->codec_id = AV_CODEC_ID_WRAPPED_AVFRAME;
280 st->codecpar->width = info->width;
281 st->codecpar->height = info->height;
282 st->codecpar->format = match_pixfmt(info->format, vs->c_order);
283
284 if (st->codecpar->format == AV_PIX_FMT_NONE) {
285 av_log(s, AV_LOG_ERROR, "Unsupported VS pixel format %s\n", info->format->name);
286 err = AVERROR_EXTERNAL;
287 goto done;
288 }
289 av_log(s, AV_LOG_VERBOSE, "VS format %s -> pixfmt %s\n", info->format->name,
290 av_get_pix_fmt_name(st->codecpar->format));
291
292 if (info->format->colorFamily == cmYCoCg)
293 st->codecpar->color_space = AVCOL_SPC_YCGCO;
294
295 done:
296 av_free(buf);
297 return err;
298 }
299
free_frame(void * opaque,uint8_t * data)300 static void free_frame(void *opaque, uint8_t *data)
301 {
302 AVFrame *frame = (AVFrame *)data;
303
304 av_frame_free(&frame);
305 }
306
get_vs_prop_int(AVFormatContext * s,const VSMap * map,const char * name,int def)307 static int get_vs_prop_int(AVFormatContext *s, const VSMap *map, const char *name, int def)
308 {
309 VSContext *vs = s->priv_data;
310 int64_t res;
311 int err = 1;
312
313 res = vs->vsapi->propGetInt(map, name, 0, &err);
314 return err || res < INT_MIN || res > INT_MAX ? def : res;
315 }
316
317 struct vsframe_ref_data {
318 const VSAPI *vsapi;
319 const VSFrameRef *frame;
320 AVBufferRef *vss_state;
321 };
322
free_vsframe_ref(void * opaque,uint8_t * data)323 static void free_vsframe_ref(void *opaque, uint8_t *data)
324 {
325 struct vsframe_ref_data *d = opaque;
326
327 if (d->frame)
328 d->vsapi->freeFrame(d->frame);
329
330 av_buffer_unref(&d->vss_state);
331
332 av_free(d);
333 }
334
read_packet_vs(AVFormatContext * s,AVPacket * pkt)335 static int read_packet_vs(AVFormatContext *s, AVPacket *pkt)
336 {
337 VSContext *vs = s->priv_data;
338 AVStream *st = s->streams[0];
339 AVFrame *frame = NULL;
340 char vserr[80];
341 const VSFrameRef *vsframe;
342 const VSVideoInfo *info = vs->vsapi->getVideoInfo(vs->outnode);
343 const VSMap *props;
344 const AVPixFmtDescriptor *desc;
345 AVBufferRef *vsframe_ref = NULL;
346 struct vsframe_ref_data *ref_data;
347 int err = 0;
348 int i;
349
350 if (vs->current_frame >= info->numFrames)
351 return AVERROR_EOF;
352
353 ref_data = av_mallocz(sizeof(*ref_data));
354 if (!ref_data) {
355 err = AVERROR(ENOMEM);
356 goto end;
357 }
358
359 // (the READONLY flag is important because the ref is reused for plane data)
360 vsframe_ref = av_buffer_create(NULL, 0, free_vsframe_ref, ref_data, AV_BUFFER_FLAG_READONLY);
361 if (!vsframe_ref) {
362 err = AVERROR(ENOMEM);
363 av_free(ref_data);
364 goto end;
365 }
366
367 vsframe = vs->vsapi->getFrame(vs->current_frame, vs->outnode, vserr, sizeof(vserr));
368 if (!vsframe) {
369 av_log(s, AV_LOG_ERROR, "Error getting frame: %s\n", vserr);
370 err = AVERROR_EXTERNAL;
371 goto end;
372 }
373
374 ref_data->vsapi = vs->vsapi;
375 ref_data->frame = vsframe;
376
377 ref_data->vss_state = av_buffer_ref(vs->vss_state);
378 if (!ref_data->vss_state) {
379 err = AVERROR(ENOMEM);
380 goto end;
381 }
382
383 props = vs->vsapi->getFramePropsRO(vsframe);
384
385 frame = av_frame_alloc();
386 if (!frame) {
387 err = AVERROR(ENOMEM);
388 goto end;
389 }
390
391 frame->format = st->codecpar->format;
392 frame->width = st->codecpar->width;
393 frame->height = st->codecpar->height;
394 frame->colorspace = st->codecpar->color_space;
395
396 // Values according to ISO/IEC 14496-10.
397 frame->colorspace = get_vs_prop_int(s, props, "_Matrix", frame->colorspace);
398 frame->color_primaries = get_vs_prop_int(s, props, "_Primaries", frame->color_primaries);
399 frame->color_trc = get_vs_prop_int(s, props, "_Transfer", frame->color_trc);
400
401 if (get_vs_prop_int(s, props, "_ColorRange", 1) == 0)
402 frame->color_range = AVCOL_RANGE_JPEG;
403
404 frame->sample_aspect_ratio.num = get_vs_prop_int(s, props, "_SARNum", 0);
405 frame->sample_aspect_ratio.den = get_vs_prop_int(s, props, "_SARDen", 1);
406
407 av_assert0(vs->vsapi->getFrameWidth(vsframe, 0) == frame->width);
408 av_assert0(vs->vsapi->getFrameHeight(vsframe, 0) == frame->height);
409
410 desc = av_pix_fmt_desc_get(frame->format);
411
412 for (i = 0; i < info->format->numPlanes; i++) {
413 int p = vs->c_order[i];
414 ptrdiff_t plane_h = frame->height;
415
416 frame->data[i] = (void *)vs->vsapi->getReadPtr(vsframe, p);
417 frame->linesize[i] = vs->vsapi->getStride(vsframe, p);
418
419 frame->buf[i] = av_buffer_ref(vsframe_ref);
420 if (!frame->buf[i]) {
421 err = AVERROR(ENOMEM);
422 goto end;
423 }
424
425 // Each plane needs an AVBufferRef that indicates the correct plane
426 // memory range. VapourSynth doesn't even give us the memory range,
427 // so make up a bad guess to make FFmpeg happy (even if almost nothing
428 // checks the memory range).
429 if (i == 1 || i == 2)
430 plane_h = AV_CEIL_RSHIFT(plane_h, desc->log2_chroma_h);
431 frame->buf[i]->data = frame->data[i];
432 frame->buf[i]->size = frame->linesize[i] * plane_h;
433 }
434
435 pkt->buf = av_buffer_create((uint8_t*)frame, sizeof(*frame),
436 free_frame, NULL, 0);
437 if (!pkt->buf) {
438 err = AVERROR(ENOMEM);
439 goto end;
440 }
441
442 frame = NULL; // pkt owns it now
443
444 pkt->data = pkt->buf->data;
445 pkt->size = pkt->buf->size;
446 pkt->flags |= AV_PKT_FLAG_TRUSTED;
447
448 if (vs->is_cfr)
449 pkt->pts = vs->current_frame;
450
451 vs->current_frame++;
452
453 end:
454 av_frame_free(&frame);
455 av_buffer_unref(&vsframe_ref);
456 return err;
457 }
458
read_seek_vs(AVFormatContext * s,int stream_idx,int64_t ts,int flags)459 static int read_seek_vs(AVFormatContext *s, int stream_idx, int64_t ts, int flags)
460 {
461 VSContext *vs = s->priv_data;
462
463 if (!vs->is_cfr)
464 return AVERROR(ENOSYS);
465
466 vs->current_frame = FFMIN(FFMAX(0, ts), s->streams[0]->duration);
467 return 0;
468 }
469
probe_vs(const AVProbeData * p)470 static av_cold int probe_vs(const AVProbeData *p)
471 {
472 // Explicitly do not support this. VS scripts are written in Python, and
473 // can run arbitrary code on the user's system.
474 return 0;
475 }
476
477 static const AVClass class_vs = {
478 .class_name = "VapourSynth demuxer",
479 .item_name = av_default_item_name,
480 .option = options,
481 .version = LIBAVUTIL_VERSION_INT,
482 };
483
484 const AVInputFormat ff_vapoursynth_demuxer = {
485 .name = "vapoursynth",
486 .long_name = NULL_IF_CONFIG_SMALL("VapourSynth demuxer"),
487 .priv_data_size = sizeof(VSContext),
488 .flags_internal = FF_FMT_INIT_CLEANUP,
489 .read_probe = probe_vs,
490 .read_header = read_header_vs,
491 .read_packet = read_packet_vs,
492 .read_close = read_close_vs,
493 .read_seek = read_seek_vs,
494 .priv_class = &class_vs,
495 };
496