Advertisement
Guest User

Untitled

a guest
May 26th, 2010
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 115.99 KB | None | 0 0
  1. Index: Makefile
  2. ===================================================================
  3. --- Makefile_orig
  4. +++ Makefile
  5. @@ -13,10 +13,11 @@
  6. encoder/set.c encoder/macroblock.c encoder/cabac.c \
  7. encoder/cavlc.c encoder/encoder.c encoder/lookahead.c
  8.  
  9. -SRCCLI = x264.c input/timecode.c \
  10. - input/yuv.c input/y4m.c output/raw.c \
  11. - output/matroska.c output/matroska_ebml.c \
  12. - output/flv.c output/flv_bytestream.c
  13. +SRCCLI = x264.c input/common.c input/timecode.c input/raw.c input/y4m.c \
  14. + output/raw.c output/matroska.c output/matroska_ebml.c \
  15. + output/flv.c output/flv_bytestream.c filter/source.c \
  16. + filter/filter.c filter/cache.c filter/select_every.c \
  17. + filter/resize.c filter/utils.c filter/fix_vfr_pts.c
  18.  
  19. SRCSO =
  20.  
  21. @@ -132,7 +133,7 @@
  22. $(CC) -shared -o $@ $(OBJS) $(OBJASM) $(OBJSO) $(SOFLAGS) $(LDFLAGS)
  23.  
  24. x264$(EXE): $(OBJCLI) libx264.a
  25. - $(CC) -o $@ $+ $(LDFLAGS) $(LDFLAGSCLI)
  26. + $(CC) -o $@ $+ $(LDFLAGSCLI) $(LDFLAGS)
  27.  
  28. checkasm: tools/checkasm.o libx264.a
  29. $(CC) -o $@ $+ $(LDFLAGS)
  30. Index: common/common.c
  31. ===================================================================
  32. --- common/common_orig.c
  33. +++ common/common.c
  34. @@ -1001,8 +1001,7 @@
  35. ****************************************************************************/
  36. int x264_picture_alloc( x264_picture_t *pic, int i_csp, int i_width, int i_height )
  37. {
  38. - pic->i_type = X264_TYPE_AUTO;
  39. - pic->i_qpplus1 = 0;
  40. + x264_picture_defaults( pic );
  41. pic->img.i_csp = i_csp;
  42. pic->img.i_plane = 3;
  43. pic->img.plane[0] = x264_malloc( 3 * i_width * i_height / 2 );
  44. @@ -1013,9 +1012,18 @@
  45. pic->img.i_stride[0] = i_width;
  46. pic->img.i_stride[1] = i_width / 2;
  47. pic->img.i_stride[2] = i_width / 2;
  48. + return 0;
  49. +}
  50. +
  51. +/****************************************************************************
  52. + * x264_picture_defaults:
  53. + ****************************************************************************/
  54. +void x264_picture_defaults( x264_picture_t *pic )
  55. +{
  56. + pic->i_type = X264_TYPE_AUTO;
  57. + pic->i_qpplus1 = 0;
  58. pic->param = NULL;
  59. pic->i_pic_struct = PIC_STRUCT_AUTO;
  60. - return 0;
  61. }
  62.  
  63. /****************************************************************************
  64. Index: configure
  65. ===================================================================
  66. --- configure_orig
  67. +++ configure
  68. @@ -13,6 +13,7 @@
  69. echo " --disable-mp4-output disables mp4 output (using gpac)"
  70. echo " --disable-avi-output disables avi output (using libavformat)"
  71. echo " --disable-pthread disables multithreaded encoding"
  72. +echo " --disable-swscale disables swscale support"
  73. echo " --disable-asm disables platform-specific assembly optimizations"
  74. echo " --enable-debug adds -g, doesn't strip"
  75. echo " --enable-gprof adds -pg, doesn't strip"
  76. @@ -62,7 +63,7 @@
  77. rm -f conftest.c
  78. [ -n "$1" ] && echo "#include <$1>" > conftest.c
  79. echo "int main () { $3 return 0; }" >> conftest.c
  80. - if $CC conftest.c $CFLAGS $LDFLAGS $LDFLAGSCLI $2 -o conftest >conftest.log 2>&1; then
  81. + if $CC conftest.c $CFLAGS $2 $LDFLAGSCLI $LDFLAGS -o conftest >conftest.log 2>&1; then
  82. res=$?
  83. log_ok
  84. else
  85. @@ -77,6 +78,25 @@
  86. return $res
  87. }
  88.  
  89. +cpp_check() {
  90. + log_check "whether $3 is true"
  91. + rm -f conftest.c
  92. + [ -n "$1" ] && echo "#include <$1>" > conftest.c
  93. + echo -e "#if !($3) \n#error $4 \n#endif " >> conftest.c
  94. +
  95. + if $CC conftest.c $CFLAGS $2 $LDFLAGSCLI $LDFLAGS -E -o conftest >conftest.log 2>&1; then
  96. + res=$?
  97. + log_ok
  98. + else
  99. + res=$?
  100. + log_fail
  101. + log_msg "--------------------------------------------------"
  102. + cat conftest.log >> config.log
  103. + log_msg "--------------------------------------------------"
  104. + fi
  105. + return $res
  106. +}
  107. +
  108. as_check() {
  109. log_check "whether $AS supports $1"
  110. echo "$1" > conftest.asm
  111. @@ -120,6 +140,7 @@
  112. mp4_output="auto"
  113. avi_output="auto"
  114. pthread="auto"
  115. +swscale="auto"
  116. asm="auto"
  117. debug="no"
  118. gprof="no"
  119. @@ -189,6 +210,12 @@
  120. --disable-pthread)
  121. pthread="no"
  122. ;;
  123. + --enable-swscale)
  124. + swscale="auto"
  125. + ;;
  126. + --disable-swscale)
  127. + swscale="no"
  128. + ;;
  129. --enable-debug)
  130. debug="yes"
  131. ;;
  132. @@ -512,6 +539,25 @@
  133. vis="no"
  134. fi
  135.  
  136. +if [ $swscale = auto ] ; then
  137. + swscale=no
  138. + if ${cross_prefix}pkg-config --exists libswscale 2>$DEVNULL; then
  139. + SWSCALE_LIBS="$SWSCALE_LIBS $(${cross_prefix}pkg-config --libs libswscale)"
  140. + SWSCALE_CFLAGS="$SWSCALE_CFLAGS $(${cross_prefix}pkg-config --cflags libswscale)"
  141. + fi
  142. + [ -z "$SWSCALE_LIBS" ] && SWSCALE_LIBS="-lswscale -lavutil"
  143. +
  144. + error="swscale must be at least version 0.9.0"
  145. + if cc_check "libswscale/swscale.h" "$SWSCALE_CFLAGS $SWSCALE_LIBS" "sws_getContext(0,0,0,0,0,0,0,0,0,0);" ; then
  146. + if cpp_check "libswscale/swscale.h" "$SWSCALE_CFLAGS" "LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(0,9,0)" "$error"; then
  147. + define HAVE_SWSCALE
  148. + swscale=yes
  149. + else
  150. + echo "Warning: ${error}"
  151. + fi
  152. + fi
  153. +fi
  154. +
  155. if [ "$lavf_input" = "auto" ] ; then
  156. lavf_input="no"
  157. if ${cross_prefix}pkg-config --exists libavformat libavcodec libswscale 2>$DEVNULL; then
  158. @@ -519,18 +565,21 @@
  159. LAVF_CFLAGS="$LAVF_CFLAGS $(${cross_prefix}pkg-config --cflags libavformat libavcodec libswscale)"
  160. fi
  161. if [ -z "$LAVF_LIBS" -a -z "$LAVF_CFLAGS" ]; then
  162. - LAVF_LIBS="-lavformat -lswscale"
  163. - for lib in -lpostproc -lavcodec -lavutil -lm -lz -lbz2 $libpthread -lavifil32; do
  164. + LAVF_LIBS="-lavformat"
  165. + for lib in -lavcodec -lpostproc -lswscale -lavutil -lz -lbz2 -lavifil32; do
  166. cc_check "" $lib && LAVF_LIBS="$LAVF_LIBS $lib"
  167. done
  168. fi
  169. LAVF_LIBS="-L. $LAVF_LIBS"
  170. - if cc_check libavformat/avformat.h "$LAVF_CFLAGS $LAVF_LIBS" && \
  171. - cc_check libswscale/swscale.h "$LAVF_CFLAGS $LAVF_LIBS" ; then
  172. + if cc_check libavformat/avformat.h "$LAVF_CFLAGS $LAVF_LIBS" ; then
  173. # avcodec_decode_video2 is currently the most recently added function that we use; it was added in r18351
  174. if cc_check libavformat/avformat.h "$LAVF_CFLAGS $LAVF_LIBS" "avcodec_decode_video2( NULL, NULL, NULL, NULL );" ; then
  175. - lavf_input="yes"
  176. - define LAVF_INPUT
  177. + if [ "$swscale" = "yes" ]; then
  178. + lavf_input="yes"
  179. + define LAVF_INPUT
  180. + else
  181. + echo "Warning: libavformat is not supported without swscale support"
  182. + fi
  183. else
  184. echo "Warning: libavformat is too old, update to ffmpeg r18351+"
  185. fi
  186. @@ -559,15 +608,15 @@
  187. FFMS2_LIBS="$FFMS2_LIBS -lstdc++ $LAVF_LIBS"
  188. fi
  189.  
  190. - if [ $api_check = "yes" -a $ffms_input = "yes" ]; then
  191. - log_check "whether ffms2 version is at least $ffms_major.$ffms_minor$vmicro$vbump"
  192. - $CC $CFLAGS $FFMS2_CFLAGS -c -o conftest -x c - >$DEVNULL 2>&1 <<EOF
  193. -#include <ffms.h>
  194. -#if FFMS_VERSION < (($ffms_major << 24) | ($ffms_minor << 16) | ($ffms_micro << 8) | $ffms_bump)
  195. -#error Requires ffms2 version 2.13.1
  196. -#endif
  197. -EOF
  198. - [ $? = 0 ] && log_ok || { ffms_input="no"; log_fail; }
  199. + error="ffms2 must be at least version 2.13.1"
  200. + if [ $api_check = "yes" -a $ffms_input = "yes" ] &&
  201. + ! cpp_check "ffms.h" "$FFMS_CFLAGS" "FFMS_VERSION >= (($ffms_major << 24) | ($ffms_minor << 16) | ($ffms_micro << 8) | $ffms_bump)" "$error"; then
  202. + ffms_input="no"
  203. + echo "Warning: $error"
  204. + fi
  205. + if [ "$ffms_input" = "yes" -a "$swscale" = "no" ]; then
  206. + echo "Warning: ffms is not supported without swscale support"
  207. + ffms_input="no"
  208. fi
  209. fi
  210.  
  211. @@ -578,6 +627,9 @@
  212. elif [ "$lavf_input" = "yes" ]; then
  213. LDFLAGSCLI="$LAVF_LIBS $LDFLAGSCLI"
  214. [ -n "$LAVF_CFLAGS" ] && CFLAGS="$CFLAGS $LAVF_CFLAGS"
  215. +elif [ "$swscale" = "yes" ]; then
  216. + LDFLAGSCLI="$SWSCALE_LIBS $LDFLAGSCLI"
  217. + [ -n "$SWSCALE_CFLAGS" ] && CFLAGS="$CFLAGS $SWSCALE_CFLAGS"
  218. fi
  219.  
  220. MP4_LDFLAGS="-lgpac_static"
  221. @@ -736,6 +788,9 @@
  222. Cflags: -I$includedir
  223. EOF
  224.  
  225. +filters="select_every"
  226. +[ $swscale = yes ] && filters="resize $filters"
  227. +
  228. cat > conftest.log <<EOF
  229. Platform: $ARCH
  230. System: $SYS
  231. @@ -746,6 +801,7 @@
  232. mp4 output: $mp4_output
  233. avi output: $avi_output
  234. pthread: $pthread
  235. +filters: $filters
  236. debug: $debug
  237. gprof: $gprof
  238. PIC: $pic
  239. Index: filter/cache.c
  240. ===================================================================
  241. --- /dev/null
  242. +++ filter/cache.c
  243. @@ -0,0 +1,142 @@
  244. +/*****************************************************************************
  245. + * cache.c: x264 cache filter
  246. + *****************************************************************************
  247. + * Copyright (C) 2010 Steven Walters <kemuri9@gmail.com>
  248. + *
  249. + * This program is free software; you can redistribute it and/or modify
  250. + * it under the terms of the GNU General Public License as published by
  251. + * the Free Software Foundation; either version 2 of the License, or
  252. + * (at your option) any later version.
  253. + *
  254. + * This program is distributed in the hope that it will be useful,
  255. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  256. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  257. + * GNU General Public License for more details.
  258. + *
  259. + * You should have received a copy of the GNU General Public License
  260. + * along with this program; if not, write to the Free Software
  261. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  262. + *****************************************************************************/
  263. +
  264. +#include "filter.h"
  265. +#include "utils.h"
  266. +
  267. +#define LAST_FRAME (h->first_frame + h->cur_size - 1)
  268. +
  269. +typedef struct
  270. +{
  271. + hnd_t prev_hnd;
  272. + cli_vid_filter_t prev_filter;
  273. +
  274. + int max_size;
  275. + int first_frame; /* first cached frame */
  276. + cli_pic_t **cache;
  277. + int cur_size;
  278. + int eof; /* frame beyond end of the file */
  279. +} cache_hnd_t;
  280. +
  281. +cli_vid_filter_t cache_filter;
  282. +
  283. +static int init( hnd_t *handle, cli_vid_filter_t *filter, video_info_t *info, x264_param_t *param, char *opt_string )
  284. +{
  285. + intptr_t size = (intptr_t)opt_string;
  286. + /* upon a <= 0 cache request, do nothing */
  287. + if( size <= 0 )
  288. + return 0;
  289. + cache_hnd_t *h = calloc( 1, sizeof(cache_hnd_t) );
  290. + if( !h )
  291. + return -1;
  292. +
  293. + h->max_size = size;
  294. + h->cache = malloc( (h->max_size+1) * sizeof(cli_pic_t*) );
  295. + if( !h->cache )
  296. + return -1;
  297. +
  298. + for( int i = 0; i < h->max_size; i++ )
  299. + {
  300. + h->cache[i] = malloc( sizeof(cli_pic_t) );
  301. + if( !h->cache[i] || x264_cli_pic_alloc( h->cache[i], info->csp, info->width, info->height ) )
  302. + return -1;
  303. + }
  304. + h->cache[h->max_size] = NULL; /* require null terminator for list methods */
  305. +
  306. + h->prev_filter = *filter;
  307. + h->prev_hnd = *handle;
  308. + *handle = h;
  309. + *filter = cache_filter;
  310. +
  311. + return 0;
  312. +}
  313. +
  314. +static void fill_cache( cache_hnd_t *h, int frame )
  315. +{
  316. + /* shift frames out of the cache as the frame request is beyond the filled cache */
  317. + int shift = frame - LAST_FRAME;
  318. + /* no frames to shift or no frames left to read */
  319. + if( shift <= 0 || h->eof )
  320. + return;
  321. + /* the next frames to read are either
  322. + * A) starting at the end of the current cache, or
  323. + * B) starting at a new frame that has the end of the cache at the desired frame
  324. + * and proceeding to fill the entire cache */
  325. + int cur_frame = X264_MAX( h->first_frame + h->cur_size, frame - h->max_size + 1 );
  326. + /* the new starting point is either
  327. + * A) the current one shifted the number of frames entering/leaving the cache, or
  328. + * B) at a new frame that has the end of the cache at the desired frame. */
  329. + h->first_frame = X264_MIN( h->first_frame + shift, cur_frame );
  330. + h->cur_size = X264_MAX( h->cur_size - shift, 0 );
  331. + while( h->cur_size < h->max_size )
  332. + {
  333. + cli_pic_t temp;
  334. + /* the old front frame is going to shift off, overwrite it with the new frame */
  335. + cli_pic_t *cache = h->cache[0];
  336. + if( h->prev_filter.get_frame( h->prev_hnd, &temp, cur_frame ) ||
  337. + x264_cli_pic_copy( cache, &temp ) ||
  338. + h->prev_filter.release_frame( h->prev_hnd, &temp, cur_frame ) )
  339. + {
  340. + h->eof = cur_frame;
  341. + return;
  342. + }
  343. + /* the read was successful, shift the frame off the front to the end */
  344. + x264_frame_push( (void*)h->cache, x264_frame_shift( (void*)h->cache ) );
  345. + cur_frame++;
  346. + h->cur_size++;
  347. + }
  348. +}
  349. +
  350. +static int get_frame( hnd_t handle, cli_pic_t *output, int frame )
  351. +{
  352. + cache_hnd_t *h = handle;
  353. + if( frame < h->first_frame )
  354. + {
  355. + fprintf( stderr, "cache [error]: frame %d is before first cached frame %d \n", frame, h->first_frame );
  356. + return -1;
  357. + }
  358. + fill_cache( h, frame );
  359. + if( frame > LAST_FRAME ) /* eof */
  360. + return -1;
  361. + int idx = frame - (h->eof ? h->eof - h->max_size : h->first_frame);
  362. + *output = *h->cache[idx];
  363. + return 0;
  364. +}
  365. +
  366. +static int release_frame( hnd_t handle, cli_pic_t *pic, int frame )
  367. +{
  368. + /* the parent filter's frame has already been released so do nothing here */
  369. + return 0;
  370. +}
  371. +
  372. +static void free_filter( hnd_t handle )
  373. +{
  374. + cache_hnd_t *h = handle;
  375. + h->prev_filter.free( h->prev_hnd );
  376. + for( int i = 0; i < h->max_size; i++ )
  377. + {
  378. + x264_cli_pic_clean( h->cache[i] );
  379. + free( h->cache[i] );
  380. + }
  381. + free( h->cache );
  382. + free( h );
  383. +}
  384. +
  385. +cli_vid_filter_t cache_filter = { "cache", NULL, init, get_frame, release_frame, free_filter, NULL };
  386. Index: filter/filter.c
  387. ===================================================================
  388. --- /dev/null
  389. +++ filter/filter.c
  390. @@ -0,0 +1,73 @@
  391. +/*****************************************************************************
  392. + * filter.c: x264 filter driver
  393. + *****************************************************************************
  394. + * Copyright (C) 2010 Steven Walters <kemuri9@gmail.com>
  395. + *
  396. + * This program is free software; you can redistribute it and/or modify
  397. + * it under the terms of the GNU General Public License as published by
  398. + * the Free Software Foundation; either version 2 of the License, or
  399. + * (at your option) any later version.
  400. + *
  401. + * This program is distributed in the hope that it will be useful,
  402. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  403. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  404. + * GNU General Public License for more details.
  405. + *
  406. + * You should have received a copy of the GNU General Public License
  407. + * along with this program; if not, write to the Free Software
  408. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  409. + *****************************************************************************/
  410. +
  411. +#include "filter.h"
  412. +
  413. +static cli_vid_filter_t *first_filter = NULL;
  414. +
  415. +static void register_vid_filter( cli_vid_filter_t *new_filter )
  416. +{
  417. + cli_vid_filter_t *filter_i = first_filter;
  418. + while( filter_i->next )
  419. + filter_i = filter_i->next;
  420. + filter_i->next = new_filter;
  421. + new_filter->next = NULL;
  422. +}
  423. +
  424. +#define REGISTER_VFILTER(name) \
  425. +{\
  426. + extern cli_vid_filter_t name##_filter;\
  427. + register_vid_filter( &name##_filter );\
  428. +}
  429. +
  430. +void x264_register_vid_filters()
  431. +{
  432. + extern cli_vid_filter_t source_filter;
  433. + first_filter = &source_filter;
  434. + //REGISTER_VFILTER( source );
  435. + REGISTER_VFILTER( cache );
  436. + REGISTER_VFILTER( fix_vfr_pts );
  437. + REGISTER_VFILTER( resize );
  438. + REGISTER_VFILTER( select_every );
  439. +}
  440. +
  441. +int x264_init_vid_filter( const char *name, hnd_t *handle, cli_vid_filter_t *filter,
  442. + video_info_t *info, x264_param_t *param, char *opt_string )
  443. +{
  444. + cli_vid_filter_t *filter_i = first_filter;
  445. + while( filter_i && strcasecmp( name, filter_i->name ) )
  446. + filter_i = filter_i->next;
  447. + if( !filter_i )
  448. + {
  449. + fprintf( stderr, "x264 [error]: invalid filter `%s'\n", name );
  450. + return -1;
  451. + }
  452. + if( filter_i->init( handle, filter, info, param, opt_string ) )
  453. + return -1;
  454. +
  455. + return 0;
  456. +}
  457. +
  458. +void x264_vid_filter_help( int longhelp )
  459. +{
  460. + for( cli_vid_filter_t *filter_i = first_filter; filter_i; filter_i = filter_i->next )
  461. + if( filter_i->help )
  462. + filter_i->help( longhelp );
  463. +}
  464. Index: filter/filter.h
  465. ===================================================================
  466. --- /dev/null
  467. +++ filter/filter.h
  468. @@ -0,0 +1,56 @@
  469. +/*****************************************************************************
  470. + * filter.h: x264 filter modules
  471. + *****************************************************************************
  472. + * Copyright (C) 2010 Steven Walters <kemuri9@gmail.com>
  473. + *
  474. + * This program is free software; you can redistribute it and/or modify
  475. + * it under the terms of the GNU General Public License as published by
  476. + * the Free Software Foundation; either version 2 of the License, or
  477. + * (at your option) any later version.
  478. + *
  479. + * This program is distributed in the hope that it will be useful,
  480. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  481. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  482. + * GNU General Public License for more details.
  483. + *
  484. + * You should have received a copy of the GNU General Public License
  485. + * along with this program; if not, write to the Free Software
  486. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  487. + *****************************************************************************/
  488. +
  489. +#ifndef X264_FILTER_H
  490. +#define X264_FILTER_H
  491. +
  492. +#include "muxers.h"
  493. +
  494. +typedef struct cli_vid_filter_t cli_vid_filter_t;
  495. +
  496. +struct cli_vid_filter_t
  497. +{
  498. + /* name of the filter */
  499. + const char *name;
  500. + /* help: a short message on what the filter does and how to use it.
  501. + * this should only be implemented by filters directly accessible by the user */
  502. + void (*help)( int longhelp );
  503. + /* init: initializes the filter given the input clip properties and parameter to adjust them as necessary
  504. + * with the given options provided by the user.
  505. + * returns 0 on success, nonzero on error. */
  506. + int (*init)( hnd_t *handle, cli_vid_filter_t *filter, video_info_t *info, x264_param_t *param, char *opt_string );
  507. + /* get_frame: given the storage for the output frame and desired frame number, generate the frame accordingly.
  508. + * the image data returned by get_frame should be treated as const and not be altered.
  509. + * returns 0 on success, nonzero on error. */
  510. + int (*get_frame)( hnd_t handle, cli_pic_t *output, int frame );
  511. + /* release_frame: frame is done being used and is signaled for cleanup. */
  512. + int (*release_frame)( hnd_t handle, cli_pic_t *pic, int frame );
  513. + /* free: run filter cleanup procedures. */
  514. + void (*free)( hnd_t handle );
  515. + /* next registered filter, unused by filters themselves */
  516. + cli_vid_filter_t *next;
  517. +};
  518. +
  519. +void x264_register_vid_filters();
  520. +void x264_vid_filter_help( int longhelp );
  521. +int x264_init_vid_filter( const char *name, hnd_t *handle, cli_vid_filter_t *filter,
  522. + video_info_t *info, x264_param_t *param, char *opt_string );
  523. +
  524. +#endif
  525. Index: filter/fix_vfr_pts.c
  526. ===================================================================
  527. --- /dev/null
  528. +++ filter/fix_vfr_pts.c
  529. @@ -0,0 +1,126 @@
  530. +/*****************************************************************************
  531. + * fix_vfr_pts.c: x264 vfr pts fixing filter
  532. + *****************************************************************************
  533. + * Copyright (C) 2010 Steven Walters <kemuri9@gmail.com>
  534. + *
  535. + * This program is free software; you can redistribute it and/or modify
  536. + * it under the terms of the GNU General Public License as published by
  537. + * the Free Software Foundation; either version 2 of the License, or
  538. + * (at your option) any later version.
  539. + *
  540. + * This program is distributed in the hope that it will be useful,
  541. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  542. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  543. + * GNU General Public License for more details.
  544. + *
  545. + * You should have received a copy of the GNU General Public License
  546. + * along with this program; if not, write to the Free Software
  547. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  548. + *****************************************************************************/
  549. +
  550. +#include "filter.h"
  551. +#include "utils.h"
  552. +
  553. +typedef struct
  554. +{
  555. + hnd_t prev_hnd;
  556. + cli_vid_filter_t prev_filter;
  557. +
  558. + /* we need 1 buffer picture and 1 place holder */
  559. + cli_pic_t buffer;
  560. + cli_pic_t holder;
  561. + int buffer_allocated;
  562. + int holder_frame;
  563. + int holder_ret;
  564. + int64_t pts;
  565. + int64_t last_duration;
  566. +} fix_vfr_pts_hnd_t;
  567. +
  568. +cli_vid_filter_t fix_vfr_pts_filter;
  569. +
  570. +static int init( hnd_t *handle, cli_vid_filter_t *filter, video_info_t *info, x264_param_t *param, char *opt_string )
  571. +{
  572. + /* if the input is not vfr, we don't do anything */
  573. + if( !info->vfr )
  574. + return 0;
  575. + fix_vfr_pts_hnd_t *h = calloc( 1, sizeof(fix_vfr_pts_hnd_t) );
  576. + if( !h )
  577. + return -1;
  578. +
  579. + h->holder_frame = -1;
  580. + h->prev_hnd = *handle;
  581. + h->prev_filter = *filter;
  582. + *handle = h;
  583. + *filter = fix_vfr_pts_filter;
  584. +
  585. + return 0;
  586. +}
  587. +
  588. +static int get_frame( hnd_t handle, cli_pic_t *output, int frame )
  589. +{
  590. + fix_vfr_pts_hnd_t *h = handle;
  591. + /* if we want the holder picture and it errored, return the error. */
  592. + if( frame == h->holder_frame )
  593. + {
  594. + if( h->holder_ret )
  595. + return h->holder_ret;
  596. + }
  597. + else
  598. + {
  599. + /* if we have a holder frame and we don't want it, release the frame */
  600. + if( h->holder_frame > 0 && h->holder_frame < frame && h->prev_filter.release_frame( h->prev_hnd, &h->holder, h->holder_frame ) )
  601. + return -1;
  602. + h->holder_frame = -1;
  603. + if( h->prev_filter.get_frame( h->prev_hnd, &h->holder, frame ) )
  604. + return -1;
  605. + }
  606. +
  607. + /* if the frame's duration is not set already, read the next frame to set it. */
  608. + if( !h->holder.duration )
  609. + {
  610. + /* allocate a buffer picture if we didn't already */
  611. + if( !h->buffer_allocated )
  612. + {
  613. + if( x264_cli_pic_alloc( &h->buffer, h->holder.img.csp, h->holder.img.width, h->holder.img.height ) )
  614. + return -1;
  615. + h->buffer_allocated = 1;
  616. + }
  617. + h->holder_frame = frame+1;
  618. + /* copy the current frame to the buffer, release it, and then read in the next frame to the placeholder */
  619. + if( x264_cli_pic_copy( &h->buffer, &h->holder ) || h->prev_filter.release_frame( h->prev_hnd, &h->holder, frame ) )
  620. + return -1;
  621. + h->holder_ret = h->prev_filter.get_frame( h->prev_hnd, &h->holder, h->holder_frame );
  622. + /* suppress non-monotonic pts warnings by setting the duration to be at least 1 */
  623. + if( !h->holder_ret )
  624. + h->last_duration = X264_MAX( h->holder.pts - h->buffer.pts, 1 );
  625. + h->buffer.duration = h->last_duration;
  626. + *output = h->buffer;
  627. + }
  628. + else
  629. + *output = h->holder;
  630. +
  631. + output->pts = h->pts;
  632. + h->pts += output->duration;
  633. +
  634. + return 0;
  635. +}
  636. +
  637. +static int release_frame( hnd_t handle, cli_pic_t *pic, int frame )
  638. +{
  639. + fix_vfr_pts_hnd_t *h = handle;
  640. + /* if the frame is the buffered one, it's already been released */
  641. + if( frame == (h->holder_frame - 1) )
  642. + return 0;
  643. + return h->prev_filter.release_frame( h->prev_hnd, pic, frame );
  644. +}
  645. +
  646. +static void free_filter( hnd_t handle )
  647. +{
  648. + fix_vfr_pts_hnd_t *h = handle;
  649. + h->prev_filter.free( h->prev_hnd );
  650. + if( h->buffer_allocated )
  651. + x264_cli_pic_clean( &h->buffer );
  652. + free( h );
  653. +}
  654. +
  655. +cli_vid_filter_t fix_vfr_pts_filter = { "fix_vfr_pts", NULL, init, get_frame, release_frame, free_filter, NULL };
  656. Index: filter/resize.c
  657. ===================================================================
  658. --- /dev/null
  659. +++ filter/resize.c
  660. @@ -0,0 +1,347 @@
  661. +/*****************************************************************************
  662. + * resize.c: x264 resize filter
  663. + *****************************************************************************
  664. + * Copyright (C) 2010 Steven Walters <kemuri9@gmail.com>
  665. + *
  666. + * This program is free software; you can redistribute it and/or modify
  667. + * it under the terms of the GNU General Public License as published by
  668. + * the Free Software Foundation; either version 2 of the License, or
  669. + * (at your option) any later version.
  670. + *
  671. + * This program is distributed in the hope that it will be useful,
  672. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  673. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  674. + * GNU General Public License for more details.
  675. + *
  676. + * You should have received a copy of the GNU General Public License
  677. + * along with this program; if not, write to the Free Software
  678. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  679. + *****************************************************************************/
  680. +
  681. +#include "filter.h"
  682. +
  683. +cli_vid_filter_t resize_filter;
  684. +
  685. +static int csp_check( video_info_t *info );
  686. +
  687. +static int full_check( video_info_t *info, x264_param_t *param )
  688. +{
  689. + int required = 0;
  690. + required |= csp_check( info );
  691. + required |= info->width != param->i_width;
  692. + required |= info->height != param->i_height;
  693. + return required;
  694. +}
  695. +
  696. +#ifdef HAVE_SWSCALE
  697. +#undef DECLARE_ALIGNED
  698. +#include <libswscale/swscale.h>
  699. +
  700. +/* this function is not a part of the swscale API but is defined in swscale_internal.h */
  701. +const char *sws_format_name( enum PixelFormat format );
  702. +
  703. +extern cli_input_t input;
  704. +
  705. +typedef struct
  706. +{
  707. + int width;
  708. + int height;
  709. + int pix_fmt;
  710. +} frame_prop_t;
  711. +
  712. +typedef struct
  713. +{
  714. + hnd_t prev_hnd;
  715. + cli_vid_filter_t prev_filter;
  716. +
  717. + cli_pic_t buffer;
  718. + int buffer_allocated;
  719. + int dst_csp;
  720. + struct SwsContext *ctx;
  721. + int ctx_flags;
  722. + frame_prop_t dst; /* desired output properties */
  723. + frame_prop_t scale; /* properties of the SwsContext input */
  724. +} resizer_hnd_t;
  725. +
  726. +static void help( int longhelp )
  727. +{
  728. + printf( " resize:widthxheight[,method]\n" );
  729. + if( !longhelp )
  730. + return;
  731. + printf( " resizes frames to the given size using resizer [\"bicubic\"]\n"
  732. + " - fastbilinear, bilinear, bicubic, experimental, point,\n"
  733. + " - area, bicublin, gauss, sinc, lanczos, spline\n" );
  734. +}
  735. +
  736. +static uint32_t convert_cpu_to_flag( uint32_t cpu )
  737. +{
  738. + uint32_t swscale_cpu = 0;
  739. + if( cpu & X264_CPU_ALTIVEC )
  740. + swscale_cpu |= SWS_CPU_CAPS_ALTIVEC;
  741. + if( cpu & X264_CPU_MMXEXT )
  742. + swscale_cpu |= SWS_CPU_CAPS_MMX | SWS_CPU_CAPS_MMX2;
  743. + return swscale_cpu;
  744. +}
  745. +
  746. +static uint32_t convert_method_to_flag( const char *name )
  747. +{
  748. + uint32_t flag = 0;
  749. + name += *name == ',';
  750. + if( !strcasecmp( name, "fastbilinear" ) )
  751. + flag = SWS_FAST_BILINEAR;
  752. + else if( !strcasecmp( name, "bilinear" ) )
  753. + flag = SWS_BILINEAR;
  754. + else if( !strcasecmp( name, "bicubic" ) )
  755. + flag = SWS_BICUBIC;
  756. + else if( !strcasecmp( name, "experimental" ) )
  757. + flag = SWS_X;
  758. + else if( !strcasecmp( name, "point" ) )
  759. + flag = SWS_POINT;
  760. + else if( !strcasecmp( name, "area" ) )
  761. + flag = SWS_AREA;
  762. + else if( !strcasecmp( name, "bicublin" ) )
  763. + flag = SWS_BICUBLIN;
  764. + else if( !strcasecmp( name, "guass" ) )
  765. + flag = SWS_GAUSS;
  766. + else if( !strcasecmp( name, "sinc" ) )
  767. + flag = SWS_SINC;
  768. + else if( !strcasecmp( name, "lanczos" ) )
  769. + flag = SWS_LANCZOS;
  770. + else if( !strcasecmp( name, "spline" ) )
  771. + flag = SWS_SPLINE;
  772. + else // default
  773. + flag = SWS_BICUBIC;
  774. + return flag;
  775. +}
  776. +
  777. +static int convert_csp_to_pix_fmt( int csp )
  778. +{
  779. + if( csp&X264_CSP_OTHER )
  780. + return csp&X264_CSP_MASK;
  781. + switch( csp&X264_CSP_MASK )
  782. + {
  783. + case X264_CSP_I420: return PIX_FMT_YUV420P;
  784. + case X264_CSP_I422: return PIX_FMT_YUV422P;
  785. + case X264_CSP_I444: return PIX_FMT_YUV444P;
  786. + case X264_CSP_YV12: return PIX_FMT_NONE; /* planar yvu 4:2:0 is not supported by libswscale */
  787. + case X264_CSP_BGR: return PIX_FMT_BGR24;
  788. + case X264_CSP_BGRA: return PIX_FMT_BGRA;
  789. + default: return PIX_FMT_NONE;
  790. + }
  791. +}
  792. +
  793. +static int pick_closest_supported_csp( int csp )
  794. +{
  795. + int pix_fmt = convert_csp_to_pix_fmt( csp );
  796. + switch( pix_fmt )
  797. + {
  798. + case PIX_FMT_YUV422P:
  799. + case PIX_FMT_YUV422P16LE:
  800. + case PIX_FMT_YUV422P16BE:
  801. + case PIX_FMT_YUYV422: // convert yuyv to 422p
  802. + case PIX_FMT_UYVY422:
  803. + return X264_CSP_I422;
  804. + case PIX_FMT_YUV444P:
  805. + case PIX_FMT_YUV444P16LE:
  806. + case PIX_FMT_YUV444P16BE:
  807. + return X264_CSP_I444;
  808. + case PIX_FMT_RGB24: // convert rgb to bgr
  809. + case PIX_FMT_RGB48BE:
  810. + case PIX_FMT_RGB48LE:
  811. + case PIX_FMT_RGB565BE:
  812. + case PIX_FMT_RGB565LE:
  813. + case PIX_FMT_RGB555BE:
  814. + case PIX_FMT_RGB555LE:
  815. + case PIX_FMT_BGR24:
  816. + case PIX_FMT_BGR565BE:
  817. + case PIX_FMT_BGR565LE:
  818. + case PIX_FMT_BGR555BE:
  819. + case PIX_FMT_BGR555LE:
  820. + return X264_CSP_BGR;
  821. + case PIX_FMT_ARGB:
  822. + case PIX_FMT_RGBA:
  823. + case PIX_FMT_ABGR:
  824. + case PIX_FMT_BGRA:
  825. + return X264_CSP_BGRA;
  826. + default:
  827. + return X264_CSP_I420;
  828. + }
  829. +}
  830. +
  831. +static int init( hnd_t *handle, cli_vid_filter_t *filter, video_info_t *info, x264_param_t *param, char *opt_string )
  832. +{
  833. + /* if called for csp conversion and no csp conversion is necessary, exit */
  834. + if( opt_string && !strcmp( opt_string, "csp" ) && !csp_check( info ) )
  835. + return 0;
  836. + /* if called for normalizing the csp to known formats and the format is not unknown, exit */
  837. + if( opt_string && !strcmp( opt_string, "normcsp" ) && !(info->csp&X264_CSP_OTHER) )
  838. + return 0;
  839. + /* if called by x264cli and nothing needs to be done, exit */
  840. + if( !opt_string && !full_check( info, param ) )
  841. + return 0;
  842. +
  843. + resizer_hnd_t *h = calloc( 1, sizeof(resizer_hnd_t) );
  844. + if( !h )
  845. + return -1;
  846. + h->dst_csp = info->dst_csp;
  847. + if( opt_string )
  848. + {
  849. + int len = 0;
  850. + h->dst.height = info->height;
  851. + h->dst.width = info->width;
  852. + if( !strcmp( opt_string, "csp" ) )
  853. + ;
  854. + else if( !strcmp( opt_string, "normcsp" ) )
  855. + h->dst_csp = pick_closest_supported_csp( info->csp );
  856. + else if( sscanf( opt_string, "%ux%u%n", &h->dst.width, &h->dst.height, &len ) != 2 )
  857. + {
  858. + fprintf( stderr, "resize [error]: invalid resolution %s\n", opt_string );
  859. + return -1;
  860. + }
  861. + opt_string += len;
  862. + }
  863. + else
  864. + {
  865. + h->dst.width = param->i_width;
  866. + h->dst.height = param->i_height;
  867. + opt_string = "";
  868. + }
  869. + /* cpu flags + no quick cheats + method */
  870. + h->ctx_flags = convert_cpu_to_flag( param->cpu ) | SWS_FULL_CHR_H_INP | SWS_FULL_CHR_H_INT
  871. + | SWS_BITEXACT | SWS_ACCURATE_RND | convert_method_to_flag( opt_string );
  872. + h->dst.pix_fmt = convert_csp_to_pix_fmt( h->dst_csp );
  873. + h->scale = h->dst;
  874. + int src_pix_fmt = convert_csp_to_pix_fmt( info->csp );
  875. + /* confirm swscale can support this conversion */
  876. + if( !sws_isSupportedInput( src_pix_fmt ) )
  877. + {
  878. + fprintf( stderr, "resize [error]: input colorspace %s is not supported\n", sws_format_name( src_pix_fmt ) );
  879. + return -1;
  880. + }
  881. + if( !sws_isSupportedOutput( h->dst.pix_fmt ) )
  882. + {
  883. + fprintf( stderr, "resize [error]: output colorspace %s is not supported\n", sws_format_name( h->dst.pix_fmt ) );
  884. + return -1;
  885. + }
  886. +
  887. + if( h->dst.width != info->width || h->dst.height != info->height )
  888. + fprintf( stderr, "resize [info]: resizing to %dx%d\n", h->dst.width, h->dst.height );
  889. + if( h->dst.pix_fmt != src_pix_fmt )
  890. + fprintf( stderr, "resize [warning]: converting from %s to %s\n", sws_format_name( src_pix_fmt ),
  891. + sws_format_name( h->dst.pix_fmt ) );
  892. + h->dst_csp |= info->csp & X264_CSP_VFLIP; // preserve vflip
  893. + /* finished initing, overwrite values */
  894. + info->csp = h->dst_csp;
  895. + info->width = h->dst.width;
  896. + info->height = h->dst.height;
  897. +
  898. + h->prev_filter = *filter;
  899. + h->prev_hnd = *handle;
  900. + *handle = h;
  901. + *filter = resize_filter;
  902. +
  903. + return 0;
  904. +}
  905. +
  906. +static int check_resizer( resizer_hnd_t *h, cli_pic_t *in )
  907. +{
  908. + frame_prop_t input_prop = { in->img.width, in->img.height, convert_csp_to_pix_fmt( in->img.csp ) };
  909. + if( !memcmp( &input_prop, &h->scale, sizeof(frame_prop_t) ) )
  910. + return 0;
  911. + if( h->ctx )
  912. + {
  913. + sws_freeContext( h->ctx );
  914. + fprintf( stderr, "resize [warning]: stream properties changed at pts %"PRId64"\n", in->pts );
  915. + }
  916. + h->scale = input_prop;
  917. + if( !h->buffer_allocated )
  918. + {
  919. + if( x264_cli_pic_alloc( &h->buffer, h->dst_csp, h->dst.width, h->dst.height ) )
  920. + return -1;
  921. + h->buffer_allocated = 1;
  922. + }
  923. + h->ctx = sws_getContext( h->scale.width, h->scale.height, h->scale.pix_fmt, h->dst.width,
  924. + h->dst.height, h->dst.pix_fmt, h->ctx_flags, NULL, NULL, NULL );
  925. + if( !h->ctx )
  926. + {
  927. + fprintf( stderr, "resize [error]: swscale init failed\n" );
  928. + return -1;
  929. + }
  930. + return 0;
  931. +}
  932. +
  933. +static int get_frame( hnd_t handle, cli_pic_t *output, int frame )
  934. +{
  935. + resizer_hnd_t *h = handle;
  936. + cli_pic_t in;
  937. + if( h->prev_filter.get_frame( h->prev_hnd, &in, frame ) )
  938. + return -1;
  939. + if( check_resizer( h, &in ) )
  940. + return -1;
  941. + *output = in; /* copy all data */
  942. + if( h->ctx )
  943. + {
  944. + sws_scale( h->ctx, (const uint8_t* const*)in.img.plane, in.img.stride, 0,
  945. + in.img.height, h->buffer.img.plane, h->buffer.img.stride );
  946. + output->img = h->buffer.img; /* copy img data */
  947. + }
  948. + else
  949. + output->img.csp = h->dst_csp;
  950. +
  951. + return 0;
  952. +}
  953. +
  954. +static int release_frame( hnd_t handle, cli_pic_t *pic, int frame )
  955. +{
  956. + resizer_hnd_t *h = handle;
  957. + return h->prev_filter.release_frame( h->prev_hnd, pic, frame );
  958. +}
  959. +
  960. +static void free_filter( hnd_t handle )
  961. +{
  962. + resizer_hnd_t *h = handle;
  963. + h->prev_filter.free( h->prev_hnd );
  964. + if( h->ctx )
  965. + sws_freeContext( h->ctx );
  966. + if( h->buffer_allocated )
  967. + x264_cli_pic_clean( &h->buffer );
  968. + free( h );
  969. +}
  970. +
  971. +#else /* no swscale */
  972. +static int init( hnd_t *handle, cli_vid_filter_t *filter, video_info_t *info, x264_param_t *param, char *opt_string )
  973. +{
  974. + int ret = 0;
  975. +
  976. + if( !opt_string )
  977. + ret = full_check( info, param );
  978. + else
  979. + {
  980. + if( !strcmp( opt_string, "csp" ) )
  981. + ret = csp_check( info );
  982. + else if( !strcmp( opt_string, "normcsp" ) )
  983. + ret = info->csp & X264_CSP_OTHER;
  984. + else
  985. + ret = -1;
  986. + }
  987. +
  988. + /* pass if nothing needs to be done, otherwise fail */
  989. + if( ret )
  990. + fprintf( stderr, "x264 [error]: resizer filter failed, not compiled with swscale support\n" );
  991. + return ret;
  992. +}
  993. +
  994. +#define help NULL
  995. +#define get_frame NULL
  996. +#define release_frame NULL
  997. +#define free_filter NULL
  998. +#define convert_csp_to_pix_fmt(x) (x & X264_CSP_MASK)
  999. +
  1000. +#endif
  1001. +
  1002. +static int csp_check( video_info_t *info )
  1003. +{
  1004. + return convert_csp_to_pix_fmt( info->csp ) != convert_csp_to_pix_fmt( info->dst_csp );
  1005. +}
  1006. +
  1007. +cli_vid_filter_t resize_filter = { "resize", help, init, get_frame, release_frame, free_filter, NULL };
  1008. Index: filter/select_every.c
  1009. ===================================================================
  1010. --- /dev/null
  1011. +++ filter/select_every.c
  1012. @@ -0,0 +1,161 @@
  1013. +/*****************************************************************************
  1014. + * select_every.c: x264 select every filter
  1015. + *****************************************************************************
  1016. + * Copyright (C) 2010 Steven Walters <kemuri9@gmail.com>
  1017. + *
  1018. + * This program is free software; you can redistribute it and/or modify
  1019. + * it under the terms of the GNU General Public License as published by
  1020. + * the Free Software Foundation; either version 2 of the License, or
  1021. + * (at your option) any later version.
  1022. + *
  1023. + * This program is distributed in the hope that it will be useful,
  1024. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1025. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1026. + * GNU General Public License for more details.
  1027. + *
  1028. + * You should have received a copy of the GNU General Public License
  1029. + * along with this program; if not, write to the Free Software
  1030. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  1031. + *****************************************************************************/
  1032. +
  1033. +#include "filter.h"
  1034. +
  1035. +#define MAX_PATTERN_SIZE 100 /* arbitrary */
  1036. +
  1037. +typedef struct
  1038. +{
  1039. + hnd_t prev_hnd;
  1040. + cli_vid_filter_t prev_filter;
  1041. +
  1042. + int *pattern;
  1043. + int pattern_len;
  1044. + int step_size;
  1045. + int vfr;
  1046. + int64_t pts;
  1047. +} selvry_hnd_t;
  1048. +
  1049. +cli_vid_filter_t select_every_filter;
  1050. +
  1051. +static void help( int longhelp )
  1052. +{
  1053. + printf( " select_every:step,offset1[,...]\n" );
  1054. + if( !longhelp )
  1055. + return;
  1056. + printf( " apply a selection pattern to input frames\n"
  1057. + " see: http://avisynth.org/mediawiki/Select#SelectEvery\n" );
  1058. +}
  1059. +
  1060. +static int init( hnd_t *handle, cli_vid_filter_t *filter, video_info_t *info, x264_param_t *param, char *opt_string )
  1061. +{
  1062. + selvry_hnd_t *h = malloc( sizeof(selvry_hnd_t) );
  1063. + if( !h )
  1064. + return -1;
  1065. + h->pattern_len = 0;
  1066. + h->step_size = 0;
  1067. + int offsets[MAX_PATTERN_SIZE];
  1068. + for( char *tok, *p = opt_string; (tok = strtok( p, "," )); p = NULL )
  1069. + {
  1070. + int val = atoi( tok );
  1071. + if( p )
  1072. + {
  1073. + h->step_size = val;
  1074. + continue;
  1075. + }
  1076. + if( val < 0 || val >= h->step_size || (!val && strcmp( tok, "0" )) )
  1077. + {
  1078. + fprintf( stderr, "select_every [error]: invalid offset `%s'\n", tok );
  1079. + return -1;
  1080. + }
  1081. + else if( h->pattern_len >= MAX_PATTERN_SIZE )
  1082. + {
  1083. + fprintf( stderr, "select_every [error]: max pattern size %d reached\n", MAX_PATTERN_SIZE );
  1084. + return -1;
  1085. + }
  1086. + offsets[h->pattern_len++] = val;
  1087. + }
  1088. + if( h->step_size <= 0 )
  1089. + {
  1090. + fprintf( stderr, "select_every [error]: no or invalid step size provided\n" );
  1091. + return -1;
  1092. + }
  1093. + if( !h->pattern_len )
  1094. + {
  1095. + fprintf( stderr, "select_every [error]: no offsets supplied\n" );
  1096. + return -1;
  1097. + }
  1098. +
  1099. + h->pattern = malloc( h->pattern_len * sizeof(int) );
  1100. + if( !h->pattern )
  1101. + return -1;
  1102. + memcpy( h->pattern, offsets, h->pattern_len * sizeof(int) );
  1103. +
  1104. + /* determine required cache size to maintain pattern. */
  1105. + intptr_t max_rewind = 0;
  1106. + int min = h->step_size;
  1107. + for( int i = h->pattern_len-1; i >= 0; i-- )
  1108. + {
  1109. + min = X264_MIN( min, offsets[i] );
  1110. + if( i )
  1111. + max_rewind = X264_MAX( max_rewind, offsets[i-1] - min + 1 );
  1112. + /* reached maximum rewind size */
  1113. + if( max_rewind == h->step_size )
  1114. + break;
  1115. + }
  1116. + if( x264_init_vid_filter( "cache", handle, filter, info, param, (void*)max_rewind ) )
  1117. + return -1;
  1118. +
  1119. + /* done initing, overwrite properties */
  1120. + if( h->step_size != h->pattern_len )
  1121. + {
  1122. + info->num_frames = (uint64_t)info->num_frames * h->pattern_len / h->step_size;
  1123. + info->fps_den *= h->step_size;
  1124. + info->fps_num *= h->pattern_len;
  1125. + x264_reduce_fraction( &info->fps_num, &info->fps_den );
  1126. + if( info->vfr )
  1127. + {
  1128. + info->timebase_den *= h->pattern_len;
  1129. + info->timebase_num *= h->step_size;
  1130. + x264_reduce_fraction( &info->timebase_num, &info->timebase_den );
  1131. + }
  1132. + }
  1133. +
  1134. + h->pts = 0;
  1135. + h->vfr = info->vfr;
  1136. + h->prev_filter = *filter;
  1137. + h->prev_hnd = *handle;
  1138. + *filter = select_every_filter;
  1139. + *handle = h;
  1140. +
  1141. + return 0;
  1142. +}
  1143. +
  1144. +static int get_frame( hnd_t handle, cli_pic_t *output, int frame )
  1145. +{
  1146. + selvry_hnd_t *h = handle;
  1147. + int pat_frame = h->pattern[frame % h->pattern_len] + frame / h->pattern_len * h->step_size;
  1148. + if( h->prev_filter.get_frame( h->prev_hnd, output, pat_frame ) )
  1149. + return -1;
  1150. + if( h->vfr )
  1151. + {
  1152. + output->pts = h->pts;
  1153. + h->pts += output->duration;
  1154. + }
  1155. + return 0;
  1156. +}
  1157. +
  1158. +static int release_frame( hnd_t handle, cli_pic_t *pic, int frame )
  1159. +{
  1160. + selvry_hnd_t *h = handle;
  1161. + int pat_frame = h->pattern[frame % h->pattern_len] + frame / h->pattern_len * h->step_size;
  1162. + return h->prev_filter.release_frame( h->prev_hnd, pic, pat_frame );
  1163. +}
  1164. +
  1165. +static void free_filter( hnd_t handle )
  1166. +{
  1167. + selvry_hnd_t *h = handle;
  1168. + h->prev_filter.free( h->prev_hnd );
  1169. + free( h->pattern );
  1170. + free( h );
  1171. +}
  1172. +
  1173. +cli_vid_filter_t select_every_filter = { "select_every", help, init, get_frame, release_frame, free_filter, NULL };
  1174. Index: filter/source.c
  1175. ===================================================================
  1176. --- /dev/null
  1177. +++ filter/source.c
  1178. @@ -0,0 +1,76 @@
  1179. +/*****************************************************************************
  1180. + * source.c: x264 source filter
  1181. + *****************************************************************************
  1182. + * Copyright (C) 2010 Steven Walters <kemuri9@gmail.com>
  1183. + *
  1184. + * This program is free software; you can redistribute it and/or modify
  1185. + * it under the terms of the GNU General Public License as published by
  1186. + * the Free Software Foundation; either version 2 of the License, or
  1187. + * (at your option) any later version.
  1188. + *
  1189. + * This program is distributed in the hope that it will be useful,
  1190. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1191. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1192. + * GNU General Public License for more details.
  1193. + *
  1194. + * You should have received a copy of the GNU General Public License
  1195. + * along with this program; if not, write to the Free Software
  1196. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  1197. + *****************************************************************************/
  1198. +
  1199. +#include "filter.h"
  1200. +
  1201. +typedef struct
  1202. +{
  1203. + cli_pic_t pic;
  1204. + hnd_t hin;
  1205. + int cur_frame;
  1206. +} source_hnd_t;
  1207. +
  1208. +cli_vid_filter_t source_filter;
  1209. +
  1210. +static int init( hnd_t *handle, cli_vid_filter_t *filter, video_info_t *info, x264_param_t *param, char *opt_string )
  1211. +{
  1212. + source_hnd_t *h = calloc( 1, sizeof(source_hnd_t) );
  1213. + if( !h )
  1214. + return -1;
  1215. + h->cur_frame = -1;
  1216. +
  1217. + if( input.picture_alloc( &h->pic, info->csp, info->width, info->height ) )
  1218. + return -1;
  1219. +
  1220. + h->hin = *handle;
  1221. + *handle = h;
  1222. + *filter = source_filter;
  1223. +
  1224. + return 0;
  1225. +}
  1226. +
  1227. +static int get_frame( hnd_t handle, cli_pic_t *output, int frame )
  1228. +{
  1229. + source_hnd_t *h = handle;
  1230. + /* do not allow requesting of frames from before the current position */
  1231. + if( frame <= h->cur_frame || input.read_frame( &h->pic, h->hin, frame ) )
  1232. + return -1;
  1233. + h->cur_frame = frame;
  1234. + *output = h->pic;
  1235. + return 0;
  1236. +}
  1237. +
  1238. +static int release_frame( hnd_t handle, cli_pic_t *pic, int frame )
  1239. +{
  1240. + source_hnd_t *h = handle;
  1241. + if( input.release_frame && input.release_frame( &h->pic, h->hin ) )
  1242. + return -1;
  1243. + return 0;
  1244. +}
  1245. +
  1246. +static void free_filter( hnd_t handle )
  1247. +{
  1248. + source_hnd_t *h = handle;
  1249. + input.picture_clean( &h->pic );
  1250. + input.close_file( h->hin );
  1251. + free( h );
  1252. +}
  1253. +
  1254. +cli_vid_filter_t source_filter = { "source", NULL, init, get_frame, release_frame, free_filter, NULL };
  1255. Index: filter/utils.c
  1256. ===================================================================
  1257. --- /dev/null
  1258. +++ filter/utils.c
  1259. @@ -0,0 +1,50 @@
  1260. +/*****************************************************************************
  1261. + * utils.c: x264 filter utilities
  1262. + *****************************************************************************
  1263. + * Copyright (C) 2010 Steven Walters <kemuri9@gmail.com>
  1264. + *
  1265. + * This program is free software; you can redistribute it and/or modify
  1266. + * it under the terms of the GNU General Public License as published by
  1267. + * the Free Software Foundation; either version 2 of the License, or
  1268. + * (at your option) any later version.
  1269. + *
  1270. + * This program is distributed in the hope that it will be useful,
  1271. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1272. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1273. + * GNU General Public License for more details.
  1274. + *
  1275. + * You should have received a copy of the GNU General Public License
  1276. + * along with this program; if not, write to the Free Software
  1277. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  1278. + *****************************************************************************/
  1279. +
  1280. +#include "utils.h"
  1281. +
  1282. +int x264_cli_pic_copy( cli_pic_t *out, cli_pic_t *in )
  1283. +{
  1284. + int csp = in->img.csp & X264_CSP_MASK;
  1285. + if( csp >= X264_CSP_CLI_MAX || csp <= X264_CSP_NONE || in->img.csp & X264_CSP_OTHER )
  1286. + {
  1287. + fprintf( stderr, "x264 [error]: invalid colorspace arg\n" );
  1288. + return -1;
  1289. + }
  1290. + if( in->img.csp != out->img.csp || in->img.height != out->img.height ||
  1291. + in->img.width != out->img.width )
  1292. + {
  1293. + fprintf( stderr, "x264 [error]: incompatible frame properties\n" );
  1294. + return -1;
  1295. + }
  1296. + /* copy data */
  1297. + out->duration = in->duration;
  1298. + out->pts = in->pts;
  1299. + out->opaque = in->opaque;
  1300. +
  1301. + for( int i = 0; i < out->img.planes; i++ )
  1302. + {
  1303. + int height = in->img.height * x264_cli_csps[csp].height[i];
  1304. + int width = in->img.width * x264_cli_csps[csp].width[i];
  1305. + x264_plane_copy_c( out->img.plane[i], out->img.stride[i], in->img.plane[i],
  1306. + in->img.stride[i], width, height );
  1307. + }
  1308. + return 0;
  1309. +}
  1310. Index: filter/utils.h
  1311. ===================================================================
  1312. --- /dev/null
  1313. +++ filter/utils.h
  1314. @@ -0,0 +1,24 @@
  1315. +/*****************************************************************************
  1316. + * utils.h: x264 filter utilities
  1317. + *****************************************************************************
  1318. + * Copyright (C) 2010 Steven Walters <kemuri9@gmail.com>
  1319. + *
  1320. + * This program is free software; you can redistribute it and/or modify
  1321. + * it under the terms of the GNU General Public License as published by
  1322. + * the Free Software Foundation; either version 2 of the License, or
  1323. + * (at your option) any later version.
  1324. + *
  1325. + * This program is distributed in the hope that it will be useful,
  1326. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1327. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1328. + * GNU General Public License for more details.
  1329. + *
  1330. + * You should have received a copy of the GNU General Public License
  1331. + * along with this program; if not, write to the Free Software
  1332. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  1333. + *****************************************************************************/
  1334. +
  1335. +#include "filter.h"
  1336. +
  1337. +void x264_plane_copy_c( uint8_t *dst, int i_dst, uint8_t *src, int i_src, int w, int h );
  1338. +int x264_cli_pic_copy( cli_pic_t *out, cli_pic_t *in );
  1339. Index: input/avs.c
  1340. ===================================================================
  1341. --- input/avs_orig.c
  1342. +++ input/avs.c
  1343. @@ -42,6 +42,10 @@
  1344. /* when AVS supports other planar colorspaces, a workaround is required */
  1345. #define AVS_INTERFACE_OTHER_PLANAR 5
  1346.  
  1347. +#ifdef HAVE_SWSCALE
  1348. +#include <libavutil/pixfmt.h>
  1349. +#endif
  1350. +
  1351. /* maximum size of the sequence of filters to try on non script files */
  1352. #define AVS_MAX_SEQUENCE 5
  1353.  
  1354. @@ -236,17 +240,23 @@
  1355. info->interlaced = 1;
  1356. info->tff = avs_is_tff( vi );
  1357. }
  1358. - if( vi->width&1 || vi->height&1 )
  1359. - {
  1360. - fprintf( stderr, "avs [error]: input clip width or height not divisible by 2 (%dx%d)\n",
  1361. - vi->width, vi->height );
  1362. - return -1;
  1363. - }
  1364. + /* if swscale is available, convert CSPs with it rather than with avisynth. */
  1365. +#ifdef HAVE_SWSCALE
  1366. + int convert_to_yv12 = 0;
  1367. +#else
  1368. + int convert_to_yv12 = !avs_is_yv12( vi );
  1369. +#endif
  1370. /* always call ConvertToYV12 to convert non YV12 planar colorspaces to YV12 when user's AVS supports them,
  1371. as all planar colorspaces are flagged as YV12. If it is already YV12 in this case, the call does nothing */
  1372. - if( !avs_is_yv12( vi ) || avs_version >= AVS_INTERFACE_OTHER_PLANAR )
  1373. + if( convert_to_yv12 || (avs_version >= AVS_INTERFACE_OTHER_PLANAR && avs_is_yv12( vi )) )
  1374. {
  1375. - fprintf( stderr, "avs %s\n", !avs_is_yv12( vi ) ? "[warning]: converting input clip to YV12"
  1376. + if( vi->width&1 || vi->height&1 )
  1377. + {
  1378. + fprintf( stderr, "avs [error]: input clip width or height not divisible by 2 (%dx%d)\n",
  1379. + vi->width, vi->height );
  1380. + return -1;
  1381. + }
  1382. + fprintf( stderr, "avs %s\n", convert_to_yv12 ? "[warning]: converting input clip to YV12"
  1383. : "[info]: avisynth 2.6+ detected, forcing conversion to YV12" );
  1384. const char *arg_name[2] = { NULL, "interlaced" };
  1385. AVS_Value arg_arr[2] = { res, avs_new_value_bool( info->interlaced ) };
  1386. @@ -260,65 +270,69 @@
  1387. }
  1388. h->func.avs_release_value( res );
  1389.  
  1390. - info->width = vi->width;
  1391. - info->height = vi->height;
  1392. + info->width = vi->width;
  1393. + info->height = vi->height;
  1394. info->fps_num = vi->fps_numerator;
  1395. info->fps_den = vi->fps_denominator;
  1396. - h->num_frames = vi->num_frames;
  1397. - info->csp = X264_CSP_YV12;
  1398. + h->num_frames = info->num_frames = vi->num_frames;
  1399. + info->thread_safe = 1;
  1400. +#ifdef HAVE_SWSCALE
  1401. + if( avs_is_rgb32( vi ) )
  1402. + info->csp = X264_CSP_BGRA | X264_CSP_VFLIP;
  1403. + else if( avs_is_rgb24( vi ) )
  1404. + info->csp = X264_CSP_BGR | X264_CSP_VFLIP;
  1405. + else if( avs_is_yuy2( vi ) )
  1406. + info->csp = PIX_FMT_YUYV422 | X264_CSP_OTHER;
  1407. + else /* yv12 */
  1408. + info->csp = X264_CSP_I420;
  1409. +#endif
  1410. info->vfr = 0;
  1411.  
  1412. *p_handle = h;
  1413. return 0;
  1414. }
  1415.  
  1416. -static int get_frame_total( hnd_t handle )
  1417. -{
  1418. - avs_hnd_t *h = handle;
  1419. - return h->num_frames;
  1420. -}
  1421. -
  1422. -static int picture_alloc( x264_picture_t *pic, int i_csp, int i_width, int i_height )
  1423. +static int picture_alloc( cli_pic_t *pic, int csp, int width, int height )
  1424. {
  1425. - pic->img.i_csp = i_csp;
  1426. - pic->img.i_plane = 3;
  1427. - pic->param = NULL;
  1428. - pic->i_pic_struct = PIC_STRUCT_AUTO;
  1429. + if( x264_cli_pic_alloc( pic, X264_CSP_NONE, width, height ) )
  1430. + return -1;
  1431. + pic->img.csp = csp;
  1432. + pic->img.planes = (csp & X264_CSP_OTHER) ? 1 : x264_cli_csps[csp & X264_CSP_MASK].planes;
  1433. return 0;
  1434. }
  1435.  
  1436. -static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame )
  1437. +static int read_frame( cli_pic_t *pic, hnd_t handle, int i_frame )
  1438. {
  1439. - static int plane[3] = { AVS_PLANAR_Y, AVS_PLANAR_V, AVS_PLANAR_U };
  1440. + static int plane[3] = { AVS_PLANAR_Y, AVS_PLANAR_U, AVS_PLANAR_V };
  1441. avs_hnd_t *h = handle;
  1442. if( i_frame >= h->num_frames )
  1443. return -1;
  1444. - AVS_VideoFrame *frm = p_pic->opaque = h->func.avs_get_frame( h->clip, i_frame );
  1445. + AVS_VideoFrame *frm = pic->opaque = h->func.avs_get_frame( h->clip, i_frame );
  1446. const char *err = h->func.avs_clip_get_error( h->clip );
  1447. if( err )
  1448. {
  1449. fprintf( stderr, "avs [error]: %s occurred while reading frame %d\n", err, i_frame );
  1450. return -1;
  1451. }
  1452. - for( int i = 0; i < 3; i++ )
  1453. + for( int i = 0; i < pic->img.planes; i++ )
  1454. {
  1455. /* explicitly cast away the const attribute to avoid a warning */
  1456. - p_pic->img.plane[i] = (uint8_t*)avs_get_read_ptr_p( frm, plane[i] );
  1457. - p_pic->img.i_stride[i] = avs_get_pitch_p( frm, plane[i] );
  1458. + pic->img.plane[i] = (uint8_t*)avs_get_read_ptr_p( frm, plane[i] );
  1459. + pic->img.stride[i] = avs_get_pitch_p( frm, plane[i] );
  1460. }
  1461. return 0;
  1462. }
  1463.  
  1464. -static int release_frame( x264_picture_t *pic, hnd_t handle )
  1465. +static int release_frame( cli_pic_t *pic, hnd_t handle )
  1466. {
  1467. avs_hnd_t *h = handle;
  1468. h->func.avs_release_video_frame( pic->opaque );
  1469. return 0;
  1470. }
  1471.  
  1472. -static void picture_clean( x264_picture_t *pic )
  1473. +static void picture_clean( cli_pic_t *pic )
  1474. {
  1475. - memset( pic, 0, sizeof(x264_picture_t) );
  1476. + memset( pic, 0, sizeof(cli_pic_t) );
  1477. }
  1478.  
  1479. static int close_file( hnd_t handle )
  1480. @@ -332,4 +346,4 @@
  1481. return 0;
  1482. }
  1483.  
  1484. -const cli_input_t avs_input = { open_file, get_frame_total, picture_alloc, read_frame, release_frame, picture_clean, close_file };
  1485. +const cli_input_t avs_input = { open_file, picture_alloc, read_frame, release_frame, picture_clean, close_file };
  1486. Index: input/common.c
  1487. ===================================================================
  1488. --- /dev/null
  1489. +++ input/common.c
  1490. @@ -0,0 +1,86 @@
  1491. +/*****************************************************************************
  1492. + * common.c: x264 input module common
  1493. + *****************************************************************************
  1494. + * Copyright (C) 2010 Steven Walters <kemuri9@gmail.com>
  1495. + *
  1496. + * This program is free software; you can redistribute it and/or modify
  1497. + * it under the terms of the GNU General Public License as published by
  1498. + * the Free Software Foundation; either version 2 of the License, or
  1499. + * (at your option) any later version.
  1500. + *
  1501. + * This program is distributed in the hope that it will be useful,
  1502. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1503. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1504. + * GNU General Public License for more details.
  1505. + *
  1506. + * You should have received a copy of the GNU General Public License
  1507. + * along with this program; if not, write to the Free Software
  1508. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  1509. + *****************************************************************************/
  1510. +
  1511. +#include "input.h"
  1512. +
  1513. +const x264_cli_csp_t x264_cli_csps[] = {
  1514. + [X264_CSP_I420] = { "i420", 3, { 1, .5, .5 }, { 1, .5, .5 } },
  1515. + [X264_CSP_I422] = { "i422", 3, { 1, .5, .5 }, { 1, 1, 1 } },
  1516. + [X264_CSP_I444] = { "i444", 3, { 1, 1, 1 }, { 1, 1, 1 } },
  1517. + [X264_CSP_YV12] = { "yv12", 3, { 1, .5, .5 }, { 1, .5, .5 } },
  1518. + [X264_CSP_BGR] = { "bgr", 1, { 3 }, { 1 }, },
  1519. + [X264_CSP_BGRA] = { "bgra", 1, { 4 }, { 1 }, }
  1520. +};
  1521. +
  1522. +static int is_invalid_csp( int csp )
  1523. +{
  1524. + int csp_mask = csp & X264_CSP_MASK;
  1525. + return csp_mask <= X264_CSP_NONE || csp_mask >= X264_CSP_CLI_MAX || csp & X264_CSP_OTHER;
  1526. +}
  1527. +
  1528. +uint64_t x264_cli_pic_plane_size( int csp, int width, int height, int plane )
  1529. +{
  1530. + int csp_mask = csp & X264_CSP_MASK;
  1531. + if( is_invalid_csp( csp ) || plane < 0 || plane >= x264_cli_csps[csp_mask].planes )
  1532. + return 0;
  1533. + uint64_t size = (uint64_t)width * height;
  1534. + size *= x264_cli_csps[csp_mask].width[plane] * x264_cli_csps[csp_mask].height[plane];
  1535. + return size;
  1536. +}
  1537. +
  1538. +uint64_t x264_cli_pic_size( int csp, int width, int height )
  1539. +{
  1540. + if( is_invalid_csp( csp ) )
  1541. + return 0;
  1542. + uint64_t size = 0;
  1543. + int csp_mask = csp & X264_CSP_MASK;
  1544. + for( int i = 0; i < x264_cli_csps[csp_mask].planes; i++ )
  1545. + size += x264_cli_pic_plane_size( csp, width, height, i );
  1546. + return size;
  1547. +}
  1548. +
  1549. +int x264_cli_pic_alloc( cli_pic_t *pic, int csp, int width, int height )
  1550. +{
  1551. + memset( pic, 0, sizeof(cli_pic_t) );
  1552. + int csp_mask = csp & X264_CSP_MASK;
  1553. + if( is_invalid_csp( csp ) )
  1554. + pic->img.planes = 0;
  1555. + else
  1556. + pic->img.planes = x264_cli_csps[csp_mask].planes;
  1557. + pic->img.csp = csp;
  1558. + pic->img.width = width;
  1559. + pic->img.height = height;
  1560. + for( int i = 0; i < pic->img.planes; i++ )
  1561. + {
  1562. + pic->img.plane[i] = x264_malloc( x264_cli_pic_plane_size( csp, width, height, i ) );
  1563. + if( !pic->img.plane[i] )
  1564. + return -1;
  1565. + pic->img.stride[i] = width * x264_cli_csps[csp_mask].width[i];
  1566. + }
  1567. +
  1568. + return 0;
  1569. +}
  1570. +
  1571. +void x264_cli_pic_clean( cli_pic_t *pic )
  1572. +{
  1573. + for( int i = 0; i < pic->img.planes; i++ )
  1574. + x264_free( pic->img.plane[i] );
  1575. + memset( pic, 0, sizeof(cli_pic_t) );
  1576. +}
  1577. Index: input/ffms.c
  1578. ===================================================================
  1579. --- input/ffms_orig.c
  1580. +++ input/ffms.c
  1581. @@ -37,19 +37,8 @@
  1582. {
  1583. FFMS_VideoSource *video_source;
  1584. FFMS_Track *track;
  1585. - int total_frames;
  1586. - struct SwsContext *scaler;
  1587. - int pts_offset_flag;
  1588. - int64_t pts_offset;
  1589. int reduce_pts;
  1590. int vfr_input;
  1591. -
  1592. - int init_width;
  1593. - int init_height;
  1594. -
  1595. - int cur_width;
  1596. - int cur_height;
  1597. - int cur_pix_fmt;
  1598. } ffms_hnd_t;
  1599.  
  1600. static int FFMS_CC update_progress( int64_t current, int64_t total, void *private )
  1601. @@ -113,12 +102,14 @@
  1602.  
  1603. FFMS_DestroyIndex( index );
  1604. const FFMS_VideoProperties *videop = FFMS_GetVideoProperties( h->video_source );
  1605. - h->total_frames = videop->NumFrames;
  1606. + info->num_frames = videop->NumFrames;
  1607. info->sar_height = videop->SARDen;
  1608. info->sar_width = videop->SARNum;
  1609. info->fps_den = videop->FPSDenominator;
  1610. info->fps_num = videop->FPSNumerator;
  1611. h->vfr_input = info->vfr;
  1612. + /* ffms is thread unsafe as it uses a single frame buffer for all frame requests */
  1613. + info->thread_safe = 0;
  1614.  
  1615. const FFMS_Frame *frame = FFMS_GetFrame( h->video_source, 0, &e );
  1616. if( !frame )
  1617. @@ -127,16 +118,12 @@
  1618. return -1;
  1619. }
  1620.  
  1621. - h->init_width = h->cur_width = info->width = frame->EncodedWidth;
  1622. - h->init_height = h->cur_height = info->height = frame->EncodedHeight;
  1623. - h->cur_pix_fmt = frame->EncodedPixelFormat;
  1624. + info->width = frame->EncodedWidth;
  1625. + info->height = frame->EncodedHeight;
  1626. + info->csp = frame->EncodedPixelFormat | X264_CSP_OTHER;
  1627. info->interlaced = frame->InterlacedFrame;
  1628. info->tff = frame->TopFieldFirst;
  1629.  
  1630. - if( h->cur_pix_fmt != PIX_FMT_YUV420P )
  1631. - fprintf( stderr, "ffms [warning]: converting from %s to YV12\n",
  1632. - avcodec_get_pix_fmt_name( h->cur_pix_fmt ) );
  1633. -
  1634. /* ffms timestamps are in milliseconds. ffms also uses int64_ts for timebase,
  1635. * so we need to reduce large timebases to prevent overflow */
  1636. if( h->vfr_input )
  1637. @@ -160,60 +147,29 @@
  1638. return 0;
  1639. }
  1640.  
  1641. -static int get_frame_total( hnd_t handle )
  1642. -{
  1643. - return ((ffms_hnd_t*)handle)->total_frames;
  1644. -}
  1645. -
  1646. -static int check_swscale( ffms_hnd_t *h, const FFMS_Frame *frame, int i_frame )
  1647. +static int picture_alloc( cli_pic_t *pic, int csp, int width, int height )
  1648. {
  1649. - if( h->scaler && h->cur_width == frame->EncodedWidth && h->cur_height == frame->EncodedHeight &&
  1650. - h->cur_pix_fmt == frame->EncodedPixelFormat )
  1651. - return 0;
  1652. - if( h->scaler )
  1653. - {
  1654. - sws_freeContext( h->scaler );
  1655. - fprintf( stderr, "ffms [warning]: stream properties changed to %dx%d, %s at frame %d \n", frame->EncodedWidth,
  1656. - frame->EncodedHeight, avcodec_get_pix_fmt_name( frame->EncodedPixelFormat ), i_frame );
  1657. - h->cur_width = frame->EncodedWidth;
  1658. - h->cur_height = frame->EncodedHeight;
  1659. - h->cur_pix_fmt = frame->EncodedPixelFormat;
  1660. - }
  1661. - h->scaler = sws_getContext( h->cur_width, h->cur_height, h->cur_pix_fmt, h->init_width, h->init_height,
  1662. - PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL );
  1663. - if( !h->scaler )
  1664. - {
  1665. - fprintf( stderr, "ffms [error]: could not open swscale context\n" );
  1666. + if( x264_cli_pic_alloc( pic, csp, width, height ) )
  1667. return -1;
  1668. - }
  1669. + pic->img.planes = 4;
  1670. return 0;
  1671. }
  1672.  
  1673. -static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame )
  1674. +static int read_frame( cli_pic_t *pic, hnd_t handle, int i_frame )
  1675. {
  1676. ffms_hnd_t *h = handle;
  1677. FFMS_ErrorInfo e;
  1678. e.BufferSize = 0;
  1679. const FFMS_Frame *frame = FFMS_GetFrame( h->video_source, i_frame, &e );
  1680. if( !frame )
  1681. - {
  1682. - fprintf( stderr, "ffms [error]: could not read frame %d\n", i_frame );
  1683. return -1;
  1684. - }
  1685. -
  1686. - if( check_swscale( h, frame, i_frame ) )
  1687. - return -1;
  1688. - /* FFMS_VideoSource has a single FFMS_Frame buffer for all calls to GetFrame.
  1689. - * With threaded input, copying the pointers would result in the data changing during encoding.
  1690. - * FIXME: don't do redundant sws_scales for singlethreaded input, or fix FFMS to allow
  1691. - * multiple FFMS_Frame buffers. */
  1692. - sws_scale( h->scaler, (const uint8_t * const *)frame->Data, (int*)frame->Linesize, 0,
  1693. - frame->EncodedHeight, p_pic->img.plane, p_pic->img.i_stride );
  1694. -
  1695. - const FFMS_FrameInfo *info = FFMS_GetFrameInfo( h->track, i_frame );
  1696. +
  1697. + memcpy( pic->img.stride, frame->Linesize, sizeof(pic->img.stride) );
  1698. + memcpy( pic->img.plane, frame->Data, sizeof(pic->img.plane) );
  1699.  
  1700. if( h->vfr_input )
  1701. {
  1702. + const FFMS_FrameInfo *info = FFMS_GetFrameInfo( h->track, i_frame );
  1703. if( info->PTS == AV_NOPTS_VALUE )
  1704. {
  1705. fprintf( stderr, "ffms [error]: invalid timestamp. "
  1706. @@ -221,24 +177,22 @@
  1707. return -1;
  1708. }
  1709.  
  1710. - if( !h->pts_offset_flag )
  1711. - {
  1712. - h->pts_offset = info->PTS;
  1713. - h->pts_offset_flag = 1;
  1714. - }
  1715. -
  1716. - p_pic->i_pts = (info->PTS - h->pts_offset) >> h->reduce_pts;
  1717. + pic->pts = info->PTS >> h->reduce_pts;
  1718. }
  1719. return 0;
  1720. }
  1721.  
  1722. +static void picture_clean( cli_pic_t *pic )
  1723. +{
  1724. + memset( pic, 0, sizeof(cli_pic_t) );
  1725. +}
  1726. +
  1727. static int close_file( hnd_t handle )
  1728. {
  1729. ffms_hnd_t *h = handle;
  1730. - sws_freeContext( h->scaler );
  1731. FFMS_DestroyVideoSource( h->video_source );
  1732. free( h );
  1733. return 0;
  1734. }
  1735.  
  1736. -const cli_input_t ffms_input = { open_file, get_frame_total, x264_picture_alloc, read_frame, NULL, x264_picture_clean, close_file };
  1737. +const cli_input_t ffms_input = { open_file, picture_alloc, read_frame, NULL, picture_clean, close_file };
  1738. Index: input/input.h
  1739. ===================================================================
  1740. --- input/input_orig.h
  1741. +++ input/input.h
  1742. @@ -25,11 +25,14 @@
  1743. #ifndef X264_INPUT_H
  1744. #define X264_INPUT_H
  1745.  
  1746. +#include "muxers.h"
  1747. +
  1748. /* options that are used by only some demuxers */
  1749. typedef struct
  1750. {
  1751. char *index;
  1752. - char *resolution; /* resolution string parsed by raw yuv input */
  1753. + char *resolution;
  1754. + char *colorspace;
  1755. char *timebase;
  1756. int seek;
  1757. int demuxer_threads;
  1758. @@ -38,37 +41,81 @@
  1759. /* properties of the source given by the demuxer */
  1760. typedef struct
  1761. {
  1762. - int csp; /* X264_CSP_YV12 or X264_CSP_I420 */
  1763. + int csp; /* actual colorspace */
  1764. + int dst_csp; /* colorspace demuxer says to give to libx264 */
  1765. uint32_t fps_num;
  1766. uint32_t fps_den;
  1767. int height;
  1768. int interlaced;
  1769. + int num_frames;
  1770. uint32_t sar_width;
  1771. uint32_t sar_height;
  1772. int tff;
  1773. + int thread_safe; /* demuxer is thread_input safe */
  1774. uint32_t timebase_num;
  1775. uint32_t timebase_den;
  1776. int vfr;
  1777. int width;
  1778. } video_info_t;
  1779.  
  1780. +/* image data type used by demuxers */
  1781. +typedef struct
  1782. +{
  1783. + int csp; /* colorspace */
  1784. + int width; /* width of the picture */
  1785. + int height; /* height of the picture */
  1786. + int planes; /* number of planes */
  1787. + uint8_t *plane[4]; /* pointers for each plane */
  1788. + int stride[4]; /* strides for each plane */
  1789. +} cli_image_t;
  1790. +
  1791. +typedef struct
  1792. +{
  1793. + cli_image_t img;
  1794. + int64_t pts; /* input pts */
  1795. + int64_t duration; /* frame duration - used for vfr */
  1796. + void *opaque; /* opaque handle */
  1797. +} cli_pic_t;
  1798. +
  1799. typedef struct
  1800. {
  1801. int (*open_file)( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt );
  1802. - int (*get_frame_total)( hnd_t handle );
  1803. - int (*picture_alloc)( x264_picture_t *pic, int i_csp, int i_width, int i_height );
  1804. - int (*read_frame)( x264_picture_t *p_pic, hnd_t handle, int i_frame );
  1805. - int (*release_frame)( x264_picture_t *pic, hnd_t handle );
  1806. - void (*picture_clean)( x264_picture_t *pic );
  1807. + int (*picture_alloc)( cli_pic_t *pic, int csp, int width, int height );
  1808. + int (*read_frame)( cli_pic_t *pic, hnd_t handle, int i_frame );
  1809. + int (*release_frame)( cli_pic_t *pic, hnd_t handle );
  1810. + void (*picture_clean)( cli_pic_t *pic );
  1811. int (*close_file)( hnd_t handle );
  1812. } cli_input_t;
  1813.  
  1814. -extern const cli_input_t yuv_input;
  1815. +extern const cli_input_t raw_input;
  1816. extern const cli_input_t y4m_input;
  1817. extern const cli_input_t avs_input;
  1818. extern cli_input_t thread_input;
  1819. extern const cli_input_t lavf_input;
  1820. extern const cli_input_t ffms_input;
  1821. extern cli_input_t timecode_input;
  1822. +
  1823. +extern cli_input_t input;
  1824. +
  1825. +/* extended colorspace list that isn't recognized by libx264 but by the cli */
  1826. +#define X264_CSP_BGR X264_CSP_MAX /* packed bgr 24bits */
  1827. +#define X264_CSP_BGRA (X264_CSP_MAX+1) /* packed bgr 32bits */
  1828. +#define X264_CSP_CLI_MAX (X264_CSP_MAX+2) /* end of list */
  1829. +#define X264_CSP_OTHER 0x2000 /* non x264 colorspace */
  1830. +
  1831. +typedef struct
  1832. +{
  1833. + const char *name;
  1834. + int planes;
  1835. + float width[4];
  1836. + float height[4];
  1837. +} x264_cli_csp_t;
  1838. +
  1839. +extern const x264_cli_csp_t x264_cli_csps[];
  1840. +
  1841. +int x264_cli_pic_alloc( cli_pic_t *pic, int csp, int width, int height );
  1842. +void x264_cli_pic_clean( cli_pic_t *pic );
  1843. +uint64_t x264_cli_pic_plane_size( int csp, int width, int height, int plane );
  1844. +uint64_t x264_cli_pic_size( int csp, int width, int height );
  1845.  
  1846. #endif
  1847. Index: input/lavf.c
  1848. ===================================================================
  1849. --- input/lavf_orig.c
  1850. +++ input/lavf.c
  1851. @@ -24,58 +24,21 @@
  1852. #include "muxers.h"
  1853. #undef DECLARE_ALIGNED
  1854. #include <libavformat/avformat.h>
  1855. -#include <libswscale/swscale.h>
  1856. +
  1857. +/* located in libavutil/pixdesc.h */
  1858. +enum PixelFormat av_get_pix_fmt( const char *name );
  1859.  
  1860. typedef struct
  1861. {
  1862. AVFormatContext *lavf;
  1863. + AVFormatParameters *param;
  1864. int stream_id;
  1865. int next_frame;
  1866. int vfr_input;
  1867. - int vertical_flip;
  1868. - struct SwsContext *scaler;
  1869. - int pts_offset_flag;
  1870. - int64_t pts_offset;
  1871. - x264_picture_t *first_pic;
  1872. -
  1873. - int init_width;
  1874. - int init_height;
  1875. -
  1876. - int cur_width;
  1877. - int cur_height;
  1878. - enum PixelFormat cur_pix_fmt;
  1879. + cli_pic_t *first_pic;
  1880. } lavf_hnd_t;
  1881.  
  1882. -typedef struct
  1883. -{
  1884. - AVFrame frame;
  1885. - AVPacket packet;
  1886. -} lavf_pic_t;
  1887. -
  1888. -static int check_swscale( lavf_hnd_t *h, AVCodecContext *c, int i_frame )
  1889. -{
  1890. - if( h->scaler && (h->cur_width == c->width) && (h->cur_height == c->height) && (h->cur_pix_fmt == c->pix_fmt) )
  1891. - return 0;
  1892. - if( h->scaler )
  1893. - {
  1894. - sws_freeContext( h->scaler );
  1895. - fprintf( stderr, "lavf [warning]: stream properties changed to %dx%d, %s at frame %d \n",
  1896. - c->width, c->height, avcodec_get_pix_fmt_name( c->pix_fmt ), i_frame );
  1897. - h->cur_width = c->width;
  1898. - h->cur_height = c->height;
  1899. - h->cur_pix_fmt = c->pix_fmt;
  1900. - }
  1901. - h->scaler = sws_getContext( h->cur_width, h->cur_height, h->cur_pix_fmt, h->init_width, h->init_height,
  1902. - PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL );
  1903. - if( !h->scaler )
  1904. - {
  1905. - fprintf( stderr, "lavf [error]: could not open swscale context\n" );
  1906. - return -1;
  1907. - }
  1908. - return 0;
  1909. -}
  1910. -
  1911. -static int read_frame_internal( x264_picture_t *p_pic, lavf_hnd_t *h, int i_frame, video_info_t *info )
  1912. +static int read_frame_internal( cli_pic_t *p_pic, lavf_hnd_t *h, int i_frame, video_info_t *info )
  1913. {
  1914. if( h->first_pic && !info )
  1915. {
  1916. @@ -83,9 +46,11 @@
  1917. * if so, retrieve the pts and image data before freeing it. */
  1918. if( !i_frame )
  1919. {
  1920. - XCHG( x264_image_t, p_pic->img, h->first_pic->img );
  1921. - p_pic->i_pts = h->first_pic->i_pts;
  1922. + XCHG( cli_image_t, p_pic->img, h->first_pic->img );
  1923. + p_pic->pts = h->first_pic->pts;
  1924. + XCHG( void*, p_pic->opaque, h->first_pic->opaque );
  1925. }
  1926. + lavf_input.release_frame( h->first_pic, NULL );
  1927. lavf_input.picture_clean( h->first_pic );
  1928. free( h->first_pic );
  1929. h->first_pic = NULL;
  1930. @@ -94,9 +59,9 @@
  1931. }
  1932.  
  1933. AVCodecContext *c = h->lavf->streams[h->stream_id]->codec;
  1934. - lavf_pic_t *pic_h = p_pic->opaque;
  1935. - AVPacket *pkt = &pic_h->packet;
  1936. - AVFrame *frame = &pic_h->frame;
  1937. + AVPacket *pkt = p_pic->opaque;
  1938. + AVFrame frame;
  1939. + avcodec_get_frame_defaults( &frame );
  1940.  
  1941. while( i_frame >= h->next_frame )
  1942. {
  1943. @@ -105,12 +70,12 @@
  1944. if( pkt->stream_index == h->stream_id )
  1945. {
  1946. c->reordered_opaque = pkt->pts;
  1947. - if( avcodec_decode_video2( c, frame, &finished, pkt ) < 0 )
  1948. + if( avcodec_decode_video2( c, &frame, &finished, pkt ) < 0 )
  1949. fprintf( stderr, "lavf [warning]: video decoding failed on frame %d\n", h->next_frame );
  1950. }
  1951. if( !finished )
  1952. {
  1953. - if( avcodec_decode_video2( c, frame, &finished, pkt ) < 0 )
  1954. + if( avcodec_decode_video2( c, &frame, &finished, pkt ) < 0 )
  1955. fprintf( stderr, "lavf [warning]: video decoding failed on frame %d\n", h->next_frame );
  1956. if( !finished )
  1957. return -1;
  1958. @@ -118,55 +83,57 @@
  1959. h->next_frame++;
  1960. }
  1961.  
  1962. - if( check_swscale( h, c, i_frame ) )
  1963. - return -1;
  1964. - /* FIXME: avoid sws_scale where possible (no colorspace conversion). */
  1965. - sws_scale( h->scaler, (const uint8_t * const *)frame->data, frame->linesize, 0, c->height, p_pic->img.plane, p_pic->img.i_stride );
  1966. + memcpy( p_pic->img.stride, frame.linesize, sizeof(p_pic->img.stride) );
  1967. + memcpy( p_pic->img.plane, frame.data, sizeof(p_pic->img.plane) );
  1968. + p_pic->img.height = c->height;
  1969. + p_pic->img.csp = c->pix_fmt | X264_CSP_OTHER;
  1970. + p_pic->img.width = c->width;
  1971.  
  1972. if( info )
  1973. {
  1974. - info->interlaced = frame->interlaced_frame;
  1975. - info->tff = frame->top_field_first;
  1976. + info->interlaced = frame.interlaced_frame;
  1977. + info->tff = frame.top_field_first;
  1978. }
  1979.  
  1980. if( h->vfr_input )
  1981. {
  1982. - p_pic->i_pts = 0;
  1983. - if( frame->reordered_opaque != AV_NOPTS_VALUE )
  1984. - p_pic->i_pts = frame->reordered_opaque;
  1985. + p_pic->pts = 0;
  1986. + if( frame.reordered_opaque != AV_NOPTS_VALUE )
  1987. + p_pic->pts = frame.reordered_opaque;
  1988. else if( pkt->dts != AV_NOPTS_VALUE )
  1989. - p_pic->i_pts = pkt->dts; // for AVI files
  1990. + p_pic->pts = pkt->dts; // for AVI files
  1991. else if( info )
  1992. {
  1993. h->vfr_input = info->vfr = 0;
  1994. - goto exit;
  1995. - }
  1996. - if( !h->pts_offset_flag )
  1997. - {
  1998. - h->pts_offset = p_pic->i_pts;
  1999. - h->pts_offset_flag = 1;
  2000. + return 0;
  2001. }
  2002. - p_pic->i_pts -= h->pts_offset;
  2003. }
  2004.  
  2005. -exit:
  2006. - if( pkt->destruct )
  2007. - pkt->destruct( pkt );
  2008. - avcodec_get_frame_defaults( frame );
  2009. return 0;
  2010. }
  2011.  
  2012. static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt )
  2013. {
  2014. - lavf_hnd_t *h = malloc( sizeof(lavf_hnd_t) );
  2015. + lavf_hnd_t *h = calloc( 1, sizeof(lavf_hnd_t) );
  2016. if( !h )
  2017. return -1;
  2018. av_register_all();
  2019. - h->scaler = NULL;
  2020. if( !strcmp( psz_filename, "-" ) )
  2021. psz_filename = "pipe:";
  2022.  
  2023. - if( av_open_input_file( &h->lavf, psz_filename, NULL, 0, NULL ) )
  2024. + AVInputFormat *fmt = NULL;
  2025. + /* if resolution was passed in, assume rawvideo */
  2026. + if( opt->resolution )
  2027. + {
  2028. + h->param = calloc( 1, sizeof(AVFormatParameters) );
  2029. + if( !h->param )
  2030. + return -1;
  2031. + sscanf( opt->resolution, "%dx%d", &h->param->width, &h->param->height );
  2032. + h->param->pix_fmt = opt->colorspace ? av_get_pix_fmt( opt->colorspace ) : PIX_FMT_YUV420P;
  2033. + fmt = av_find_input_format( "rawvideo" );
  2034. + }
  2035. +
  2036. + if( av_open_input_file( &h->lavf, psz_filename, fmt, 0, h->param ) )
  2037. {
  2038. fprintf( stderr, "lavf [error]: could not open input file\n" );
  2039. return -1;
  2040. @@ -188,27 +155,14 @@
  2041. }
  2042. h->stream_id = i;
  2043. h->next_frame = 0;
  2044. - h->pts_offset_flag = 0;
  2045. - h->pts_offset = 0;
  2046. AVCodecContext *c = h->lavf->streams[i]->codec;
  2047. - h->init_width = h->cur_width = info->width = c->width;
  2048. - h->init_height = h->cur_height = info->height = c->height;
  2049. - h->cur_pix_fmt = c->pix_fmt;
  2050. info->fps_num = h->lavf->streams[i]->r_frame_rate.num;
  2051. info->fps_den = h->lavf->streams[i]->r_frame_rate.den;
  2052. info->timebase_num = h->lavf->streams[i]->time_base.num;
  2053. info->timebase_den = h->lavf->streams[i]->time_base.den;
  2054. + /* lavf is thread unsafe as calling av_read_frame invalidates previously read AVPackets */
  2055. + info->thread_safe = 0;
  2056. h->vfr_input = info->vfr;
  2057. - h->vertical_flip = 0;
  2058. -
  2059. - /* avisynth stores rgb data vertically flipped. */
  2060. - if( !strcasecmp( get_filename_extension( psz_filename ), "avs" ) &&
  2061. - (h->cur_pix_fmt == PIX_FMT_BGRA || h->cur_pix_fmt == PIX_FMT_BGR24) )
  2062. - info->csp |= X264_CSP_VFLIP;
  2063. -
  2064. - if( h->cur_pix_fmt != PIX_FMT_YUV420P )
  2065. - fprintf( stderr, "lavf [warning]: converting from %s to YV12\n",
  2066. - avcodec_get_pix_fmt_name( h->cur_pix_fmt ) );
  2067.  
  2068. if( opt->demuxer_threads > 1 )
  2069. if( avcodec_thread_init( c, opt->demuxer_threads ) )
  2070. @@ -221,8 +175,8 @@
  2071. }
  2072.  
  2073. /* prefetch the first frame and set/confirm flags */
  2074. - h->first_pic = malloc( sizeof(x264_picture_t) );
  2075. - if( !h->first_pic || lavf_input.picture_alloc( h->first_pic, info->csp, info->width, info->height ) )
  2076. + h->first_pic = malloc( sizeof(cli_pic_t) );
  2077. + if( !h->first_pic || lavf_input.picture_alloc( h->first_pic, X264_CSP_OTHER, info->width, info->height ) )
  2078. {
  2079. fprintf( stderr, "lavf [error]: malloc failed\n" );
  2080. return -1;
  2081. @@ -230,50 +184,62 @@
  2082. else if( read_frame_internal( h->first_pic, h, 0, info ) )
  2083. return -1;
  2084.  
  2085. + info->width = c->width;
  2086. + info->height = c->height;
  2087. + info->csp = h->first_pic->img.csp;
  2088. + info->num_frames = 0; /* FIXME */
  2089. info->sar_height = c->sample_aspect_ratio.den;
  2090. info->sar_width = c->sample_aspect_ratio.num;
  2091. +
  2092. + /* avisynth stores rgb data vertically flipped. */
  2093. + if( !strcasecmp( get_filename_extension( psz_filename ), "avs" ) &&
  2094. + (c->pix_fmt == PIX_FMT_BGRA || c->pix_fmt == PIX_FMT_BGR24) )
  2095. + info->csp |= X264_CSP_VFLIP;
  2096. +
  2097. *p_handle = h;
  2098.  
  2099. return 0;
  2100. }
  2101.  
  2102. -static int picture_alloc( x264_picture_t *pic, int i_csp, int i_width, int i_height )
  2103. +static int picture_alloc( cli_pic_t *pic, int csp, int width, int height )
  2104. {
  2105. - if( x264_picture_alloc( pic, i_csp, i_width, i_height ) )
  2106. + if( x264_cli_pic_alloc( pic, csp, width, height ) )
  2107. return -1;
  2108. - lavf_pic_t *pic_h = pic->opaque = malloc( sizeof(lavf_pic_t) );
  2109. - if( !pic_h )
  2110. + pic->img.planes = 4;
  2111. + pic->opaque = malloc( sizeof(AVPacket) );
  2112. + if( !pic->opaque )
  2113. return -1;
  2114. - avcodec_get_frame_defaults( &pic_h->frame );
  2115. - av_init_packet( &pic_h->packet );
  2116. + av_init_packet( pic->opaque );
  2117. return 0;
  2118. }
  2119.  
  2120. -/* FIXME */
  2121. -static int get_frame_total( hnd_t handle )
  2122. +static int read_frame( cli_pic_t *pic, hnd_t handle, int i_frame )
  2123. {
  2124. - return 0;
  2125. + return read_frame_internal( pic, handle, i_frame, NULL );
  2126. }
  2127.  
  2128. -static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame )
  2129. +static int release_frame( cli_pic_t *pic, hnd_t handle )
  2130. {
  2131. - return read_frame_internal( p_pic, handle, i_frame, NULL );
  2132. + av_free_packet( pic->opaque );
  2133. + av_init_packet( pic->opaque );
  2134. + return 0;
  2135. }
  2136.  
  2137. -static void picture_clean( x264_picture_t *pic )
  2138. +static void picture_clean( cli_pic_t *pic )
  2139. {
  2140. free( pic->opaque );
  2141. - x264_picture_clean( pic );
  2142. + memset( pic, 0, sizeof(cli_pic_t) );
  2143. }
  2144.  
  2145. static int close_file( hnd_t handle )
  2146. {
  2147. lavf_hnd_t *h = handle;
  2148. - sws_freeContext( h->scaler );
  2149. avcodec_close( h->lavf->streams[h->stream_id]->codec );
  2150. av_close_input_file( h->lavf );
  2151. + if( h->param )
  2152. + free( h->param );
  2153. free( h );
  2154. return 0;
  2155. }
  2156.  
  2157. -const cli_input_t lavf_input = { open_file, get_frame_total, picture_alloc, read_frame, NULL, picture_clean, close_file };
  2158. +const cli_input_t lavf_input = { open_file, picture_alloc, read_frame, release_frame, picture_clean, close_file };
  2159. Index: input/raw.c
  2160. ===================================================================
  2161. --- /dev/null
  2162. +++ input/raw.c
  2163. @@ -0,0 +1,136 @@
  2164. +/*****************************************************************************
  2165. + * raw.c: x264 raw input module
  2166. + *****************************************************************************
  2167. + * Copyright (C) 2003-2009 x264 project
  2168. + *
  2169. + * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  2170. + * Loren Merritt <lorenm@u.washington.edu>
  2171. + *
  2172. + * This program is free software; you can redistribute it and/or modify
  2173. + * it under the terms of the GNU General Public License as published by
  2174. + * the Free Software Foundation; either version 2 of the License, or
  2175. + * (at your option) any later version.
  2176. + *
  2177. + * This program is distributed in the hope that it will be useful,
  2178. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2179. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2180. + * GNU General Public License for more details.
  2181. + *
  2182. + * You should have received a copy of the GNU General Public License
  2183. + * along with this program; if not, write to the Free Software
  2184. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  2185. + *****************************************************************************/
  2186. +
  2187. +#include "muxers.h"
  2188. +
  2189. +typedef struct
  2190. +{
  2191. + FILE *fh;
  2192. + int next_frame;
  2193. + uint64_t plane_size[3];
  2194. +} raw_hnd_t;
  2195. +
  2196. +static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt )
  2197. +{
  2198. + raw_hnd_t *h = malloc( sizeof(raw_hnd_t) );
  2199. + if( !h )
  2200. + return -1;
  2201. +
  2202. + if( !opt->resolution )
  2203. + {
  2204. + /* try to parse the file name */
  2205. + for( char *p = psz_filename; *p; p++ )
  2206. + if( *p >= '0' && *p <= '9' && sscanf( p, "%ux%u", &info->width, &info->height ) == 2 )
  2207. + break;
  2208. + }
  2209. + else
  2210. + sscanf( opt->resolution, "%ux%u", &info->width, &info->height );
  2211. + if( !info->width || !info->height )
  2212. + {
  2213. + fprintf( stderr, "raw [error]: raw input requires a resolution.\n" );
  2214. + return -1;
  2215. + }
  2216. + if( opt->colorspace )
  2217. + {
  2218. + for( info->csp = X264_CSP_CLI_MAX-1; x264_cli_csps[info->csp].name && strcasecmp( x264_cli_csps[info->csp].name, opt->colorspace ); )
  2219. + info->csp--;
  2220. + if( info->csp == X264_CSP_NONE )
  2221. + {
  2222. + fprintf( stderr, "raw [error]: unsupported colorspace '%s'\n", opt->colorspace );
  2223. + fprintf( stderr, "supported colorspaces are i420, i422, i444, yv12, bgr, bgra\n" );
  2224. + return -1;
  2225. + }
  2226. + }
  2227. + else /* default */
  2228. + info->csp = X264_CSP_I420;
  2229. +
  2230. + h->next_frame = 0;
  2231. + info->vfr = 0;
  2232. +
  2233. + if( !strcmp( psz_filename, "-" ) )
  2234. + h->fh = stdin;
  2235. + else
  2236. + h->fh = fopen( psz_filename, "rb" );
  2237. + if( h->fh == NULL )
  2238. + return -1;
  2239. +
  2240. + info->thread_safe = 1;
  2241. + info->num_frames = 0;
  2242. + for( int i = 0; i < x264_cli_csps[info->csp].planes; i++ )
  2243. + h->plane_size[i] = x264_cli_pic_plane_size( info->csp, info->width, info->height, i );
  2244. +
  2245. + if( x264_is_regular_file( h->fh ) )
  2246. + {
  2247. + fseek( h->fh, 0, SEEK_END );
  2248. + uint64_t size = ftell( h->fh );
  2249. + fseek( h->fh, 0, SEEK_SET );
  2250. + info->num_frames = size / x264_cli_pic_size( info->csp, info->width, info->height );
  2251. + }
  2252. +
  2253. + *p_handle = h;
  2254. + return 0;
  2255. +}
  2256. +
  2257. +static int read_frame_internal( cli_pic_t *pic, raw_hnd_t *h )
  2258. +{
  2259. + int error = 0;
  2260. + for( int i = 0; i < pic->img.planes && !error; i++ )
  2261. + error |= fread( pic->img.plane[i], h->plane_size[i], 1, h->fh ) <= 0;
  2262. + return error;
  2263. +}
  2264. +
  2265. +static int read_frame( cli_pic_t *pic, hnd_t handle, int i_frame )
  2266. +{
  2267. + raw_hnd_t *h = handle;
  2268. +
  2269. + if( i_frame > h->next_frame )
  2270. + {
  2271. + if( x264_is_regular_file( h->fh ) )
  2272. + fseek( h->fh, i_frame * x264_cli_pic_size( pic->img.csp, pic->img.width, pic->img.height ), SEEK_SET );
  2273. + else
  2274. + while( i_frame > h->next_frame )
  2275. + {
  2276. + if( read_frame_internal( pic, h ) )
  2277. + return -1;
  2278. + h->next_frame++;
  2279. + }
  2280. + }
  2281. +
  2282. + if( read_frame_internal( pic, h ) )
  2283. + return -1;
  2284. +
  2285. + h->next_frame = i_frame+1;
  2286. + return 0;
  2287. +}
  2288. +
  2289. +static int close_file( hnd_t handle )
  2290. +{
  2291. + raw_hnd_t *h = handle;
  2292. + if( !h || !h->fh )
  2293. + return 0;
  2294. + fclose( h->fh );
  2295. + free( h );
  2296. + return 0;
  2297. +}
  2298. +
  2299. +const cli_input_t raw_input = { open_file, x264_cli_pic_alloc, read_frame, NULL, x264_cli_pic_clean, close_file };
  2300. Index: input/thread.c
  2301. ===================================================================
  2302. --- input/thread_orig.c
  2303. +++ input/thread.c
  2304. @@ -23,13 +23,11 @@
  2305.  
  2306. #include "muxers.h"
  2307.  
  2308. -extern cli_input_t input;
  2309. -
  2310. typedef struct
  2311. {
  2312. cli_input_t input;
  2313. hnd_t p_handle;
  2314. - x264_picture_t pic;
  2315. + cli_pic_t pic;
  2316. x264_pthread_t tid;
  2317. int next_frame;
  2318. int frame_total;
  2319. @@ -40,7 +38,7 @@
  2320. typedef struct thread_input_arg_t
  2321. {
  2322. thread_hnd_t *h;
  2323. - x264_picture_t *pic;
  2324. + cli_pic_t *pic;
  2325. int i_frame;
  2326. int status;
  2327. } thread_input_arg_t;
  2328. @@ -62,7 +60,7 @@
  2329. return -1;
  2330. h->next_args->h = h;
  2331. h->next_args->status = 0;
  2332. - h->frame_total = input.get_frame_total( h->p_handle );
  2333. + h->frame_total = info->num_frames;
  2334. thread_input.picture_alloc = h->input.picture_alloc;
  2335. thread_input.picture_clean = h->input.picture_clean;
  2336.  
  2337. @@ -70,18 +68,12 @@
  2338. return 0;
  2339. }
  2340.  
  2341. -static int get_frame_total( hnd_t handle )
  2342. -{
  2343. - thread_hnd_t *h = handle;
  2344. - return h->frame_total;
  2345. -}
  2346. -
  2347. static void read_frame_thread_int( thread_input_arg_t *i )
  2348. {
  2349. i->status = i->h->input.read_frame( i->pic, i->h->p_handle, i->i_frame );
  2350. }
  2351.  
  2352. -static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame )
  2353. +static int read_frame( cli_pic_t *p_pic, hnd_t handle, int i_frame )
  2354. {
  2355. thread_hnd_t *h = handle;
  2356. int ret = 0;
  2357. @@ -94,7 +86,7 @@
  2358. }
  2359.  
  2360. if( h->next_frame == i_frame )
  2361. - XCHG( x264_picture_t, *p_pic, h->pic );
  2362. + XCHG( cli_pic_t, *p_pic, h->pic );
  2363. else
  2364. ret |= h->input.read_frame( p_pic, h->p_handle, i_frame );
  2365.  
  2366. @@ -113,7 +105,7 @@
  2367. return ret;
  2368. }
  2369.  
  2370. -static int release_frame( x264_picture_t *pic, hnd_t handle )
  2371. +static int release_frame( cli_pic_t *pic, hnd_t handle )
  2372. {
  2373. thread_hnd_t *h = handle;
  2374. if( h->input.release_frame )
  2375. @@ -133,4 +125,4 @@
  2376. return 0;
  2377. }
  2378.  
  2379. -cli_input_t thread_input = { open_file, get_frame_total, NULL, read_frame, release_frame, NULL, close_file };
  2380. +cli_input_t thread_input = { open_file, NULL, read_frame, release_frame, NULL, close_file };
  2381. Index: input/timecode.c
  2382. ===================================================================
  2383. --- input/timecode_orig.c
  2384. +++ input/timecode.c
  2385. @@ -23,18 +23,14 @@
  2386. #include "muxers.h"
  2387. #include <math.h>
  2388.  
  2389. -extern cli_input_t input;
  2390. -
  2391. typedef struct
  2392. {
  2393. cli_input_t input;
  2394. hnd_t p_handle;
  2395. - int frame_total;
  2396. int auto_timebase_num;
  2397. int auto_timebase_den;
  2398. uint64_t timebase_num;
  2399. uint64_t timebase_den;
  2400. - int seek;
  2401. int stored_pts_num;
  2402. int64_t *pts;
  2403. double assume_fps;
  2404. @@ -105,7 +101,6 @@
  2405. {
  2406. char buff[256];
  2407. int ret, tcfv, num, seq_num, timecodes_num;
  2408. - int64_t pts_seek_offset;
  2409. double *timecodes = NULL;
  2410. double *fpss = NULL;
  2411.  
  2412. @@ -120,7 +115,7 @@
  2413. {
  2414. uint64_t file_pos;
  2415. double assume_fps, seq_fps;
  2416. - int start, end = h->seek;
  2417. + int start, end;
  2418. int prev_start = -1, prev_end = -1;
  2419.  
  2420. h->assume_fps = 0;
  2421. @@ -148,7 +143,7 @@
  2422. if( buff[0] == '#' || buff[0] == '\n' || buff[0] == '\r' )
  2423. {
  2424. if( sscanf( buff, "# TDecimate Mode 3: Last Frame = %d", &end ) == 1 )
  2425. - h->stored_pts_num = end + 1 - h->seek;
  2426. + h->stored_pts_num = end + 1;
  2427. continue;
  2428. }
  2429. ret = sscanf( buff, "%d,%d,%lf", &start, &end, &seq_fps );
  2430. @@ -168,8 +163,8 @@
  2431. ++seq_num;
  2432. }
  2433. if( !h->stored_pts_num )
  2434. - h->stored_pts_num = end + 1 - h->seek;
  2435. - timecodes_num = h->stored_pts_num + h->seek;
  2436. + h->stored_pts_num = end + 1;
  2437. + timecodes_num = h->stored_pts_num;
  2438. fseek( tcfile_in, file_pos, SEEK_SET );
  2439.  
  2440. timecodes = malloc( timecodes_num * sizeof(double) );
  2441. @@ -245,20 +240,18 @@
  2442. {
  2443. uint64_t file_pos = ftell( tcfile_in );
  2444.  
  2445. - num = h->stored_pts_num = 0;
  2446. + h->stored_pts_num = 0;
  2447. while( fgets( buff, sizeof(buff), tcfile_in ) != NULL )
  2448. {
  2449. if( buff[0] == '#' || buff[0] == '\n' || buff[0] == '\r' )
  2450. {
  2451. - if( !num )
  2452. + if( !h->stored_pts_num )
  2453. file_pos = ftell( tcfile_in );
  2454. continue;
  2455. }
  2456. - if( num >= h->seek )
  2457. - ++h->stored_pts_num;
  2458. - ++num;
  2459. + h->stored_pts_num++;
  2460. }
  2461. - timecodes_num = h->stored_pts_num + h->seek;
  2462. + timecodes_num = h->stored_pts_num;
  2463. if( !timecodes_num )
  2464. {
  2465. fprintf( stderr, "timecode [error]: input tcfile doesn't have any timecodes!\n" );
  2466. @@ -354,12 +347,10 @@
  2467. h->pts = malloc( h->stored_pts_num * sizeof(int64_t) );
  2468. if( !h->pts )
  2469. goto fail;
  2470. - pts_seek_offset = (int64_t)( timecodes[h->seek] * ((double)h->timebase_den / h->timebase_num) + 0.5 );
  2471. h->pts[0] = 0;
  2472. for( num = 1; num < h->stored_pts_num; num++ )
  2473. {
  2474. - h->pts[num] = (int64_t)( timecodes[h->seek + num] * ((double)h->timebase_den / h->timebase_num) + 0.5 );
  2475. - h->pts[num] -= pts_seek_offset;
  2476. + h->pts[num] = timecodes[num] * ((double)h->timebase_den / h->timebase_num) + 0.5;
  2477. if( h->pts[num] <= h->pts[num - 1] )
  2478. {
  2479. fprintf( stderr, "timecode [error]: invalid timebase or timecode for frame %d\n", num );
  2480. @@ -393,8 +384,6 @@
  2481. }
  2482. h->input = input;
  2483. h->p_handle = *p_handle;
  2484. - h->frame_total = input.get_frame_total( h->p_handle );
  2485. - h->seek = opt->seek;
  2486. if( opt->timebase )
  2487. {
  2488. ret = sscanf( opt->timebase, "%"SCNu64"/%"SCNu64, &h->timebase_num, &h->timebase_den );
  2489. @@ -446,39 +435,38 @@
  2490. return 0;
  2491. }
  2492.  
  2493. -static int get_frame_total( hnd_t handle )
  2494. +static int64_t get_frame_pts( timecode_hnd_t *h, int frame, int real_frame )
  2495. {
  2496. - timecode_hnd_t *h = handle;
  2497. - return h->frame_total;
  2498. -}
  2499. -
  2500. -static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame )
  2501. -{
  2502. - timecode_hnd_t *h = handle;
  2503. - int ret = h->input.read_frame( p_pic, h->p_handle, i_frame );
  2504. -
  2505. - if( i_frame - h->seek < h->stored_pts_num )
  2506. - {
  2507. - assert( i_frame >= h->seek );
  2508. - p_pic->i_pts = h->pts[i_frame - h->seek];
  2509. - }
  2510. + if( frame < h->stored_pts_num )
  2511. + return h->pts[frame];
  2512. else
  2513. {
  2514. - if( h->pts )
  2515. + if( h->pts && real_frame )
  2516. {
  2517. fprintf( stderr, "timecode [info]: input timecode file missing data for frame %d and later\n"
  2518. - " assuming constant fps %.6f\n", i_frame, h->assume_fps );
  2519. + " assuming constant fps %.6f\n", frame, h->assume_fps );
  2520. free( h->pts );
  2521. h->pts = NULL;
  2522. }
  2523. - h->last_timecode += 1 / h->assume_fps;
  2524. - p_pic->i_pts = (int64_t)( h->last_timecode * ((double)h->timebase_den / h->timebase_num) + 0.5 );
  2525. + double timecode = h->last_timecode + 1 / h->assume_fps;
  2526. + if( real_frame )
  2527. + h->last_timecode = timecode;
  2528. + return timecode * ((double)h->timebase_den / h->timebase_num) + 0.5;
  2529. }
  2530. +}
  2531. +
  2532. +static int read_frame( cli_pic_t *pic, hnd_t handle, int frame )
  2533. +{
  2534. + timecode_hnd_t *h = handle;
  2535. + int ret = h->input.read_frame( pic, h->p_handle, frame );
  2536. +
  2537. + pic->pts = get_frame_pts( h, frame, 1 );
  2538. + pic->duration = get_frame_pts( h, frame + 1, 0 ) - pic->pts;
  2539.  
  2540. return ret;
  2541. }
  2542.  
  2543. -static int release_frame( x264_picture_t *pic, hnd_t handle )
  2544. +static int release_frame( cli_pic_t *pic, hnd_t handle )
  2545. {
  2546. timecode_hnd_t *h = handle;
  2547. if( h->input.release_frame )
  2548. @@ -496,4 +485,4 @@
  2549. return 0;
  2550. }
  2551.  
  2552. -cli_input_t timecode_input = { open_file, get_frame_total, NULL, read_frame, release_frame, NULL, close_file };
  2553. +cli_input_t timecode_input = { open_file, NULL, read_frame, release_frame, NULL, close_file };
  2554. Index: input/y4m.c
  2555. ===================================================================
  2556. --- input/y4m_orig.c
  2557. +++ input/y4m.c
  2558. @@ -26,10 +26,11 @@
  2559. typedef struct
  2560. {
  2561. FILE *fh;
  2562. - int width, height;
  2563. int next_frame;
  2564. - int seq_header_len, frame_header_len;
  2565. - int frame_size;
  2566. + int seq_header_len;
  2567. + int frame_header_len;
  2568. + uint64_t frame_size;
  2569. + uint64_t plane_size[3];
  2570. } y4m_hnd_t;
  2571.  
  2572. #define Y4M_MAGIC "YUV4MPEG2"
  2573. @@ -37,6 +38,18 @@
  2574. #define Y4M_FRAME_MAGIC "FRAME"
  2575. #define MAX_FRAME_HEADER 80
  2576.  
  2577. +static int csp_string_to_int( char *csp_name )
  2578. +{
  2579. + int csp = X264_CSP_MAX;
  2580. + if( !strncmp( "420", csp_name, 3 ) )
  2581. + csp = X264_CSP_I420;
  2582. + else if( !strncmp( "422", csp_name, 3 ) )
  2583. + csp = X264_CSP_I422;
  2584. + else if( !strncmp( "444", csp_name, 3 ) )
  2585. + csp = X264_CSP_I444;
  2586. + return csp;
  2587. +}
  2588. +
  2589. static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt )
  2590. {
  2591. y4m_hnd_t *h = malloc( sizeof(y4m_hnd_t) );
  2592. @@ -87,18 +100,15 @@
  2593. switch( *tokstart++ )
  2594. {
  2595. case 'W': /* Width. Required. */
  2596. - h->width = info->width = strtol( tokstart, &tokend, 10 );
  2597. + info->width = strtol( tokstart, &tokend, 10 );
  2598. tokstart=tokend;
  2599. break;
  2600. case 'H': /* Height. Required. */
  2601. - h->height = info->height = strtol( tokstart, &tokend, 10 );
  2602. + info->height = strtol( tokstart, &tokend, 10 );
  2603. tokstart=tokend;
  2604. break;
  2605. case 'C': /* Color space */
  2606. - if( !strncmp( "420", tokstart, 3 ) )
  2607. - colorspace = X264_CSP_I420;
  2608. - else
  2609. - colorspace = X264_CSP_MAX; ///< anything other than 420 since we don't handle it
  2610. + colorspace = csp_string_to_int( tokstart );
  2611. tokstart = strchr( tokstart, 0x20 );
  2612. break;
  2613. case 'I': /* Interlace type */
  2614. @@ -145,10 +155,7 @@
  2615. {
  2616. /* Older nonstandard pixel format representation */
  2617. tokstart += 6;
  2618. - if( !strncmp( "420",tokstart, 3 ) )
  2619. - alt_colorspace = X264_CSP_I420;
  2620. - else
  2621. - alt_colorspace = X264_CSP_MAX;
  2622. + alt_colorspace = csp_string_to_int( tokstart );
  2623. }
  2624. tokstart = strchr( tokstart, 0x20 );
  2625. break;
  2626. @@ -162,36 +169,37 @@
  2627. if( colorspace == X264_CSP_NONE )
  2628. colorspace = X264_CSP_I420;
  2629.  
  2630. - if( colorspace != X264_CSP_I420 )
  2631. + if( colorspace <= X264_CSP_NONE && colorspace >= X264_CSP_MAX )
  2632. {
  2633. fprintf( stderr, "y4m [error]: colorspace unhandled\n" );
  2634. return -1;
  2635. }
  2636.  
  2637. - *p_handle = h;
  2638. - return 0;
  2639. -}
  2640. -
  2641. -/* Most common case: frame_header = "FRAME" */
  2642. -static int get_frame_total( hnd_t handle )
  2643. -{
  2644. - y4m_hnd_t *h = handle;
  2645. - int i_frame_total = 0;
  2646. + info->thread_safe = 1;
  2647. + info->num_frames = 0;
  2648. + info->csp = colorspace;
  2649. + h->frame_size = h->frame_header_len;
  2650. + for( i = 0; i < x264_cli_csps[info->csp].planes; i++ )
  2651. + {
  2652. + h->plane_size[i] = x264_cli_pic_plane_size( info->csp, info->width, info->height, i );
  2653. + h->frame_size += h->plane_size[i];
  2654. + }
  2655.  
  2656. + /* Most common case: frame_header = "FRAME" */
  2657. if( x264_is_regular_file( h->fh ) )
  2658. {
  2659. uint64_t init_pos = ftell( h->fh );
  2660. fseek( h->fh, 0, SEEK_END );
  2661. uint64_t i_size = ftell( h->fh );
  2662. fseek( h->fh, init_pos, SEEK_SET );
  2663. - i_frame_total = (int)((i_size - h->seq_header_len) /
  2664. - (3*(h->width*h->height)/2+h->frame_header_len));
  2665. + info->num_frames = (i_size - h->seq_header_len) / h->frame_size;
  2666. }
  2667.  
  2668. - return i_frame_total;
  2669. + *p_handle = h;
  2670. + return 0;
  2671. }
  2672.  
  2673. -static int read_frame_internal( x264_picture_t *p_pic, y4m_hnd_t *h )
  2674. +static int read_frame_internal( cli_pic_t *pic, y4m_hnd_t *h )
  2675. {
  2676. int slen = strlen( Y4M_FRAME_MAGIC );
  2677. int i = 0;
  2678. @@ -218,34 +226,32 @@
  2679. return -1;
  2680. }
  2681. h->frame_header_len = i+slen+1;
  2682. + h->frame_size = x264_cli_pic_size( pic->img.csp, pic->img.width, pic->img.height ) + h->frame_header_len;
  2683.  
  2684. - if( fread( p_pic->img.plane[0], h->width * h->height, 1, h->fh ) <= 0
  2685. - || fread( p_pic->img.plane[1], h->width * h->height / 4, 1, h->fh ) <= 0
  2686. - || fread( p_pic->img.plane[2], h->width * h->height / 4, 1, h->fh ) <= 0 )
  2687. - return -1;
  2688. -
  2689. - return 0;
  2690. + int error = 0;
  2691. + for( i = 0; i < pic->img.planes && !error; i++ )
  2692. + error |= fread( pic->img.plane[i], h->plane_size[i], 1, h->fh ) <= 0;
  2693. + return error;
  2694. }
  2695.  
  2696. -static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame )
  2697. +static int read_frame( cli_pic_t *pic, hnd_t handle, int i_frame )
  2698. {
  2699. y4m_hnd_t *h = handle;
  2700.  
  2701. if( i_frame > h->next_frame )
  2702. {
  2703. if( x264_is_regular_file( h->fh ) )
  2704. - fseek( h->fh, (uint64_t)i_frame*(3*(h->width*h->height)/2+h->frame_header_len)
  2705. - + h->seq_header_len, SEEK_SET );
  2706. + fseek( h->fh, h->frame_size * i_frame + h->seq_header_len, SEEK_SET );
  2707. else
  2708. while( i_frame > h->next_frame )
  2709. {
  2710. - if( read_frame_internal( p_pic, h ) )
  2711. + if( read_frame_internal( pic, h ) )
  2712. return -1;
  2713. h->next_frame++;
  2714. }
  2715. }
  2716.  
  2717. - if( read_frame_internal( p_pic, h ) )
  2718. + if( read_frame_internal( pic, h ) )
  2719. return -1;
  2720.  
  2721. h->next_frame = i_frame+1;
  2722. @@ -262,4 +268,4 @@
  2723. return 0;
  2724. }
  2725.  
  2726. -const cli_input_t y4m_input = { open_file, get_frame_total, x264_picture_alloc, read_frame, NULL, x264_picture_clean, close_file };
  2727. +const cli_input_t y4m_input = { open_file, x264_cli_pic_alloc, read_frame, NULL, x264_cli_pic_clean, close_file };
  2728. Index: input/yuv.c
  2729. ===================================================================
  2730. --- input/yuv.c
  2731. +++ /dev/null
  2732. @@ -1,127 +0,0 @@
  2733. -/*****************************************************************************
  2734. - * yuv.c: x264 yuv input module
  2735. - *****************************************************************************
  2736. - * Copyright (C) 2003-2009 x264 project
  2737. - *
  2738. - * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  2739. - * Loren Merritt <lorenm@u.washington.edu>
  2740. - *
  2741. - * This program is free software; you can redistribute it and/or modify
  2742. - * it under the terms of the GNU General Public License as published by
  2743. - * the Free Software Foundation; either version 2 of the License, or
  2744. - * (at your option) any later version.
  2745. - *
  2746. - * This program is distributed in the hope that it will be useful,
  2747. - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2748. - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2749. - * GNU General Public License for more details.
  2750. - *
  2751. - * You should have received a copy of the GNU General Public License
  2752. - * along with this program; if not, write to the Free Software
  2753. - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  2754. - *****************************************************************************/
  2755. -
  2756. -#include "muxers.h"
  2757. -
  2758. -typedef struct
  2759. -{
  2760. - FILE *fh;
  2761. - int width, height;
  2762. - int next_frame;
  2763. -} yuv_hnd_t;
  2764. -
  2765. -static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt )
  2766. -{
  2767. - yuv_hnd_t *h = malloc( sizeof(yuv_hnd_t) );
  2768. - if( !h )
  2769. - return -1;
  2770. -
  2771. - if( !opt->resolution )
  2772. - {
  2773. - /* try to parse the file name */
  2774. - for( char *p = psz_filename; *p; p++ )
  2775. - if( *p >= '0' && *p <= '9' && sscanf( p, "%ux%u", &info->width, &info->height ) == 2 )
  2776. - break;
  2777. - }
  2778. - else
  2779. - sscanf( opt->resolution, "%ux%u", &info->width, &info->height );
  2780. - if( !info->width || !info->height )
  2781. - {
  2782. - fprintf( stderr, "yuv [error]: rawyuv input requires a resolution.\n" );
  2783. - return -1;
  2784. - }
  2785. -
  2786. - h->next_frame = 0;
  2787. - info->vfr = 0;
  2788. - h->width = info->width;
  2789. - h->height = info->height;
  2790. -
  2791. - if( !strcmp( psz_filename, "-" ) )
  2792. - h->fh = stdin;
  2793. - else
  2794. - h->fh = fopen( psz_filename, "rb" );
  2795. - if( h->fh == NULL )
  2796. - return -1;
  2797. -
  2798. - *p_handle = h;
  2799. - return 0;
  2800. -}
  2801. -
  2802. -static int get_frame_total( hnd_t handle )
  2803. -{
  2804. - yuv_hnd_t *h = handle;
  2805. - int i_frame_total = 0;
  2806. -
  2807. - if( x264_is_regular_file( h->fh ) )
  2808. - {
  2809. - fseek( h->fh, 0, SEEK_END );
  2810. - uint64_t i_size = ftell( h->fh );
  2811. - fseek( h->fh, 0, SEEK_SET );
  2812. - i_frame_total = (int)(i_size / ( h->width * h->height * 3 / 2 ));
  2813. - }
  2814. -
  2815. - return i_frame_total;
  2816. -}
  2817. -
  2818. -static int read_frame_internal( x264_picture_t *p_pic, yuv_hnd_t *h )
  2819. -{
  2820. - return fread( p_pic->img.plane[0], h->width * h->height, 1, h->fh ) <= 0
  2821. - || fread( p_pic->img.plane[1], h->width * h->height / 4, 1, h->fh ) <= 0
  2822. - || fread( p_pic->img.plane[2], h->width * h->height / 4, 1, h->fh ) <= 0;
  2823. -}
  2824. -
  2825. -static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame )
  2826. -{
  2827. - yuv_hnd_t *h = handle;
  2828. -
  2829. - if( i_frame > h->next_frame )
  2830. - {
  2831. - if( x264_is_regular_file( h->fh ) )
  2832. - fseek( h->fh, (uint64_t)i_frame * h->width * h->height * 3 / 2, SEEK_SET );
  2833. - else
  2834. - while( i_frame > h->next_frame )
  2835. - {
  2836. - if( read_frame_internal( p_pic, h ) )
  2837. - return -1;
  2838. - h->next_frame++;
  2839. - }
  2840. - }
  2841. -
  2842. - if( read_frame_internal( p_pic, h ) )
  2843. - return -1;
  2844. -
  2845. - h->next_frame = i_frame+1;
  2846. - return 0;
  2847. -}
  2848. -
  2849. -static int close_file( hnd_t handle )
  2850. -{
  2851. - yuv_hnd_t *h = handle;
  2852. - if( !h || !h->fh )
  2853. - return 0;
  2854. - fclose( h->fh );
  2855. - free( h );
  2856. - return 0;
  2857. -}
  2858. -
  2859. -const cli_input_t yuv_input = { open_file, get_frame_total, x264_picture_alloc, read_frame, NULL, x264_picture_clean, close_file };
  2860. Index: x264.c
  2861. ===================================================================
  2862. --- x264_orig.c
  2863. +++ x264.c
  2864. @@ -34,6 +34,7 @@
  2865. #include "common/cpu.h"
  2866. #include "x264.h"
  2867. #include "muxers.h"
  2868. +#include "filter/filter.h"
  2869.  
  2870. #ifdef _WIN32
  2871. #include <windows.h>
  2872. @@ -66,10 +67,13 @@
  2873. cli_input_t input;
  2874. static cli_output_t output;
  2875.  
  2876. +/* video filter operation function pointer struct */
  2877. +static cli_vid_filter_t filter;
  2878. +
  2879. static const char * const demuxer_names[] =
  2880. {
  2881. "auto",
  2882. - "yuv",
  2883. + "raw",
  2884. "y4m",
  2885. #ifdef AVS_INPUT
  2886. "avs",
  2887. @@ -209,10 +213,10 @@
  2888. #define H1 if(longhelp>=1) printf
  2889. #define H2 if(longhelp==2) printf
  2890. H0( "x264 core:%d%s\n"
  2891. - "Syntax: x264 [options] -o outfile infile [widthxheight]\n"
  2892. + "Syntax: x264 [options] -o outfile infile\n"
  2893. "\n"
  2894. - "Infile can be raw YUV 4:2:0 (in which case resolution is required),\n"
  2895. - " or YUV4MPEG 4:2:0 (*.y4m),\n"
  2896. + "Infile can be raw (in which case resolution is required),\n"
  2897. + " or YUV4MPEG (*.y4m),\n"
  2898. " or Avisynth if compiled with support (%s).\n"
  2899. " or libav* formats if compiled with lavf support (%s) or ffms support (%s).\n"
  2900. "Outfile type is selected by filename:\n"
  2901. @@ -566,6 +570,8 @@
  2902. " - %s\n", muxer_names[0], stringify_names( buf, muxer_names ) );
  2903. H1( " --demuxer <string> Specify input container format [\"%s\"]\n"
  2904. " - %s\n", demuxer_names[0], stringify_names( buf, demuxer_names ) );
  2905. + H1( " --input-csp <string> Specify input colorspace format\n" );
  2906. + H1( " --input-res <intxint> Specify input resolution (width x height)\n" );
  2907. H1( " --index <string> Filename for input index file\n" );
  2908. H0( " --sar width:height Specify Sample Aspect Ratio\n" );
  2909. H0( " --fps <float|rational> Specify framerate\n" );
  2910. @@ -597,6 +603,13 @@
  2911. " <integer> Specify timebase numerator for input timecode file\n"
  2912. " or specify timebase denominator for other input\n" );
  2913. H0( "\n" );
  2914. + H0( "Filtering:\n" );
  2915. + H0( "\n" );
  2916. + H0( "--vf, --video-filter <filter0>/<filter1>/... Apply video filtering to the input file\n" );
  2917. + H0( " Available filters:\n" );
  2918. + x264_register_vid_filters();
  2919. + x264_vid_filter_help( longhelp );
  2920. + H0( "\n" );
  2921. }
  2922.  
  2923. #define OPT_FRAMES 256
  2924. @@ -622,6 +635,9 @@
  2925. #define OPT_TIMEBASE 276
  2926. #define OPT_PULLDOWN 277
  2927. #define OPT_DEMUXER_THREADS 278
  2928. +#define OPT_VIDEO_FILTER 279
  2929. +#define OPT_INPUT_RES 280
  2930. +#define OPT_INPUT_CSP 281
  2931.  
  2932. static char short_options[] = "8A:B:b:f:hI:i:m:o:p:q:r:t:Vvw";
  2933. static struct option long_options[] =
  2934. @@ -769,6 +785,10 @@
  2935. { "nal-hrd", required_argument, NULL, 0 },
  2936. { "pulldown", required_argument, NULL, OPT_PULLDOWN },
  2937. { "fake-interlaced", no_argument, NULL, 0 },
  2938. + { "vf", required_argument, NULL, OPT_VIDEO_FILTER },
  2939. + { "video-filter", required_argument, NULL, OPT_VIDEO_FILTER },
  2940. + { "input-res", required_argument, NULL, OPT_INPUT_RES },
  2941. + { "input-csp", required_argument, NULL, OPT_INPUT_CSP },
  2942. {0, 0, 0, 0}
  2943. };
  2944.  
  2945. @@ -838,7 +858,7 @@
  2946. int b_regular = strcmp( filename, "-" );
  2947. int b_auto = !strcasecmp( demuxer, "auto" );
  2948. if( !b_regular && b_auto )
  2949. - ext = "yuv";
  2950. + ext = "raw";
  2951. if( b_regular )
  2952. {
  2953. FILE *f = fopen( filename, "r" );
  2954. @@ -862,8 +882,8 @@
  2955. }
  2956. else if( !strcasecmp( module, "y4m" ) )
  2957. input = y4m_input;
  2958. - else if( !strcasecmp( module, "yuv" ) )
  2959. - input = yuv_input;
  2960. + else if( !strcasecmp( module, "raw" ) )
  2961. + input = raw_input;
  2962. else
  2963. {
  2964. #ifdef FFMS_INPUT
  2965. @@ -893,11 +913,11 @@
  2966. input = avs_input;
  2967. }
  2968. #endif
  2969. - if( b_auto && !yuv_input.open_file( filename, p_handle, info, opt ) )
  2970. + if( b_auto && !raw_input.open_file( filename, p_handle, info, opt ) )
  2971. {
  2972. - module = "yuv";
  2973. + module = "raw";
  2974. b_auto = 0;
  2975. - input = yuv_input;
  2976. + input = raw_input;
  2977. }
  2978.  
  2979. if( !(*p_handle) )
  2980. @@ -911,6 +931,49 @@
  2981. return 0;
  2982. }
  2983.  
  2984. +int init_vid_filters( char *sequence, hnd_t *handle, video_info_t *info, x264_param_t *param )
  2985. +{
  2986. + x264_register_vid_filters();
  2987. +
  2988. + /* intialize baseline filters */
  2989. + if( x264_init_vid_filter( "source", handle, &filter, info, param, NULL ) ) /* wrap demuxer into a filter */
  2990. + return -1;
  2991. + if( x264_init_vid_filter( "resize", handle, &filter, info, param, "normcsp" ) ) /* normalize csps to be of a known/supported format */
  2992. + return -1;
  2993. + if( x264_init_vid_filter( "fix_vfr_pts", handle, &filter, info, param, NULL ) ) /* fix vfr pts */
  2994. + return -1;
  2995. +
  2996. + /* parse filter chain */
  2997. + for( char *p = sequence; p && *p; )
  2998. + {
  2999. + int tok_len = strcspn( p, "/" );
  3000. + int p_len = strlen( p );
  3001. + p[tok_len] = 0;
  3002. + int name_len = strcspn( p, ":" );
  3003. + if( name_len == tok_len )
  3004. + {
  3005. + fprintf( stderr, "x264 [error]: invalid filter format `%s'\n", p );
  3006. + return -1;
  3007. + }
  3008. + p[name_len++] = 0;
  3009. + if( x264_init_vid_filter( p, handle, &filter, info, param, p + name_len ) )
  3010. + return -1;
  3011. + p += X264_MIN( tok_len+1, p_len );
  3012. + }
  3013. +
  3014. + /* force end result resolution */
  3015. + if( !param->i_width && !param->i_height )
  3016. + {
  3017. + param->i_height = info->height;
  3018. + param->i_width = info->width;
  3019. + }
  3020. + info->dst_csp = param->i_csp; /* force end result colorspace */
  3021. + if( x264_init_vid_filter( "resize", handle, &filter, info, param, NULL ) )
  3022. + return -1;
  3023. +
  3024. + return 0;
  3025. +}
  3026. +
  3027. static int parse_enum_name( const char *arg, const char * const *names, const char **dst )
  3028. {
  3029. for( int i = 0; names[i]; i++ )
  3030. @@ -945,6 +1008,7 @@
  3031. char *tcfile_name = NULL;
  3032. x264_param_t defaults;
  3033. char *profile = NULL;
  3034. + char *vid_filters = NULL;
  3035. int b_thread_input = 0;
  3036. int i_demuxer_threads = 1;
  3037. int b_turbo = 1;
  3038. @@ -1112,6 +1176,15 @@
  3039. if( parse_enum_value( optarg, pulldown_names, &opt->i_pulldown ) < 0 )
  3040. return -1;
  3041. break;
  3042. + case OPT_VIDEO_FILTER:
  3043. + vid_filters = optarg;
  3044. + break;
  3045. + case OPT_INPUT_RES:
  3046. + input_opt.resolution = optarg;
  3047. + break;
  3048. + case OPT_INPUT_CSP:
  3049. + input_opt.colorspace = optarg;
  3050. + break;
  3051. default:
  3052. generic_option:
  3053. {
  3054. @@ -1167,13 +1240,13 @@
  3055. }
  3056.  
  3057. input_filename = argv[optind++];
  3058. - input_opt.resolution = optind < argc ? argv[optind++] : NULL;
  3059. input_opt.demuxer_threads = X264_MAX( i_demuxer_threads, 1 );
  3060. video_info_t info = {0};
  3061. char demuxername[5];
  3062.  
  3063. /* set info flags to param flags to be overwritten by demuxer as necessary. */
  3064. info.csp = param->i_csp;
  3065. + info.dst_csp = param->i_csp;
  3066. info.fps_num = param->i_fps_num;
  3067. info.fps_den = param->i_fps_den;
  3068. info.interlaced = param->b_interlaced;
  3069. @@ -1210,8 +1283,7 @@
  3070. fprintf( stderr, "x264 [error]: timecode input failed\n" );
  3071. return -1;
  3072. }
  3073. - else
  3074. - input = timecode_input;
  3075. + input = timecode_input;
  3076. }
  3077. else if( !info.vfr && input_opt.timebase )
  3078. {
  3079. @@ -1219,11 +1291,34 @@
  3080. return -1;
  3081. }
  3082.  
  3083. + /* init threaded input while input info is unaltered by filtering */
  3084. +#ifdef HAVE_PTHREAD
  3085. + if( info.thread_safe && (b_thread_input || param->i_threads > 1
  3086. + || (param->i_threads == X264_THREADS_AUTO && x264_cpu_num_processors() > 1)) )
  3087. + {
  3088. + if( thread_input.open_file( NULL, &opt->hin, &info, NULL ) )
  3089. + {
  3090. + fprintf( stderr, "x264 [error]: threaded input failed\n" );
  3091. + return -1;
  3092. + }
  3093. + input = thread_input;
  3094. + }
  3095. +#endif
  3096. +
  3097. /* set param flags from the info flags as necessary */
  3098. - param->i_csp = info.csp;
  3099. - param->i_height = info.height;
  3100. + param->i_csp = info.dst_csp;
  3101. +
  3102. + if( init_vid_filters( vid_filters, &opt->hin, &info, param ) )
  3103. + return -1;
  3104. +
  3105. param->b_vfr_input = info.vfr;
  3106. - param->i_width = info.width;
  3107. +
  3108. + info.num_frames = X264_MAX( info.num_frames - opt->i_seek, 0 );
  3109. + if( (!info.num_frames || param->i_frame_total < info.num_frames)
  3110. + && param->i_frame_total > 0 )
  3111. + info.num_frames = param->i_frame_total;
  3112. + param->i_frame_total = info.num_frames;
  3113. +
  3114. if( !b_user_interlaced && info.interlaced )
  3115. {
  3116. fprintf( stderr, "x264 [warning]: input appears to be interlaced, enabling %cff interlaced mode.\n"
  3117. @@ -1279,21 +1374,6 @@
  3118. param->vui.i_sar_height = info.sar_height;
  3119. }
  3120.  
  3121. -#ifdef HAVE_PTHREAD
  3122. - if( b_thread_input || param->i_threads > 1
  3123. - || (param->i_threads == X264_THREADS_AUTO && x264_cpu_num_processors() > 1) )
  3124. - {
  3125. - if( thread_input.open_file( NULL, &opt->hin, &info, NULL ) )
  3126. - {
  3127. - fprintf( stderr, "x264 [error]: threaded input failed\n" );
  3128. - return -1;
  3129. - }
  3130. - else
  3131. - input = thread_input;
  3132. - }
  3133. -#endif
  3134. -
  3135. -
  3136. /* Automatically reduce reference frame count to match the user's target level
  3137. * if the user didn't explicitly set a reference frame count. */
  3138. if( !b_user_ref )
  3139. @@ -1407,13 +1487,23 @@
  3140. fflush( stderr ); // needed in windows
  3141. }
  3142.  
  3143. +static void Convert_cli_to_lib_pic( x264_picture_t *lib, cli_pic_t *cli )
  3144. +{
  3145. + memcpy( lib->img.i_stride, cli->img.stride, sizeof(cli->img.stride) );
  3146. + memcpy( lib->img.plane, cli->img.plane, sizeof(cli->img.plane) );
  3147. + lib->img.i_plane = cli->img.planes;
  3148. + lib->img.i_csp = cli->img.csp;
  3149. + lib->i_pts = cli->pts;
  3150. +}
  3151. +
  3152. static int Encode( x264_param_t *param, cli_opt_t *opt )
  3153. {
  3154. x264_t *h;
  3155. x264_picture_t pic;
  3156. + cli_pic_t cli_pic;
  3157. const cli_pulldown_t *pulldown = NULL; // shut up gcc
  3158.  
  3159. - int i_frame, i_frame_total, i_frame_output;
  3160. + int i_frame, i_frame_output;
  3161. int64_t i_start, i_end;
  3162. int64_t i_file = 0;
  3163. int i_frame_size;
  3164. @@ -1432,13 +1522,8 @@
  3165. double pulldown_pts = 0;
  3166.  
  3167. opt->b_progress &= param->i_log_level < X264_LOG_DEBUG;
  3168. - i_frame_total = input.get_frame_total( opt->hin );
  3169. - i_frame_total = X264_MAX( i_frame_total - opt->i_seek, 0 );
  3170. - if( ( i_frame_total == 0 || param->i_frame_total < i_frame_total )
  3171. - && param->i_frame_total > 0 )
  3172. - i_frame_total = param->i_frame_total;
  3173. - param->i_frame_total = i_frame_total;
  3174. - i_update_interval = i_frame_total ? x264_clip3( i_frame_total / 1000, 1, 10 ) : 10;
  3175. + i_update_interval = param->i_frame_total ? x264_clip3( param->i_frame_total / 1000, 1, 10 ) : 10;
  3176. + x264_picture_defaults( &pic );
  3177.  
  3178. /* set up pulldown */
  3179. if( opt->i_pulldown && !param->b_vfr_input )
  3180. @@ -1457,7 +1542,7 @@
  3181. if( ( h = x264_encoder_open( param ) ) == NULL )
  3182. {
  3183. fprintf( stderr, "x264 [error]: x264_encoder_open failed\n" );
  3184. - input.close_file( opt->hin );
  3185. + filter.free( opt->hin );
  3186. return -1;
  3187. }
  3188.  
  3189. @@ -1468,18 +1553,11 @@
  3190. if( output.set_param( opt->hout, param ) )
  3191. {
  3192. fprintf( stderr, "x264 [error]: can't set outfile param\n" );
  3193. - input.close_file( opt->hin );
  3194. + filter.free( opt->hin );
  3195. output.close_file( opt->hout, largest_pts, second_largest_pts );
  3196. return -1;
  3197. }
  3198.  
  3199. - /* Create a new pic */
  3200. - if( input.picture_alloc( &pic, param->i_csp, param->i_width, param->i_height ) )
  3201. - {
  3202. - fprintf( stderr, "x264 [error]: malloc failed\n" );
  3203. - return -1;
  3204. - }
  3205. -
  3206. i_start = x264_mdate();
  3207. /* ticks/frame = ticks/second / frames/second */
  3208. ticks_per_frame = (int64_t)param->i_timebase_den * param->i_fps_den / param->i_timebase_num / param->i_fps_num;
  3209. @@ -1509,10 +1587,11 @@
  3210. fprintf( opt->tcfile_out, "# timecode format v2\n" );
  3211.  
  3212. /* Encode frames */
  3213. - for( i_frame = 0, i_frame_output = 0; b_ctrl_c == 0 && (i_frame < i_frame_total || i_frame_total == 0); )
  3214. + for( i_frame = 0, i_frame_output = 0; !b_ctrl_c && (i_frame < param->i_frame_total || !param->i_frame_total); i_frame++ )
  3215. {
  3216. - if( input.read_frame( &pic, opt->hin, i_frame + opt->i_seek ) )
  3217. + if( filter.get_frame( opt->hin, &cli_pic, i_frame + opt->i_seek ) )
  3218. break;
  3219. + Convert_cli_to_lib_pic( &pic, &cli_pic );
  3220.  
  3221. if( !param->b_vfr_input )
  3222. pic.i_pts = i_frame;
  3223. @@ -1569,14 +1648,12 @@
  3224. first_dts = prev_dts = last_dts;
  3225. }
  3226.  
  3227. - i_frame++;
  3228. -
  3229. - if( input.release_frame && input.release_frame( &pic, opt->hin ) )
  3230. + if( filter.release_frame( opt->hin, &cli_pic, i_frame + opt->i_seek ) )
  3231. break;
  3232.  
  3233. /* update status line (up to 1000 times per input file) */
  3234. if( opt->b_progress && i_frame_output % i_update_interval == 0 && i_frame_output )
  3235. - Print_status( i_start, i_frame_output, i_frame_total, i_file, param, 2 * last_dts - prev_dts - first_dts );
  3236. + Print_status( i_start, i_frame_output, param->i_frame_total, i_file, param, 2 * last_dts - prev_dts - first_dts );
  3237. }
  3238. /* Flush delayed frames */
  3239. while( !b_ctrl_c && x264_encoder_delayed_frames( h ) )
  3240. @@ -1593,7 +1670,7 @@
  3241. first_dts = prev_dts = last_dts;
  3242. }
  3243. if( opt->b_progress && i_frame_output % i_update_interval == 0 && i_frame_output )
  3244. - Print_status( i_start, i_frame_output, i_frame_total, i_file, param, 2 * last_dts - prev_dts - first_dts );
  3245. + Print_status( i_start, i_frame_output, param->i_frame_total, i_file, param, 2 * last_dts - prev_dts - first_dts );
  3246. }
  3247. if( pts_warning_cnt >= MAX_PTS_WARNING && param->i_log_level < X264_LOG_DEBUG )
  3248. fprintf( stderr, "x264 [warning]: %d suppressed nonmonotonic pts warnings\n", pts_warning_cnt-MAX_PTS_WARNING );
  3249. @@ -1609,7 +1686,6 @@
  3250. duration *= dts_compress_multiplier;
  3251.  
  3252. i_end = x264_mdate();
  3253. - input.picture_clean( &pic );
  3254. /* Erase progress indicator before printing encoding stats. */
  3255. if( opt->b_progress )
  3256. fprintf( stderr, " \r" );
  3257. @@ -1625,7 +1701,7 @@
  3258. opt->tcfile_out = NULL;
  3259. }
  3260.  
  3261. - input.close_file( opt->hin );
  3262. + filter.free( opt->hin );
  3263. output.close_file( opt->hout, largest_pts, second_largest_pts );
  3264.  
  3265. if( i_frame_output > 0 )
  3266. Index: x264.h
  3267. ===================================================================
  3268. --- x264_orig.h
  3269. +++ x264.h
  3270. @@ -35,7 +35,7 @@
  3271.  
  3272. #include <stdarg.h>
  3273.  
  3274. -#define X264_BUILD 96
  3275. +#define X264_BUILD 97
  3276.  
  3277. /* x264_t:
  3278. * opaque handler for encoder */
  3279. @@ -123,12 +123,8 @@
  3280. #define X264_CSP_I420 0x0001 /* yuv 4:2:0 planar */
  3281. #define X264_CSP_I422 0x0002 /* yuv 4:2:2 planar */
  3282. #define X264_CSP_I444 0x0003 /* yuv 4:4:4 planar */
  3283. -#define X264_CSP_YV12 0x0004 /* yuv 4:2:0 planar */
  3284. -#define X264_CSP_YUYV 0x0005 /* yuv 4:2:2 packed */
  3285. -#define X264_CSP_RGB 0x0006 /* rgb 24bits */
  3286. -#define X264_CSP_BGR 0x0007 /* bgr 24bits */
  3287. -#define X264_CSP_BGRA 0x0008 /* bgr 32bits */
  3288. -#define X264_CSP_MAX 0x0009 /* end of list */
  3289. +#define X264_CSP_YV12 0x0004 /* yvu 4:2:0 planar */
  3290. +#define X264_CSP_MAX 0x0005 /* end of list */
  3291. #define X264_CSP_VFLIP 0x1000 /* */
  3292.  
  3293. /* Slice type */
  3294. @@ -548,6 +544,10 @@
  3295. not even copy it from input to output frames. */
  3296. void *opaque;
  3297. } x264_picture_t;
  3298. +
  3299. +/* x264_picture_defaults:
  3300. + * set the picture's values to the defaults. */
  3301. +void x264_picture_defaults( x264_picture_t *pic );
  3302.  
  3303. /* x264_picture_alloc:
  3304. * alloc data for a picture. You must call x264_picture_clean on it.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement