You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

497 lines
14KB

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