Advertisement
DJATOM

x264 vpy support

Apr 28th, 2018
300
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 42.20 KB | None | 0 0
  1. diff -urN ./x264.src/Makefile ./x264.vpy/Makefile
  2. --- ./x264.src/Makefile 2017-06-29 09:28:57 +0000
  3. +++ ./x264.vpy/Makefile 2018-04-27 17:41:51 +0000
  4. @@ -46,6 +46,10 @@
  5.  endif
  6.  
  7.  # Optional module sources
  8. +ifneq ($(findstring HAVE_VPY 1, $(CONFIG)),)
  9. +SRCCLI += input/vpy.c
  10. +endif
  11. +
  12.  ifneq ($(findstring HAVE_AVS 1, $(CONFIG)),)
  13.  SRCCLI += input/avs.c
  14.  endif
  15. diff -urN ./x264.src/configure ./x264.vpy/configure
  16. --- ./x264.src/configure    2017-06-29 09:28:58 +0000
  17. +++ ./x264.vpy/configure    2018-04-28 15:49:07 +0000
  18. @@ -47,6 +47,7 @@
  19.    --sysroot=SYSROOT        root of cross-build tree
  20.  
  21.  External library support:
  22. +  --disable-vpy            disable vapoursynth support
  23.    --disable-avs            disable avisynth support
  24.    --disable-swscale        disable swscale support
  25.    --disable-lavf           disable libavformat support
  26. @@ -337,6 +338,7 @@
  27.  cli_libx264="internal"
  28.  shared="no"
  29.  static="no"
  30. +vpy="auto"
  31.  avs="auto"
  32.  lavf="auto"
  33.  ffms="auto"
  34. @@ -417,6 +419,9 @@
  35.          --disable-interlaced)
  36.              interlaced="no"
  37.              ;;
  38. +        --disable-vpy)
  39. +            vpy="no"
  40. +            ;;
  41.          --disable-avs)
  42.              avs="no"
  43.              ;;
  44. @@ -1202,6 +1207,18 @@
  45.      fi
  46.  fi
  47.  
  48. +if [ "$vpy" = "auto" ] ; then
  49. +    vpy="yes"
  50. +    define HAVE_VPY 1
  51. +    if [ "$SYS" = "LINUX" -o "$SYS" = "MACOSX" ] ; then
  52. +        VPY_LIBS="-lvapoursynth-script"
  53. +        if [ "$avs" = "no" ] ; then
  54. +            VPY_LIBS="-ldl $VPY_LIBS"
  55. +        fi
  56. +        LDFLAGSCLI="$VPY_LIBS $LDFLAGSCLI"
  57. +    fi
  58. +fi
  59. +
  60.  cc_check "stdint.h" "" "uint32_t test_vec __attribute__ ((vector_size (16))) = {0,1,2,3};" && define HAVE_VECTOREXT
  61.  
  62.  if [ "$pic" = "yes" ] ; then
  63. @@ -1508,6 +1525,7 @@
  64.  static:        $static
  65.  asm:           $asm
  66.  interlaced:    $interlaced
  67. +vpy:           $vpy
  68.  avs:           $avs
  69.  lavf:          $lavf
  70.  ffms:          $ffms
  71. diff -urN ./x264.src/extras/VSHelper.h ./x264.vpy/extras/VSHelper.h
  72. --- ./x264.src/extras/VSHelper.h    1970-01-01 00:00:00 +0000
  73. +++ ./x264.vpy/extras/VSHelper.h    2018-04-28 18:12:18 +0000
  74. @@ -0,0 +1,174 @@
  75. +/*****************************************************************************
  76. +* Copyright (c) 2012-2015 Fredrik Mellbin
  77. +* --- Legal stuff ---
  78. +* This program is free software. It comes without any warranty, to
  79. +* the extent permitted by applicable law. You can redistribute it
  80. +* and/or modify it under the terms of the Do What The Fuck You Want
  81. +* To Public License, Version 2, as published by Sam Hocevar. See
  82. +* http://sam.zoy.org/wtfpl/COPYING for more details.
  83. +*****************************************************************************/
  84. +
  85. +#ifndef VSHELPER_H
  86. +#define VSHELPER_H
  87. +
  88. +#include <limits.h>
  89. +#include <stdint.h>
  90. +#include <stdlib.h>
  91. +#include <string.h>
  92. +#include <assert.h>
  93. +#include <math.h>
  94. +#ifdef _WIN32
  95. +#include <malloc.h>
  96. +#endif
  97. +#include "VapourSynth.h"
  98. +
  99. +/* Visual Studio doesn't recognize inline in c mode */
  100. +#if defined(_MSC_VER) && !defined(__cplusplus)
  101. +#define inline _inline
  102. +#endif
  103. +
  104. +/* A kinda portable definition of the C99 restrict keyword (or its inofficial C++ equivalent) */
  105. +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* Available in C99 */
  106. +#define VS_RESTRICT restrict
  107. +#elif defined(__cplusplus) || defined(_MSC_VER) /* Almost all relevant C++ compilers support it so just assume it works */
  108. +#define VS_RESTRICT __restrict
  109. +#else /* Not supported */
  110. +#define VS_RESTRICT
  111. +#endif
  112. +
  113. +#ifdef _WIN32
  114. +#define VS_ALIGNED_MALLOC(pptr, size, alignment) do { *(pptr) = _aligned_malloc((size), (alignment)); } while (0)
  115. +#define VS_ALIGNED_FREE(ptr) do { _aligned_free((ptr)); } while (0)
  116. +#else
  117. +#define VS_ALIGNED_MALLOC(pptr, size, alignment) do { if(posix_memalign((void**)(pptr), (alignment), (size))) *((void**)pptr) = NULL; } while (0)
  118. +#define VS_ALIGNED_FREE(ptr) do { free((ptr)); } while (0)
  119. +#endif
  120. +
  121. +#define VSMAX(a,b) ((a) > (b) ? (a) : (b))
  122. +#define VSMIN(a,b) ((a) > (b) ? (b) : (a))
  123. +
  124. +#ifdef __cplusplus
  125. +/* A nicer templated malloc for all the C++ users out there */
  126. +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
  127. +template<typename T=void>
  128. +#else
  129. +template<typename T>
  130. +#endif
  131. +static inline T* vs_aligned_malloc(size_t size, size_t alignment) {
  132. +#ifdef _WIN32
  133. +    return (T*)_aligned_malloc(size, alignment);
  134. +#else
  135. +    void *tmp = NULL;
  136. +    if (posix_memalign(&tmp, alignment, size))
  137. +        tmp = 0;
  138. +    return (T*)tmp;
  139. +#endif
  140. +}
  141. +
  142. +static inline void vs_aligned_free(void *ptr) {
  143. +    VS_ALIGNED_FREE(ptr);
  144. +}
  145. +#endif /* __cplusplus */
  146. +
  147. +/* convenience function for checking if the format never changes between frames */
  148. +static inline int isConstantFormat(const VSVideoInfo *vi) {
  149. +    return vi->height > 0 && vi->width > 0 && vi->format;
  150. +}
  151. +
  152. +/* convenience function to check for if two clips have the same format (unknown/changeable will be considered the same too) */
  153. +static inline int isSameFormat(const VSVideoInfo *v1, const VSVideoInfo *v2) {
  154. +    return v1->height == v2->height && v1->width == v2->width && v1->format == v2->format;
  155. +}
  156. +
  157. +/* multiplies and divides a rational number, such as a frame duration, in place and reduces the result */
  158. +static inline void muldivRational(int64_t *num, int64_t *den, int64_t mul, int64_t div) {
  159. +    /* do nothing if the rational number is invalid */
  160. +    if (!*den)
  161. +        return;
  162. +
  163. +    /* nobody wants to accidentally divide by zero */
  164. +    assert(div);
  165. +
  166. +    int64_t a, b;
  167. +    *num *= mul;
  168. +    *den *= div;
  169. +    a = *num;
  170. +    b = *den;
  171. +    while (b != 0) {
  172. +        int64_t t = a;
  173. +        a = b;
  174. +        b = t % b;
  175. +    }
  176. +    if (a < 0)
  177. +        a = -a;
  178. +    *num /= a;
  179. +    *den /= a;
  180. +}
  181. +
  182. +/* reduces a rational number */
  183. +static inline void vs_normalizeRational(int64_t *num, int64_t *den) {
  184. +    muldivRational(num, den, 1, 1);
  185. +}
  186. +
  187. +/* add two rational numbers and reduces the result */
  188. +static inline void vs_addRational(int64_t *num, int64_t *den, int64_t addnum, int64_t addden) {
  189. +    /* do nothing if the rational number is invalid */
  190. +    if (!*den)
  191. +        return;
  192. +
  193. +    /* nobody wants to accidentally add an invalid rational number */
  194. +    assert(addden);
  195. +
  196. +    if (*den == addden) {
  197. +        *num += addnum;
  198. +    } else {
  199. +        int64_t temp = addden;
  200. +        addnum *= *den;
  201. +        addden *= *den;
  202. +        *num *= temp;
  203. +        *den *= temp;
  204. +
  205. +        *num += addnum;
  206. +
  207. +        vs_normalizeRational(num, den);
  208. +    }
  209. +}
  210. +
  211. +/* converts an int64 to int with saturation, useful to silence warnings when reading int properties among other things */
  212. +static inline int int64ToIntS(int64_t i) {
  213. +    if (i > INT_MAX)
  214. +        return INT_MAX;
  215. +    else if (i < INT_MIN)
  216. +        return INT_MIN;
  217. +    else return (int)i;
  218. +}
  219. +
  220. +static inline void vs_bitblt(void *dstp, int dst_stride, const void *srcp, int src_stride, size_t row_size, size_t height) {
  221. +    if (height) {
  222. +        if (src_stride == dst_stride && src_stride == (int)row_size) {
  223. +            memcpy(dstp, srcp, row_size * height);
  224. +        } else {
  225. +            const uint8_t *srcp8 = (const uint8_t *)srcp;
  226. +            uint8_t *dstp8 = (uint8_t *)dstp;
  227. +            size_t i;
  228. +            for (i = 0; i < height; i++) {
  229. +                memcpy(dstp8, srcp8, row_size);
  230. +                srcp8 += src_stride;
  231. +                dstp8 += dst_stride;
  232. +            }
  233. +        }
  234. +    }
  235. +}
  236. +
  237. +/* check if the frame dimensions are valid for a given format */
  238. +/* returns non-zero for valid width and height */
  239. +static inline int areValidDimensions(const VSFormat *fi, int width, int height) {
  240. +    return !(width % (1 << fi->subSamplingW) || height % (1 << fi->subSamplingH));
  241. +}
  242. +
  243. +/* Visual Studio doesn't recognize inline in c mode */
  244. +#if defined(_MSC_VER) && !defined(__cplusplus)
  245. +#undef inline
  246. +#endif
  247. +
  248. +#endif
  249. diff -urN ./x264.src/extras/VSScript.h ./x264.vpy/extras/VSScript.h
  250. --- ./x264.src/extras/VSScript.h    1970-01-01 00:00:00 +0000
  251. +++ ./x264.vpy/extras/VSScript.h    2018-04-28 15:36:11 +0000
  252. @@ -0,0 +1,84 @@
  253. +/*
  254. +* Copyright (c) 2013-2018 Fredrik Mellbin
  255. +*
  256. +* This file is part of VapourSynth.
  257. +*
  258. +* VapourSynth is free software; you can redistribute it and/or
  259. +* modify it under the terms of the GNU Lesser General Public
  260. +* License as published by the Free Software Foundation; either
  261. +* version 2.1 of the License, or (at your option) any later version.
  262. +*
  263. +* VapourSynth is distributed in the hope that it will be useful,
  264. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  265. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  266. +* Lesser General Public License for more details.
  267. +*
  268. +* You should have received a copy of the GNU Lesser General Public
  269. +* License along with VapourSynth; if not, write to the Free Software
  270. +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  271. +*/
  272. +
  273. +#ifndef VSSCRIPT_H
  274. +#define VSSCRIPT_H
  275. +
  276. +#include "VapourSynth.h"
  277. +
  278. +#define VSSCRIPT_API_MAJOR 3
  279. +#define VSSCRIPT_API_MINOR 2
  280. +#define VSSCRIPT_API_VERSION ((VSSCRIPT_API_MAJOR << 16) | (VSSCRIPT_API_MINOR))
  281. +
  282. +/* As of api 3.2 all functions are threadsafe */
  283. +
  284. +typedef struct VSScript VSScript;
  285. +
  286. +typedef enum VSEvalFlags {
  287. +    efSetWorkingDir = 1,
  288. +} VSEvalFlags;
  289. +
  290. +/* Get the api version */
  291. +VS_API(int) vsscript_getApiVersion(void); /* api 3.1 */
  292. +
  293. +/* Initialize the available scripting runtimes, returns zero on failure */
  294. +VS_API(int) vsscript_init(void);
  295. +
  296. +/* Free all scripting runtimes */
  297. +VS_API(int) vsscript_finalize(void);
  298. +
  299. +/*
  300. +* Pass a pointer to a null handle to create a new one
  301. +* The values returned by the query functions are only valid during the lifetime of the VSScript
  302. +* scriptFilename is if the error message should reference a certain file, NULL allowed in vsscript_evaluateScript()
  303. +* core is to pass in an already created instance so that mixed environments can be used,
  304. +* NULL creates a new core that can be fetched with vsscript_getCore() later OR implicitly uses the one associated with an already existing handle when passed
  305. +* If efSetWorkingDir is passed to flags the current working directory will be changed to the path of the script
  306. +* note that if scriptFilename is NULL in vsscript_evaluateScript() then __file__ won't be set and the working directory won't be changed
  307. +* Set efSetWorkingDir to get the default and recommended behavior
  308. +*/
  309. +VS_API(int) vsscript_evaluateScript(VSScript **handle, const char *script, const char *scriptFilename, int flags);
  310. +/* Convenience version of the above function that loads the script from a file */
  311. +VS_API(int) vsscript_evaluateFile(VSScript **handle, const char *scriptFilename, int flags);
  312. +/* Create an empty environment for use in later invocations, mostly useful to set script variables before execution */
  313. +VS_API(int) vsscript_createScript(VSScript **handle);
  314. +
  315. +VS_API(void) vsscript_freeScript(VSScript *handle);
  316. +VS_API(const char *) vsscript_getError(VSScript *handle);
  317. +/* The node returned must be freed using freeNode() before calling vsscript_freeScript() */
  318. +VS_API(VSNodeRef *) vsscript_getOutput(VSScript *handle, int index);
  319. +/* Both nodes returned must be freed using freeNode() before calling vsscript_freeScript(), the alpha node pointer will only be set if an alpha clip has been set in the script */
  320. +VS_API(VSNodeRef *) vsscript_getOutput2(VSScript *handle, int index, VSNodeRef **alpha); /* api 3.1 */
  321. +/* Unset an output index */
  322. +VS_API(int) vsscript_clearOutput(VSScript *handle, int index);
  323. +/* The core is valid as long as the environment exists */
  324. +VS_API(VSCore *) vsscript_getCore(VSScript *handle);
  325. +/* Convenience function for retrieving a vsapi pointer */
  326. +VS_API(const VSAPI *) vsscript_getVSApi(void); /* deprecated as of api 3.2 since it's impossible to tell the api version supported */
  327. +VS_API(const VSAPI *) vsscript_getVSApi2(int version); /* api 3.2, generally you should pass VAPOURSYNTH_API_VERSION */
  328. +
  329. +/* Variables names that are not set or not of a convertible type will return an error */
  330. +VS_API(int) vsscript_getVariable(VSScript *handle, const char *name, VSMap *dst);
  331. +VS_API(int) vsscript_setVariable(VSScript *handle, const VSMap *vars);
  332. +VS_API(int) vsscript_clearVariable(VSScript *handle, const char *name);
  333. +/* Tries to clear everything set in an environment, normally it is better to simply free an environment completely and create a new one */
  334. +VS_API(void) vsscript_clearEnvironment(VSScript *handle);
  335. +
  336. +#endif /* VSSCRIPT_H */
  337. diff -urN ./x264.src/extras/VapourSynth.h ./x264.vpy/extras/VapourSynth.h
  338. --- ./x264.src/extras/VapourSynth.h 1970-01-01 00:00:00 +0000
  339. +++ ./x264.vpy/extras/VapourSynth.h 2018-04-28 15:36:38 +0000
  340. @@ -0,0 +1,342 @@
  341. +/*
  342. +* Copyright (c) 2012-2017 Fredrik Mellbin
  343. +*
  344. +* This file is part of VapourSynth.
  345. +*
  346. +* VapourSynth is free software; you can redistribute it and/or
  347. +* modify it under the terms of the GNU Lesser General Public
  348. +* License as published by the Free Software Foundation; either
  349. +* version 2.1 of the License, or (at your option) any later version.
  350. +*
  351. +* VapourSynth is distributed in the hope that it will be useful,
  352. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  353. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  354. +* Lesser General Public License for more details.
  355. +*
  356. +* You should have received a copy of the GNU Lesser General Public
  357. +* License along with VapourSynth; if not, write to the Free Software
  358. +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  359. +*/
  360. +
  361. +#ifndef VAPOURSYNTH_H
  362. +#define VAPOURSYNTH_H
  363. +
  364. +#include <stdint.h>
  365. +
  366. +#define VAPOURSYNTH_API_MAJOR 3
  367. +#define VAPOURSYNTH_API_MINOR 5
  368. +#define VAPOURSYNTH_API_VERSION ((VAPOURSYNTH_API_MAJOR << 16) | (VAPOURSYNTH_API_MINOR))
  369. +
  370. +/* Convenience for C++ users. */
  371. +#ifdef __cplusplus
  372. +#    define VS_EXTERN_C extern "C"
  373. +#    if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
  374. +#        define VS_NOEXCEPT noexcept
  375. +#    else
  376. +#        define VS_NOEXCEPT
  377. +#    endif
  378. +#else
  379. +#    define VS_EXTERN_C
  380. +#    define VS_NOEXCEPT
  381. +#endif
  382. +
  383. +#if defined(_WIN32) && !defined(_WIN64)
  384. +#    define VS_CC __stdcall
  385. +#else
  386. +#    define VS_CC
  387. +#endif
  388. +
  389. +/* And now for some symbol hide-and-seek... */
  390. +#if defined(_WIN32) /* Windows being special */
  391. +#    define VS_EXTERNAL_API(ret) VS_EXTERN_C __declspec(dllexport) ret VS_CC
  392. +#elif defined(__GNUC__) && __GNUC__ >= 4
  393. +#    define VS_EXTERNAL_API(ret) VS_EXTERN_C __attribute__((visibility("default"))) ret VS_CC
  394. +#else
  395. +#    define VS_EXTERNAL_API(ret) VS_EXTERN_C ret VS_CC
  396. +#endif
  397. +
  398. +#if !defined(VS_CORE_EXPORTS) && defined(_WIN32)
  399. +#    define VS_API(ret) VS_EXTERN_C __declspec(dllimport) ret VS_CC
  400. +#else
  401. +#    define VS_API(ret) VS_EXTERNAL_API(ret)
  402. +#endif
  403. +
  404. +typedef struct VSFrameRef VSFrameRef;
  405. +typedef struct VSNodeRef VSNodeRef;
  406. +typedef struct VSCore VSCore;
  407. +typedef struct VSPlugin VSPlugin;
  408. +typedef struct VSNode VSNode;
  409. +typedef struct VSFuncRef VSFuncRef;
  410. +typedef struct VSMap VSMap;
  411. +typedef struct VSAPI VSAPI;
  412. +typedef struct VSFrameContext VSFrameContext;
  413. +
  414. +typedef enum VSColorFamily {
  415. +    /* all planar formats */
  416. +    cmGray   = 1000000,
  417. +    cmRGB    = 2000000,
  418. +    cmYUV    = 3000000,
  419. +    cmYCoCg  = 4000000,
  420. +    /* special for compatibility */
  421. +    cmCompat = 9000000
  422. +} VSColorFamily;
  423. +
  424. +typedef enum VSSampleType {
  425. +    stInteger = 0,
  426. +    stFloat = 1
  427. +} VSSampleType;
  428. +
  429. +/* The +10 is so people won't be using the constants interchangably "by accident" */
  430. +typedef enum VSPresetFormat {
  431. +    pfNone = 0,
  432. +
  433. +    pfGray8 = cmGray + 10,
  434. +    pfGray16,
  435. +
  436. +    pfGrayH,
  437. +    pfGrayS,
  438. +
  439. +    pfYUV420P8 = cmYUV + 10,
  440. +    pfYUV422P8,
  441. +    pfYUV444P8,
  442. +    pfYUV410P8,
  443. +    pfYUV411P8,
  444. +    pfYUV440P8,
  445. +
  446. +    pfYUV420P9,
  447. +    pfYUV422P9,
  448. +    pfYUV444P9,
  449. +
  450. +    pfYUV420P10,
  451. +    pfYUV422P10,
  452. +    pfYUV444P10,
  453. +
  454. +    pfYUV420P16,
  455. +    pfYUV422P16,
  456. +    pfYUV444P16,
  457. +
  458. +    pfYUV444PH,
  459. +    pfYUV444PS,
  460. +
  461. +    pfYUV420P12,
  462. +    pfYUV422P12,
  463. +    pfYUV444P12,
  464. +
  465. +    pfYUV420P14,
  466. +    pfYUV422P14,
  467. +    pfYUV444P14,
  468. +
  469. +    pfRGB24 = cmRGB + 10,
  470. +    pfRGB27,
  471. +    pfRGB30,
  472. +    pfRGB48,
  473. +
  474. +    pfRGBH,
  475. +    pfRGBS,
  476. +
  477. +    /* special for compatibility, if you implement these in any filter I'll personally kill you */
  478. +    /* I'll also change their ids around to break your stuff regularly */
  479. +    pfCompatBGR32 = cmCompat + 10,
  480. +    pfCompatYUY2
  481. +} VSPresetFormat;
  482. +
  483. +typedef enum VSFilterMode {
  484. +    fmParallel = 100, /* completely parallel execution */
  485. +    fmParallelRequests = 200, /* for filters that are serial in nature but can request one or more frames they need in advance */
  486. +    fmUnordered = 300, /* for filters that modify their internal state every request */
  487. +    fmSerial = 400 /* for source filters and compatibility with other filtering architectures */
  488. +} VSFilterMode;
  489. +
  490. +typedef struct VSFormat {
  491. +    char name[32];
  492. +    int id;
  493. +    int colorFamily; /* see VSColorFamily */
  494. +    int sampleType; /* see VSSampleType */
  495. +    int bitsPerSample; /* number of significant bits */
  496. +    int bytesPerSample; /* actual storage is always in a power of 2 and the smallest possible that can fit the number of bits used per sample */
  497. +
  498. +    int subSamplingW; /* log2 subsampling factor, applied to second and third plane */
  499. +    int subSamplingH;
  500. +
  501. +    int numPlanes; /* implicit from colorFamily */
  502. +} VSFormat;
  503. +
  504. +typedef enum VSNodeFlags {
  505. +    nfNoCache    = 1,
  506. +    nfIsCache    = 2,
  507. +    nfMakeLinear = 4 /* api 3.3 */
  508. +} VSNodeFlags;
  509. +
  510. +typedef enum VSPropTypes {
  511. +    ptUnset = 'u',
  512. +    ptInt = 'i',
  513. +    ptFloat = 'f',
  514. +    ptData = 's',
  515. +    ptNode = 'c',
  516. +    ptFrame = 'v',
  517. +    ptFunction = 'm'
  518. +} VSPropTypes;
  519. +
  520. +typedef enum VSGetPropErrors {
  521. +    peUnset = 1,
  522. +    peType  = 2,
  523. +    peIndex = 4
  524. +} VSGetPropErrors;
  525. +
  526. +typedef enum VSPropAppendMode {
  527. +    paReplace = 0,
  528. +    paAppend  = 1,
  529. +    paTouch   = 2
  530. +} VSPropAppendMode;
  531. +
  532. +typedef struct VSCoreInfo {
  533. +    const char *versionString;
  534. +    int core;
  535. +    int api;
  536. +    int numThreads;
  537. +    int64_t maxFramebufferSize;
  538. +    int64_t usedFramebufferSize;
  539. +} VSCoreInfo;
  540. +
  541. +typedef struct VSVideoInfo {
  542. +    const VSFormat *format;
  543. +    int64_t fpsNum;
  544. +    int64_t fpsDen;
  545. +    int width;
  546. +    int height;
  547. +    int numFrames; /* api 3.2 - no longer allowed to be 0 */
  548. +    int flags;
  549. +} VSVideoInfo;
  550. +
  551. +typedef enum VSActivationReason {
  552. +    arInitial = 0,
  553. +    arFrameReady = 1,
  554. +    arAllFramesReady = 2,
  555. +    arError = -1
  556. +} VSActivationReason;
  557. +
  558. +typedef enum VSMessageType {
  559. +    mtDebug = 0,
  560. +    mtWarning = 1,
  561. +    mtCritical = 2,
  562. +    mtFatal = 3
  563. +} VSMessageType;
  564. +
  565. +/* core entry point */
  566. +typedef const VSAPI *(VS_CC *VSGetVapourSynthAPI)(int version);
  567. +
  568. +/* plugin function and filter typedefs */
  569. +typedef void (VS_CC *VSPublicFunction)(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi);
  570. +typedef void (VS_CC *VSRegisterFunction)(const char *name, const char *args, VSPublicFunction argsFunc, void *functionData, VSPlugin *plugin);
  571. +typedef void (VS_CC *VSConfigPlugin)(const char *identifier, const char *defaultNamespace, const char *name, int apiVersion, int readonly, VSPlugin *plugin);
  572. +typedef void (VS_CC *VSInitPlugin)(VSConfigPlugin configFunc, VSRegisterFunction registerFunc, VSPlugin *plugin);
  573. +typedef void (VS_CC *VSFreeFuncData)(void *userData);
  574. +typedef void (VS_CC *VSFilterInit)(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi);
  575. +typedef const VSFrameRef *(VS_CC *VSFilterGetFrame)(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi);
  576. +typedef void (VS_CC *VSFilterFree)(void *instanceData, VSCore *core, const VSAPI *vsapi);
  577. +
  578. +/* other */
  579. +typedef void (VS_CC *VSFrameDoneCallback)(void *userData, const VSFrameRef *f, int n, VSNodeRef *, const char *errorMsg);
  580. +typedef void (VS_CC *VSMessageHandler)(int msgType, const char *msg, void *userData);
  581. +
  582. +struct VSAPI {
  583. +    VSCore *(VS_CC *createCore)(int threads) VS_NOEXCEPT;
  584. +    void (VS_CC *freeCore)(VSCore *core) VS_NOEXCEPT;
  585. +    const VSCoreInfo *(VS_CC *getCoreInfo)(VSCore *core) VS_NOEXCEPT;
  586. +
  587. +    const VSFrameRef *(VS_CC *cloneFrameRef)(const VSFrameRef *f) VS_NOEXCEPT;
  588. +    VSNodeRef *(VS_CC *cloneNodeRef)(VSNodeRef *node) VS_NOEXCEPT;
  589. +    VSFuncRef *(VS_CC *cloneFuncRef)(VSFuncRef *f) VS_NOEXCEPT;
  590. +
  591. +    void (VS_CC *freeFrame)(const VSFrameRef *f) VS_NOEXCEPT;
  592. +    void (VS_CC *freeNode)(VSNodeRef *node) VS_NOEXCEPT;
  593. +    void (VS_CC *freeFunc)(VSFuncRef *f) VS_NOEXCEPT;
  594. +
  595. +    VSFrameRef *(VS_CC *newVideoFrame)(const VSFormat *format, int width, int height, const VSFrameRef *propSrc, VSCore *core) VS_NOEXCEPT;
  596. +    VSFrameRef *(VS_CC *copyFrame)(const VSFrameRef *f, VSCore *core) VS_NOEXCEPT;
  597. +    void (VS_CC *copyFrameProps)(const VSFrameRef *src, VSFrameRef *dst, VSCore *core) VS_NOEXCEPT;
  598. +
  599. +    void (VS_CC *registerFunction)(const char *name, const char *args, VSPublicFunction argsFunc, void *functionData, VSPlugin *plugin) VS_NOEXCEPT;
  600. +    VSPlugin *(VS_CC *getPluginById)(const char *identifier, VSCore *core) VS_NOEXCEPT;
  601. +    VSPlugin *(VS_CC *getPluginByNs)(const char *ns, VSCore *core) VS_NOEXCEPT;
  602. +    VSMap *(VS_CC *getPlugins)(VSCore *core) VS_NOEXCEPT;
  603. +    VSMap *(VS_CC *getFunctions)(VSPlugin *plugin) VS_NOEXCEPT;
  604. +    void (VS_CC *createFilter)(const VSMap *in, VSMap *out, const char *name, VSFilterInit init, VSFilterGetFrame getFrame, VSFilterFree free, int filterMode, int flags, void *instanceData, VSCore *core) VS_NOEXCEPT;
  605. +    void (VS_CC *setError)(VSMap *map, const char *errorMessage) VS_NOEXCEPT; /* use to signal errors outside filter getframe functions */
  606. +    const char *(VS_CC *getError)(const VSMap *map) VS_NOEXCEPT; /* use to query errors, returns 0 if no error */
  607. +    void (VS_CC *setFilterError)(const char *errorMessage, VSFrameContext *frameCtx) VS_NOEXCEPT; /* use to signal errors in the filter getframe function */
  608. +    VSMap *(VS_CC *invoke)(VSPlugin *plugin, const char *name, const VSMap *args) VS_NOEXCEPT;
  609. +
  610. +    const VSFormat *(VS_CC *getFormatPreset)(int id, VSCore *core) VS_NOEXCEPT;
  611. +    const VSFormat *(VS_CC *registerFormat)(int colorFamily, int sampleType, int bitsPerSample, int subSamplingW, int subSamplingH, VSCore *core) VS_NOEXCEPT;
  612. +
  613. +    const VSFrameRef *(VS_CC *getFrame)(int n, VSNodeRef *node, char *errorMsg, int bufSize) VS_NOEXCEPT; /* do never use inside a filter's getframe function, for external applications using the core as a library or for requesting frames in a filter constructor */
  614. +    void (VS_CC *getFrameAsync)(int n, VSNodeRef *node, VSFrameDoneCallback callback, void *userData) VS_NOEXCEPT; /* do never use inside a filter's getframe function, for external applications using the core as a library or for requesting frames in a filter constructor */
  615. +    const VSFrameRef *(VS_CC *getFrameFilter)(int n, VSNodeRef *node, VSFrameContext *frameCtx) VS_NOEXCEPT; /* only use inside a filter's getframe function */
  616. +    void (VS_CC *requestFrameFilter)(int n, VSNodeRef *node, VSFrameContext *frameCtx) VS_NOEXCEPT; /* only use inside a filter's getframe function */
  617. +    void (VS_CC *queryCompletedFrame)(VSNodeRef **node, int *n, VSFrameContext *frameCtx) VS_NOEXCEPT; /* only use inside a filter's getframe function */
  618. +    void (VS_CC *releaseFrameEarly)(VSNodeRef *node, int n, VSFrameContext *frameCtx) VS_NOEXCEPT; /* only use inside a filter's getframe function */
  619. +
  620. +    int (VS_CC *getStride)(const VSFrameRef *f, int plane) VS_NOEXCEPT;
  621. +    const uint8_t *(VS_CC *getReadPtr)(const VSFrameRef *f, int plane) VS_NOEXCEPT;
  622. +    uint8_t *(VS_CC *getWritePtr)(VSFrameRef *f, int plane) VS_NOEXCEPT;
  623. +
  624. +    VSFuncRef *(VS_CC *createFunc)(VSPublicFunction func, void *userData, VSFreeFuncData free, VSCore *core, const VSAPI *vsapi) VS_NOEXCEPT;
  625. +    void (VS_CC *callFunc)(VSFuncRef *func, const VSMap *in, VSMap *out, VSCore *core, const VSAPI *vsapi) VS_NOEXCEPT; /* core and vsapi arguments are completely ignored, they only remain to preserve ABI */
  626. +
  627. +    /* property access functions */
  628. +    VSMap *(VS_CC *createMap)(void) VS_NOEXCEPT;
  629. +    void (VS_CC *freeMap)(VSMap *map) VS_NOEXCEPT;
  630. +    void (VS_CC *clearMap)(VSMap *map) VS_NOEXCEPT;
  631. +
  632. +    const VSVideoInfo *(VS_CC *getVideoInfo)(VSNodeRef *node) VS_NOEXCEPT;
  633. +    void (VS_CC *setVideoInfo)(const VSVideoInfo *vi, int numOutputs, VSNode *node) VS_NOEXCEPT;
  634. +    const VSFormat *(VS_CC *getFrameFormat)(const VSFrameRef *f) VS_NOEXCEPT;
  635. +    int (VS_CC *getFrameWidth)(const VSFrameRef *f, int plane) VS_NOEXCEPT;
  636. +    int (VS_CC *getFrameHeight)(const VSFrameRef *f, int plane) VS_NOEXCEPT;
  637. +    const VSMap *(VS_CC *getFramePropsRO)(const VSFrameRef *f) VS_NOEXCEPT;
  638. +    VSMap *(VS_CC *getFramePropsRW)(VSFrameRef *f) VS_NOEXCEPT;
  639. +
  640. +    int (VS_CC *propNumKeys)(const VSMap *map) VS_NOEXCEPT;
  641. +    const char *(VS_CC *propGetKey)(const VSMap *map, int index) VS_NOEXCEPT;
  642. +    int (VS_CC *propNumElements)(const VSMap *map, const char *key) VS_NOEXCEPT;
  643. +    char (VS_CC *propGetType)(const VSMap *map, const char *key) VS_NOEXCEPT;
  644. +
  645. +    int64_t(VS_CC *propGetInt)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT;
  646. +    double(VS_CC *propGetFloat)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT;
  647. +    const char *(VS_CC *propGetData)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT;
  648. +    int (VS_CC *propGetDataSize)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT;
  649. +    VSNodeRef *(VS_CC *propGetNode)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT;
  650. +    const VSFrameRef *(VS_CC *propGetFrame)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT;
  651. +    VSFuncRef *(VS_CC *propGetFunc)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT;
  652. +
  653. +    int (VS_CC *propDeleteKey)(VSMap *map, const char *key) VS_NOEXCEPT;
  654. +    int (VS_CC *propSetInt)(VSMap *map, const char *key, int64_t i, int append) VS_NOEXCEPT;
  655. +    int (VS_CC *propSetFloat)(VSMap *map, const char *key, double d, int append) VS_NOEXCEPT;
  656. +    int (VS_CC *propSetData)(VSMap *map, const char *key, const char *data, int size, int append) VS_NOEXCEPT;
  657. +    int (VS_CC *propSetNode)(VSMap *map, const char *key, VSNodeRef *node, int append) VS_NOEXCEPT;
  658. +    int (VS_CC *propSetFrame)(VSMap *map, const char *key, const VSFrameRef *f, int append) VS_NOEXCEPT;
  659. +    int (VS_CC *propSetFunc)(VSMap *map, const char *key, VSFuncRef *func, int append) VS_NOEXCEPT;
  660. +
  661. +    int64_t (VS_CC *setMaxCacheSize)(int64_t bytes, VSCore *core) VS_NOEXCEPT;
  662. +    int (VS_CC *getOutputIndex)(VSFrameContext *frameCtx) VS_NOEXCEPT;
  663. +    VSFrameRef *(VS_CC *newVideoFrame2)(const VSFormat *format, int width, int height, const VSFrameRef **planeSrc, const int *planes, const VSFrameRef *propSrc, VSCore *core) VS_NOEXCEPT;
  664. +    void (VS_CC *setMessageHandler)(VSMessageHandler handler, void *userData) VS_NOEXCEPT;
  665. +    int (VS_CC *setThreadCount)(int threads, VSCore *core) VS_NOEXCEPT;
  666. +
  667. +    const char *(VS_CC *getPluginPath)(const VSPlugin *plugin) VS_NOEXCEPT;
  668. +
  669. +    /* api 3.1 */
  670. +    const int64_t *(VS_CC *propGetIntArray)(const VSMap *map, const char *key, int *error) VS_NOEXCEPT;
  671. +    const double *(VS_CC *propGetFloatArray)(const VSMap *map, const char *key, int *error) VS_NOEXCEPT;
  672. +
  673. +    int (VS_CC *propSetIntArray)(VSMap *map, const char *key, const int64_t *i, int size) VS_NOEXCEPT;
  674. +    int (VS_CC *propSetFloatArray)(VSMap *map, const char *key, const double *d, int size) VS_NOEXCEPT;
  675. +
  676. +    /* api 3.4 */
  677. +    void (VS_CC *logMessage)(int msgType, const char *msg) VS_NOEXCEPT;
  678. +};
  679. +
  680. +VS_API(const VSAPI *) getVapourSynthAPI(int version) VS_NOEXCEPT;
  681. +
  682. +#endif /* VAPOURSYNTH_H */
  683. diff -urN ./x264.src/input/input.h ./x264.vpy/input/input.h
  684. --- ./x264.src/input/input.h    2017-06-29 09:28:58 +0000
  685. +++ ./x264.vpy/input/input.h    2018-04-25 21:23:18 +0000
  686. @@ -101,6 +101,7 @@
  687.  
  688.  extern const cli_input_t raw_input;
  689.  extern const cli_input_t y4m_input;
  690. +extern const cli_input_t vpy_input;
  691.  extern const cli_input_t avs_input;
  692.  extern const cli_input_t thread_input;
  693.  extern const cli_input_t lavf_input;
  694. diff -urN ./x264.src/input/vpy.c ./x264.vpy/input/vpy.c
  695. --- ./x264.src/input/vpy.c  1970-01-01 00:00:00 +0000
  696. +++ ./x264.vpy/input/vpy.c  2018-04-28 18:17:02 +0000
  697. @@ -0,0 +1,313 @@
  698. +/*****************************************************************************
  699. + * vpy.c: VapourSynth input
  700. + *****************************************************************************
  701. + * Copyright (C) 2009-2018 x264 project
  702. + *
  703. + * Author: Vladimir Kontserenko <djatom@beatrice-raws.org>
  704. + * Some portions of code and ideas taken for avs.c, y4m.c files, "ffmpeg demuxer"
  705. + * and from rigaya's NVEnc codebase.
  706. + *
  707. + * This program is free software; you can redistribute it and/or modify
  708. + * it under the terms of the GNU General Public License as published by
  709. + * the Free Software Foundation; either version 2 of the License, or
  710. + * (at your option) any later version.
  711. + *
  712. + * This program is distributed in the hope that it will be useful,
  713. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  714. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  715. + * GNU General Public License for more details.
  716. + *
  717. + * You should have received a copy of the GNU General Public License
  718. + * along with this program; if not, write to the Free Software
  719. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  720. + *
  721. + * This program is also available under a commercial proprietary license.
  722. + * For more information, contact us at licensing@x264.com.
  723. + *****************************************************************************/
  724. +
  725. +#include "input.h"
  726. +#include <stdatomic.h>
  727. +#include "extras/VSScript.h"
  728. +#include "extras/VSHelper.h"
  729. +
  730. +#ifdef _M_IX86
  731. +#define VPY_X64 0
  732. +#else
  733. +#define VPY_X64 1
  734. +#endif
  735. +
  736. +#ifdef __unix__
  737. +#include <dlfcn.h>
  738. +#include <unistd.h>
  739. +#include <ctype.h>
  740. +#define vs_sleep sleep
  741. +#define vs_strtok strtok_r
  742. +#define vs_sscanf sscanf
  743. +#ifdef __MACH__
  744. +#define vs_open() dlopen( "libvapoursynth-script.dylib", RTLD_NOW )
  745. +#else
  746. +#define vs_open() dlopen( "libvapoursynth-script.so", RTLD_NOW )
  747. +#endif
  748. +#define vs_close dlclose
  749. +#define vs_address dlsym
  750. +#else
  751. +#define vs_sleep Sleep
  752. +#define vs_strtok strtok_s
  753. +#define vs_sscanf sscanf_s
  754. +#define vs_open() LoadLibraryW( L"vsscript" )
  755. +#define vs_close FreeLibrary
  756. +#define vs_address GetProcAddress
  757. +#endif
  758. +
  759. +#define DECLARE_VS_FUNC(name) func_##name name
  760. +
  761. +#define FAIL_IF_ERROR( cond, ... ) FAIL_IF_ERR( cond, "vpy", __VA_ARGS__ )
  762. +
  763. +#define LOAD_VS_FUNC(name, namex86)\
  764. +{\
  765. +    h->func.name = (void*)vs_address( h->library, (VPY_X64) ? #name : namex86 );\
  766. +    if( !h->func.name )\
  767. +        goto fail;\
  768. +}
  769. +
  770. +typedef int (VS_CC *func_vsscript_init)(void);
  771. +typedef int (VS_CC *func_vsscript_finalize)(void);
  772. +typedef int (VS_CC *func_vsscript_evaluateFile)(VSScript **handle, const char *scriptFilename, int flags);
  773. +typedef void (VS_CC *func_vsscript_freeScript)(VSScript *handle);
  774. +typedef const char * (VS_CC *func_vsscript_getError)(VSScript *handle);
  775. +typedef VSNodeRef * (VS_CC *func_vsscript_getOutput)(VSScript *handle, int index);
  776. +typedef VSCore * (VS_CC *func_vsscript_getCore)(VSScript *handle);
  777. +typedef const VSAPI * (VS_CC *func_vsscript_getVSApi2)(int version);
  778. +
  779. +typedef struct VapourSynthContext {
  780. +    void *library;
  781. +    const VSAPI *vsapi;
  782. +    VSScript *script;
  783. +    VSNodeRef *node;
  784. +    int curr_frame;
  785. +    int ncpu;
  786. +    atomic_int async_pending;
  787. +    int num_frames;
  788. +    int bit_depth;
  789. +    uint64_t plane_size[3];
  790. +    int uc_depth;
  791. +    struct
  792. +    {
  793. +        DECLARE_VS_FUNC( vsscript_init );
  794. +        DECLARE_VS_FUNC( vsscript_finalize );
  795. +        DECLARE_VS_FUNC( vsscript_evaluateFile );
  796. +        DECLARE_VS_FUNC( vsscript_freeScript );
  797. +        DECLARE_VS_FUNC( vsscript_getError );
  798. +        DECLARE_VS_FUNC( vsscript_getOutput );
  799. +        DECLARE_VS_FUNC( vsscript_getCore );
  800. +        DECLARE_VS_FUNC( vsscript_getVSApi2 );
  801. +    } func;
  802. +} VapourSynthContext;
  803. +
  804. +static int x264_vs_load_library( VapourSynthContext *h )
  805. +{
  806. +    h->library = vs_open();
  807. +    if( !h->library )
  808. +        return -1;
  809. +    LOAD_VS_FUNC( vsscript_init, "_vsscript_init@0" );
  810. +    LOAD_VS_FUNC( vsscript_finalize, "_vsscript_finalize@0" );
  811. +    LOAD_VS_FUNC( vsscript_evaluateFile, "_vsscript_evaluateFile@12" );
  812. +    LOAD_VS_FUNC( vsscript_freeScript, "_vsscript_freeScript@4" );
  813. +    LOAD_VS_FUNC( vsscript_getError, "_vsscript_getError@4" );
  814. +    LOAD_VS_FUNC( vsscript_getOutput, "_vsscript_getOutput@8" );
  815. +    LOAD_VS_FUNC( vsscript_getCore, "_vsscript_getCore@4" );
  816. +    LOAD_VS_FUNC( vsscript_getVSApi2, "_vsscript_getVSApi2@4" );
  817. +    return 0;
  818. +fail:
  819. +    vs_close( h->library );
  820. +    h->library = NULL;
  821. +    return -1;
  822. +}
  823. +
  824. +static void VS_CC async_callback( void *user_data, const VSFrameRef *f, int n, VSNodeRef *node, const char *error_msg )
  825. +{
  826. +    VapourSynthContext *h = user_data;
  827. +
  828. +    if (!f) {
  829. +        x264_cli_log( "vpy", X264_LOG_WARNING, "async frame request failed: %s\n", error_msg );
  830. +    }
  831. +
  832. +    h->vsapi->freeFrame( f );
  833. +    atomic_fetch_sub( &h->async_pending, 1 );
  834. +}
  835. +
  836. +/* slightly modified rigaya's VersionString parser */
  837. +int get_core_revision(const char *vsVersionString)
  838. +{
  839. +    char *api_info = NULL;
  840. +    char buf[1024];
  841. +    strcpy( buf, vsVersionString );
  842. +    for ( char *p = buf, *q = NULL, *r = NULL; NULL != ( q = vs_strtok( p, "\n", &r ) ); ) {
  843. +        if ( NULL != ( api_info = strstr( q, "Core" ) ) ) {
  844. +            strcpy( buf, api_info );
  845. +            for ( char *s = buf; *s; s++ )
  846. +                *s = (char)tolower( *s );
  847. +            int rev = 0;
  848. +            return ( 1 == vs_sscanf( buf, "core r%d", &rev ) ) ? rev : 0;
  849. +        }
  850. +        p = NULL;
  851. +    }
  852. +    return 0;
  853. +}
  854. +
  855. +static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt )
  856. +{
  857. +    FILE *fh = x264_fopen( psz_filename, "r" );
  858. +    if( !fh )
  859. +        return -1;
  860. +    int b_regular = x264_is_regular_file( fh );
  861. +    fclose( fh );
  862. +    FAIL_IF_ERROR( !b_regular, "VPY input is incompatible with non-regular file `%s'\n", psz_filename );
  863. +
  864. +    VapourSynthContext *h = calloc( 1, sizeof(VapourSynthContext) );
  865. +    if( !h )
  866. +        return -1;
  867. +    FAIL_IF_ERROR( x264_vs_load_library( h ), "failed to load VapourSynth\n" );
  868. +    if( !h->func.vsscript_init() )
  869. +        FAIL_IF_ERROR( 1, "failed to initialize VapourSynth environment\n" );
  870. +    h->vsapi = h->func.vsscript_getVSApi2( VAPOURSYNTH_API_VERSION );
  871. +    FAIL_IF_ERROR( !h->vsapi, "failed to get vapoursynth API\n" );
  872. +    if( h->func.vsscript_evaluateFile( &h->script, (const char *)psz_filename, efSetWorkingDir ) )
  873. +        FAIL_IF_ERROR( 1, "Can't evaluate script: %s\n",  h->func.vsscript_getError( h->script ) );
  874. +    h->node = h->func.vsscript_getOutput( h->script, 0 );
  875. +    FAIL_IF_ERROR( !h->node, "`%s' has no video data\n", psz_filename );
  876. +
  877. +    const VSCoreInfo *core_info = h->vsapi->getCoreInfo( h->func.vsscript_getCore( h->script ) );
  878. +    const VSVideoInfo *vi = h->vsapi->getVideoInfo( h->node );
  879. +    FAIL_IF_ERROR( !isConstantFormat(vi), "only constant video formats are supported\n" );
  880. +    x264_cli_log( "vpy", X264_LOG_INFO, "using VapourSynth Video Processing Library Core R%d\n", get_core_revision( core_info->versionString ) );
  881. +    info->width = vi->width;
  882. +    info->height = vi->height;
  883. +    info->fps_num = vi->fpsNum;
  884. +    info->fps_den = vi->fpsDen;
  885. +    h->num_frames = info->num_frames = vi->numFrames;
  886. +    h->bit_depth = vi->format->bitsPerSample;
  887. +    info->thread_safe = 1;
  888. +    h->ncpu = core_info->numThreads;
  889. +    h->uc_depth = (h->bit_depth & 7) && (vi->format->colorFamily == cmYUV || vi->format->colorFamily == cmYCoCg);
  890. +
  891. +    if( vi->format->id == pfRGB48 )
  892. +        info->csp = X264_CSP_BGR | X264_CSP_VFLIP | X264_CSP_HIGH_DEPTH;
  893. +    else if( vi->format->id == pfRGB24 )
  894. +        info->csp = X264_CSP_BGR | X264_CSP_VFLIP;
  895. +    else if( vi->format->id == pfYUV444P9 || vi->format->id == pfYUV444P10 || vi->format->id == pfYUV444P12 || vi->format->id == pfYUV444P14 || vi->format->id == pfYUV444P16)
  896. +        info->csp = X264_CSP_I444 | X264_CSP_HIGH_DEPTH;
  897. +    else if( vi->format->id == pfYUV422P9 || vi->format->id == pfYUV422P10 || vi->format->id == pfYUV422P12 || vi->format->id == pfYUV422P14 || vi->format->id == pfYUV422P16)
  898. +        info->csp = X264_CSP_I422 | X264_CSP_HIGH_DEPTH;
  899. +    else if( vi->format->id == pfYUV420P9 || vi->format->id == pfYUV420P10 || vi->format->id == pfYUV420P12 || vi->format->id == pfYUV420P14 || vi->format->id == pfYUV420P16)
  900. +        info->csp = X264_CSP_I420 | X264_CSP_HIGH_DEPTH;
  901. +    else if( vi->format->id == pfYUV444P8 )
  902. +        info->csp = X264_CSP_I444;
  903. +    else if( vi->format->id == pfYUV422P8 )
  904. +        info->csp = X264_CSP_I422;
  905. +    else if( vi->format->id == pfYUV420P8 )
  906. +        info->csp = X264_CSP_I420;
  907. +    else
  908. +        FAIL_IF_ERROR( 1, "not supported pixel type: %s\n", vi->format->name );
  909. +
  910. +    /* since VapourSynth supports vfr internally, it would be great to implement handling for it someday */
  911. +    info->vfr = 0;
  912. +
  913. +    /* bitdepth upconversion stuff */
  914. +    if( h->uc_depth ) {
  915. +        const x264_cli_csp_t *cli_csp = x264_cli_get_csp( info->csp );
  916. +        for( int i = 0; i < cli_csp->planes; i++ ) {
  917. +            h->plane_size[i] = x264_cli_pic_plane_size( info->csp, info->width, info->height, i );
  918. +            h->plane_size[i] /= x264_cli_csp_depth_factor( info->csp );
  919. +        }
  920. +    }
  921. +
  922. +    *p_handle = h;
  923. +
  924. +    return 0;
  925. +}
  926. +
  927. +static int picture_alloc( cli_pic_t *pic, hnd_t handle, int csp, int width, int height )
  928. +{
  929. +    if( x264_cli_pic_alloc( pic, X264_CSP_NONE, width, height ) )
  930. +        return -1;
  931. +    pic->img.csp = csp;
  932. +    const x264_cli_csp_t *cli_csp = x264_cli_get_csp( csp );
  933. +    if( cli_csp )
  934. +        pic->img.planes = cli_csp->planes;
  935. +    return 0;
  936. +}
  937. +
  938. +static int read_frame( cli_pic_t *pic, hnd_t handle, int i_frame )
  939. +{
  940. +    static const int planes[3] = { 0, 1, 2 };
  941. +    char errbuf[256];
  942. +    const VSFrameRef *frm = NULL;
  943. +    VapourSynthContext *h = handle;
  944. +
  945. +    if( i_frame >= h->num_frames )
  946. +        return -1;
  947. +
  948. +    /* explicitly cast away the const attribute to avoid a warning */
  949. +    frm = pic->opaque = (VSFrameRef*)h->vsapi->getFrame( i_frame, h->node, errbuf, sizeof(errbuf) );
  950. +    FAIL_IF_ERROR( !frm, "%s occurred while reading frame %d\n", errbuf, i_frame );
  951. +
  952. +    /* Prefetch the subsequent frames. */
  953. +    for ( int i = 0; i < h->ncpu; ++i ) {
  954. +        if ( i >= h->num_frames - i_frame )
  955. +            break;
  956. +        h->vsapi->getFrameAsync( i_frame + i, h->node, async_callback, h );
  957. +        atomic_fetch_add( &h->async_pending, 1 );
  958. +    }
  959. +
  960. +    for( int i = 0; i < pic->img.planes; i++ ) {
  961. +        /* explicitly cast away the const attribute to avoid a warning */
  962. +        pic->img.plane[i] = (uint8_t*)h->vsapi->getReadPtr( frm, planes[i] );
  963. +        pic->img.stride[i] = h->vsapi->getStride( frm, planes[i] );
  964. +        if( h->uc_depth ) {
  965. +            /* upconvert non 16bit high depth planes to 16bit using the same
  966. +             * algorithm as used in the depth filter. */
  967. +            uint16_t *plane = (uint16_t*)pic->img.plane[i];
  968. +            uint64_t pixel_count = h->plane_size[i];
  969. +            int lshift = 16 - h->bit_depth;
  970. +            for( uint64_t j = 0; j < pixel_count; j++ )
  971. +                plane[j] = plane[j] << lshift;
  972. +        }
  973. +    }
  974. +    return 0;
  975. +}
  976. +
  977. +static int release_frame( cli_pic_t *pic, hnd_t handle )
  978. +{
  979. +    VapourSynthContext *h = handle;
  980. +    h->vsapi->freeFrame( pic->opaque );
  981. +    return 0;
  982. +}
  983. +
  984. +static void picture_clean( cli_pic_t *pic, hnd_t handle )
  985. +{
  986. +    memset( pic, 0, sizeof(cli_pic_t) );
  987. +}
  988. +
  989. +static int close_file( hnd_t handle )
  990. +{
  991. +    VapourSynthContext *h = handle;
  992. +
  993. +    /* Wait for any async requests to complete. */
  994. +    while ( atomic_load( &h->async_pending ) ) {
  995. +        vs_sleep( 1 );
  996. +    }
  997. +
  998. +    h->vsapi->freeNode( h->node );
  999. +    h->func.vsscript_freeScript( h->script );
  1000. +    h->func.vsscript_finalize();
  1001. +
  1002. +    if( h->library )
  1003. +        vs_close( h->library );
  1004. +
  1005. +    free( h );
  1006. +    return 0;
  1007. +}
  1008. +
  1009. +const cli_input_t vpy_input = { open_file, picture_alloc, read_frame, release_frame, picture_clean, close_file };
  1010. \ No newline at end of file
  1011. diff -urN ./x264.src/x264.c ./x264.vpy/x264.c
  1012. --- ./x264.src/x264.c   2017-10-28 21:37:39 +0000
  1013. +++ ./x264.vpy/x264.c   2018-04-28 15:56:02 +0000
  1014. @@ -169,6 +169,9 @@
  1015.      "auto",
  1016.      "raw",
  1017.      "y4m",
  1018. +#if HAVE_VPY
  1019. +    "vpy",
  1020. +#endif
  1021.  #if HAVE_AVS
  1022.      "avs",
  1023.  #endif
  1024. @@ -538,6 +541,7 @@
  1025.          "\n"
  1026.          "Infile can be raw (in which case resolution is required),\n"
  1027.          "  or YUV4MPEG (*.y4m),\n"
  1028. +        "  or VapourSynth if compiled with support (%s).\n"
  1029.          "  or Avisynth if compiled with support (%s).\n"
  1030.          "  or libav* formats if compiled with lavf support (%s) or ffms support (%s).\n"
  1031.          "Outfile type is selected by filename:\n"
  1032. @@ -554,6 +558,11 @@
  1033.          "      --fullhelp              List all options\n"
  1034.          "\n",
  1035.          X264_BUILD, X264_VERSION,
  1036. +#if HAVE_VPY
  1037. +        "yes",
  1038. +#else
  1039. +        "no",
  1040. +#endif
  1041.  #if HAVE_AVS
  1042.          "yes",
  1043.  #else
  1044. @@ -1293,7 +1302,15 @@
  1045.          return -1;
  1046.  #endif
  1047.      }
  1048. -    else if( !strcasecmp( module, "y4m" ) )
  1049. +    else if( !strcasecmp( module, "vpy" ) ) {
  1050. +#if HAVE_VPY
  1051. +        cli_input = vpy_input;
  1052. +        module = "vpy";
  1053. +#else
  1054. +        x264_cli_log( "x264", X264_LOG_ERROR, "not compiled with VPY input support\n" );
  1055. +        return -1;
  1056. +#endif
  1057. +    } else if( !strcasecmp( module, "y4m" ) )
  1058.          cli_input = y4m_input;
  1059.      else if( !strcasecmp( module, "raw" ) || !strcasecmp( ext, "yuv" ) )
  1060.          cli_input = raw_input;
  1061. @@ -1317,6 +1334,15 @@
  1062.              cli_input = lavf_input;
  1063.          }
  1064.  #endif
  1065. +#if HAVE_VPY
  1066. +        if( b_regular && (b_auto || !strcasecmp( demuxer, "vpy" )) &&
  1067. +            !vpy_input.open_file( filename, p_handle, info, opt ) )
  1068. +        {
  1069. +            module = "vpy";
  1070. +            b_auto = 0;
  1071. +            cli_input = vpy_input;
  1072. +        }
  1073. +#endif
  1074.  #if HAVE_AVS
  1075.          if( b_regular && (b_auto || !strcasecmp( demuxer, "avs" )) &&
  1076.              !avs_input.open_file( filename, p_handle, info, opt ) )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement