Commit 30d76a5e authored by Kieran Kunhya's avatar Kieran Kunhya Committed by Fiona Glaser

LAVF/FFMS input support, native VFR timestamp handling

libx264 now takes three new API parameters.
b_vfr_input tells x264 whether or not the input is VFR, and is 1 by default.
i_timebase_num and i_timebase_den pass the timebase to x264.

x264_picture_t now returns the DTS of each frame: the calling app need not calculate it anymore.

Add libavformat and FFMS2 input support: requires libav* and ffms2 libraries respectively.
FFMS2 is _STRONGLY_ preferred over libavformat: we encourage all distributions to compile with FFMS2 support if at all possible.
FFMS2 can be found at http://code.google.com/p/ffmpegsource/.
--index, a new x264cli option, allows the user to store (or load) an FFMS2 index file for future use, to avoid re-indexing in the future.

Overhaul the muxers to pass through timestamps instead of assuming CFR.
Also overhaul muxers to correctly use b_annexb and b_repeat_headers to simplify the code.
Remove VFW input support, since it's now pretty much redundant with native AVS support and LAVF support.
Finally, overhaul a large part of the x264cli internals.

--force-cfr, a new x264cli option, allows the user to force the old method of timestamp handling.  May be useful in case of a source with broken timestamps.
Avisynth, YUV, and Y4M input are all still CFR.  LAVF or FFMS2 must be used for VFR support.

Do note that this patch does *not* add VFR ratecontrol yet.
Support for telecined input is also somewhat dubious at the moment.

Large parts of this patch by Mike Gurlitz <mike.gurlitz@gmail.com>, Steven Walters <kemuri9@gmail.com>, and Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>.
parent 8c8bfe19
...@@ -19,10 +19,6 @@ SRCCLI = x264.c input/yuv.c input/y4m.c output/raw.c \ ...@@ -19,10 +19,6 @@ SRCCLI = x264.c input/yuv.c input/y4m.c output/raw.c \
MUXERS := $(shell grep -E "(IN|OUT)PUT" config.h) MUXERS := $(shell grep -E "(IN|OUT)PUT" config.h)
# Optional muxer module sources # Optional muxer module sources
ifneq ($(findstring VFW_INPUT, $(MUXERS)),)
SRCCLI += input/vfw.c
endif
ifneq ($(findstring AVS_INPUT, $(MUXERS)),) ifneq ($(findstring AVS_INPUT, $(MUXERS)),)
SRCCLI += input/avs.c SRCCLI += input/avs.c
endif endif
...@@ -31,6 +27,14 @@ ifneq ($(findstring HAVE_PTHREAD, $(CFLAGS)),) ...@@ -31,6 +27,14 @@ ifneq ($(findstring HAVE_PTHREAD, $(CFLAGS)),)
SRCCLI += input/thread.c SRCCLI += input/thread.c
endif endif
ifneq ($(findstring LAVF_INPUT, $(MUXERS)),)
SRCCLI += input/lavf.c
endif
ifneq ($(findstring FFMS_INPUT, $(MUXERS)),)
SRCCLI += input/ffms.c
endif
ifneq ($(findstring MP4_OUTPUT, $(MUXERS)),) ifneq ($(findstring MP4_OUTPUT, $(MUXERS)),)
SRCCLI += output/mp4.c SRCCLI += output/mp4.c
endif endif
...@@ -110,8 +114,8 @@ libx264.a: .depend $(OBJS) $(OBJASM) ...@@ -110,8 +114,8 @@ libx264.a: .depend $(OBJS) $(OBJASM)
$(SONAME): .depend $(OBJS) $(OBJASM) $(SONAME): .depend $(OBJS) $(OBJASM)
$(CC) -shared -o $@ $(OBJS) $(OBJASM) $(SOFLAGS) $(LDFLAGS) $(CC) -shared -o $@ $(OBJS) $(OBJASM) $(SOFLAGS) $(LDFLAGS)
x264$(EXE): $(OBJCLI) libx264.a x264$(EXE): $(OBJCLI) libx264.a
$(CC) -o $@ $+ $(LDFLAGS) $(CC) -o $@ $+ $(LDFLAGS) $(LDFLAGSCLI)
checkasm: tools/checkasm.o libx264.a checkasm: tools/checkasm.o libx264.a
$(CC) -o $@ $+ $(LDFLAGS) $(CC) -o $@ $+ $(LDFLAGS)
......
...@@ -156,6 +156,7 @@ void x264_param_default( x264_param_t *param ) ...@@ -156,6 +156,7 @@ void x264_param_default( x264_param_t *param )
param->b_repeat_headers = 1; param->b_repeat_headers = 1;
param->b_annexb = 1; param->b_annexb = 1;
param->b_aud = 0; param->b_aud = 0;
param->b_vfr_input = 1;
} }
static int parse_enum( const char *arg, const char * const *names, int *dst ) static int parse_enum( const char *arg, const char * const *names, int *dst )
...@@ -615,6 +616,8 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value ) ...@@ -615,6 +616,8 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value )
p->b_repeat_headers = atobool(value); p->b_repeat_headers = atobool(value);
OPT("annexb") OPT("annexb")
p->b_annexb = atobool(value); p->b_annexb = atobool(value);
OPT("force-cfr")
p->b_vfr_input = !atobool(value);
else else
return X264_PARAM_BAD_NAME; return X264_PARAM_BAD_NAME;
#undef OPT #undef OPT
......
...@@ -431,6 +431,8 @@ struct x264_t ...@@ -431,6 +431,8 @@ struct x264_t
int i_max_ref0; int i_max_ref0;
int i_max_ref1; int i_max_ref1;
int i_delay; /* Number of frames buffered for B reordering */ int i_delay; /* Number of frames buffered for B reordering */
int i_bframe_delay;
int64_t i_bframe_delay_time;
int b_have_lowres; /* Whether 1/2 resolution luma planes are being used */ int b_have_lowres; /* Whether 1/2 resolution luma planes are being used */
int b_have_sub8x8_esa; int b_have_sub8x8_esa;
} frames; } frames;
......
...@@ -223,7 +223,7 @@ int x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src ) ...@@ -223,7 +223,7 @@ int x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
dst->i_type = src->i_type; dst->i_type = src->i_type;
dst->i_qpplus1 = src->i_qpplus1; dst->i_qpplus1 = src->i_qpplus1;
dst->i_pts = src->i_pts; dst->i_pts = dst->i_dts = src->i_pts;
dst->param = src->param; dst->param = src->param;
for( i=0; i<3; i++ ) for( i=0; i<3; i++ )
......
...@@ -35,10 +35,11 @@ typedef struct x264_frame ...@@ -35,10 +35,11 @@ typedef struct x264_frame
int i_type; int i_type;
int i_qpplus1; int i_qpplus1;
int64_t i_pts; int64_t i_pts;
int64_t i_dts;
x264_param_t *param; x264_param_t *param;
int i_frame; /* Presentation frame number */ int i_frame; /* Presentation frame number */
int i_dts; /* Coded frame number */ int i_coded; /* Coded frame number */
int i_frame_num; /* 7.4.3 frame_num */ int i_frame_num; /* 7.4.3 frame_num */
int b_kept_as_ref; int b_kept_as_ref;
uint8_t b_fdec; uint8_t b_fdec;
......
...@@ -8,6 +8,8 @@ echo "available options:" ...@@ -8,6 +8,8 @@ echo "available options:"
echo "" echo ""
echo " --help print this message" echo " --help print this message"
echo " --disable-avs-input disables avisynth input (win32 only)" echo " --disable-avs-input disables avisynth input (win32 only)"
echo " --disable-lavf-input disables libavformat input"
echo " --disable-ffms-input disables ffmpegsource input"
echo " --disable-mp4-output disables mp4 output (using gpac)" echo " --disable-mp4-output disables mp4 output (using gpac)"
echo " --disable-pthread disables multithreaded encoding" echo " --disable-pthread disables multithreaded encoding"
echo " --disable-asm disables assembly optimizations on x86 and arm" echo " --disable-asm disables assembly optimizations on x86 and arm"
...@@ -29,7 +31,7 @@ cc_check() { ...@@ -29,7 +31,7 @@ cc_check() {
rm -f conftest.c rm -f conftest.c
[ -n "$1" ] && echo "#include <$1>" > conftest.c [ -n "$1" ] && echo "#include <$1>" > conftest.c
echo "int main () { $3 return 0; }" >> conftest.c echo "int main () { $3 return 0; }" >> conftest.c
$CC conftest.c $CFLAGS $LDFLAGS $2 -o conftest 2>$DEVNULL $CC conftest.c $CFLAGS $LDFLAGS $LDFLAGSCLI $2 -o conftest 2>$DEVNULL
} }
as_check() { as_check() {
...@@ -52,6 +54,8 @@ includedir='${prefix}/include' ...@@ -52,6 +54,8 @@ includedir='${prefix}/include'
DEVNULL='/dev/null' DEVNULL='/dev/null'
avs_input="auto" avs_input="auto"
lavf_input="auto"
ffms_input="auto"
mp4_output="auto" mp4_output="auto"
pthread="auto" pthread="auto"
asm="yes" asm="yes"
...@@ -63,6 +67,7 @@ shared="no" ...@@ -63,6 +67,7 @@ shared="no"
CFLAGS="$CFLAGS -Wall -I." CFLAGS="$CFLAGS -Wall -I."
LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS"
LDFLAGSCLI="$LDFLAGSCLI"
ASFLAGS="$ASFLAGS" ASFLAGS="$ASFLAGS"
HAVE_GETOPT_LONG=1 HAVE_GETOPT_LONG=1
cross_prefix="" cross_prefix=""
...@@ -95,17 +100,24 @@ for opt do ...@@ -95,17 +100,24 @@ for opt do
--disable-asm) --disable-asm)
asm="no" asm="no"
;; ;;
--enable-avs-input=*) --enable-avs-input)
avs_input="$optarg" avs_input="auto"
if [ "$avs_input" != "auto" -a "$avs_input" != "vfw" -a "$avs_input" != "avs" ] ; then
echo "unrecognized enable-avis-input option '$avs_input'"
echo "available options are 'auto', 'avs', or 'vfw'"
avs_input="auto"
fi
;; ;;
--disable-avs-input) --disable-avs-input)
avs_input="no" avs_input="no"
;; ;;
--enable-lavf-input)
lavf_input="auto"
;;
--disable-lavf-input)
lavf_input="no"
;;
--enable-ffms-input)
ffms_input="auto"
;;
--disable-ffms-input)
ffms_input="no"
;;
--enable-mp4-output) --enable-mp4-output)
mp4_output="yes" mp4_output="yes"
;; ;;
...@@ -402,6 +414,48 @@ if test "$pthread" = "yes" ; then ...@@ -402,6 +414,48 @@ if test "$pthread" = "yes" ; then
LDFLAGS="$LDFLAGS $libpthread" LDFLAGS="$LDFLAGS $libpthread"
fi fi
if [ "$lavf_input" = "auto" ] ; then
lavf_input="no"
if [ `pkg-config --exists libavformat libavcodec libswscale 2>$DEVNULL` ] ; then
LAVF_LDFLAGS="$LAVF_LDFLAGS $(pkg-config --libs libavformat libavcodec libswscale)"
LAVF_CDFLAGS="$LAVF_CFLAGS $(pkg-config --cflags libavformat libavcodec libswscale)"
fi
if [ -z "$LAVF_LDFLAGS" -a -z "$LAVF_CFLAGS" ]; then
LAVF_LDFLAGS="-lavformat -lswscale"
for lib in -lpostproc -lavcodec -lavutil -lm -lz -lbz2 $libpthread -lavifil32; do
cc_check "" $lib && LAVF_LDFLAGS="$LAVF_LDFLAGS $lib"
done
fi
LAVF_LDFLAGS="-L. $LAVF_LDFLAGS"
if cc_check libavformat/avformat.h "$LAVF_CFLAGS $LAVF_LDFLAGS" && \
cc_check libswscale/swscale.h "$LAVF_CFLAGS $LAVF_LDFLAGS" ; then
# avcodec_decode_video2 is currently the most recently added function that we use; it was added in r18351
if cc_check libavformat/avformat.h "$LAVF_CFLAGS $LAVF_LDFLAGS" "avcodec_decode_video2( NULL, NULL, NULL, NULL );" ; then
lavf_input="yes"
echo "#define LAVF_INPUT" >> config.h
LDFLAGSCLI="$LDFLAGSCLI $LAVF_LDFLAGS"
[ -n "$LAVF_CFLAGS" ] && CFLAGS="$CFLAGS $LAVF_CFLAGS"
else
echo "Warning: libavformat is too old, update to ffmpeg r18351+"
fi
fi
fi
if [ "$ffms_input" = "auto" ] ; then
ffms_input="no"
if [ "$lavf_input" = "yes" ] ; then
if cc_check ffms.h -lFFMS2 "FFMS_DestroyVideoSource(0);" ; then
ffms_input="yes"
echo "#define FFMS_INPUT" >> config.h
LDFLAGSCLI="$LDFLAGSCLI -lFFMS2"
elif cc_check ffms.h "-lFFMS2 $LAVF_LDFLAGS -lstdc++" "FFMS_DestroyVideoSource(0);" ; then
ffms_input="yes"
echo "#define FFMS_INPUT" >> config.h
LDFLAGSCLI="-lFFMS2 $LDFLAGSCLI -lstdc++"
fi
fi
fi
MP4_LDFLAGS="-lgpac_static" MP4_LDFLAGS="-lgpac_static"
if [ $SYS = MINGW ]; then if [ $SYS = MINGW ]; then
MP4_LDFLAGS="$MP4_LDFLAGS -lwinmm" MP4_LDFLAGS="$MP4_LDFLAGS -lwinmm"
...@@ -412,32 +466,18 @@ if [ "$mp4_output" = "auto" ] ; then ...@@ -412,32 +466,18 @@ if [ "$mp4_output" = "auto" ] ; then
fi fi
if [ "$mp4_output" = "yes" ] ; then if [ "$mp4_output" = "yes" ] ; then
echo "#define MP4_OUTPUT" >> config.h echo "#define MP4_OUTPUT" >> config.h
LDFLAGS="$LDFLAGS $MP4_LDFLAGS" LDFLAGSCLI="$LDFLAGSCLI $MP4_LDFLAGS"
fi fi
if [ "$avs_input" = "auto" -o "$avs_input" = "avs" ] ; then if [ "$avs_input" = "auto" ] ; then
avs_input=no
if [ $SYS = MINGW ] && cc_check avisynth_c.h ; then if [ $SYS = MINGW ] && cc_check avisynth_c.h ; then
avs_input="avs" avs_input="yes"
echo "#define AVS_INPUT" >> config.h echo "#define AVS_INPUT" >> config.h
echo "#define HAVE_AVISYNTH_C_H" >> config.h echo "#define HAVE_AVISYNTH_C_H" >> config.h
elif [ $SYS = MINGW ] && cc_check extras/avisynth_c.h ; then elif [ $SYS = MINGW ] && cc_check extras/avisynth_c.h ; then
avs_input="avs" avs_input="yes"
echo "#define AVS_INPUT" >> config.h echo "#define AVS_INPUT" >> config.h
else
avs_input="auto"
fi
fi
if [ "$avs_input" = "auto" -o "$avs_input" = "vfw" ] ; then
if [ $SYS = MINGW ] && cc_check "stdlib.h" -lvfw32 ; then
echo "#define VFW_INPUT" >> config.h
LDFLAGS="$LDFLAGS -lvfw32"
avs_input="vfw"
elif [ $SYS = MINGW ] && cc_check "stdlib.h" -lavifil32 ; then
echo "#define VFW_INPUT" >> config.h
LDFLAGS="$LDFLAGS -lavifil32"
avs_input="vfw"
else
avs_input="no";
fi fi
fi fi
...@@ -486,6 +526,7 @@ SYS=$SYS ...@@ -486,6 +526,7 @@ SYS=$SYS
CC=$CC CC=$CC
CFLAGS=$CFLAGS CFLAGS=$CFLAGS
LDFLAGS=$LDFLAGS LDFLAGS=$LDFLAGS
LDFLAGSCLI=$LDFLAGSCLI
AR=$AR AR=$AR
RANLIB=$RANLIB RANLIB=$RANLIB
STRIP=$STRIP STRIP=$STRIP
...@@ -541,6 +582,8 @@ echo "Platform: $ARCH" ...@@ -541,6 +582,8 @@ echo "Platform: $ARCH"
echo "System: $SYS" echo "System: $SYS"
echo "asm: $asm" echo "asm: $asm"
echo "avs input: $avs_input" echo "avs input: $avs_input"
echo "lavf input: $lavf_input"
echo "ffms input: $ffms_input"
echo "mp4 output: $mp4_output" echo "mp4 output: $mp4_output"
echo "pthread: $pthread" echo "pthread: $pthread"
echo "debug: $debug" echo "debug: $debug"
......
...@@ -395,7 +395,8 @@ static int x264_validate_parameters( x264_t *h ) ...@@ -395,7 +395,8 @@ static int x264_validate_parameters( x264_t *h )
h->param.i_width, h->param.i_height ); h->param.i_width, h->param.i_height );
return -1; return -1;
} }
if( h->param.i_csp != X264_CSP_I420 && h->param.i_csp != X264_CSP_YV12 ) int i_csp = h->param.i_csp & X264_CSP_MASK;
if( i_csp != X264_CSP_I420 && i_csp != X264_CSP_YV12 )
{ {
x264_log( h, X264_LOG_ERROR, "invalid CSP (only I420/YV12 supported)\n" ); x264_log( h, X264_LOG_ERROR, "invalid CSP (only I420/YV12 supported)\n" );
return -1; return -1;
...@@ -560,6 +561,12 @@ static int x264_validate_parameters( x264_t *h ) ...@@ -560,6 +561,12 @@ static int x264_validate_parameters( x264_t *h )
h->param.rc.i_lookahead = X264_MIN( h->param.rc.i_lookahead, X264_MAX( h->param.i_keyint_max, bufsize*fps ) ); h->param.rc.i_lookahead = X264_MIN( h->param.rc.i_lookahead, X264_MAX( h->param.i_keyint_max, bufsize*fps ) );
} }
if( !h->param.i_timebase_num || !h->param.i_timebase_den )
{
h->param.i_timebase_num = h->param.i_fps_den;
h->param.i_timebase_den = h->param.i_fps_num;
}
h->param.rc.f_qcompress = x264_clip3f( h->param.rc.f_qcompress, 0.0, 1.0 ); h->param.rc.f_qcompress = x264_clip3f( h->param.rc.f_qcompress, 0.0, 1.0 );
if( !h->param.rc.i_lookahead || h->param.i_keyint_max == 1 || h->param.rc.f_qcompress == 1 ) if( !h->param.rc.i_lookahead || h->param.i_keyint_max == 1 || h->param.rc.f_qcompress == 1 )
h->param.rc.b_mb_tree = 0; h->param.rc.b_mb_tree = 0;
...@@ -833,6 +840,7 @@ x264_t *x264_encoder_open( x264_param_t *param ) ...@@ -833,6 +840,7 @@ x264_t *x264_encoder_open( x264_param_t *param )
x264_set_aspect_ratio( h, param, 1 ); x264_set_aspect_ratio( h, param, 1 );
x264_reduce_fraction( &h->param.i_fps_num, &h->param.i_fps_den ); x264_reduce_fraction( &h->param.i_fps_num, &h->param.i_fps_den );
x264_reduce_fraction( &h->param.i_timebase_num, &h->param.i_timebase_den );
/* Init x264_t */ /* Init x264_t */
h->i_frame = -1; h->i_frame = -1;
...@@ -866,6 +874,7 @@ x264_t *x264_encoder_open( x264_param_t *param ) ...@@ -866,6 +874,7 @@ x264_t *x264_encoder_open( x264_param_t *param )
h->frames.i_delay += h->param.i_threads - 1; h->frames.i_delay += h->param.i_threads - 1;
h->frames.i_delay = X264_MIN( h->frames.i_delay, X264_LOOKAHEAD_MAX ); h->frames.i_delay = X264_MIN( h->frames.i_delay, X264_LOOKAHEAD_MAX );
h->frames.i_delay += h->param.i_sync_lookahead; h->frames.i_delay += h->param.i_sync_lookahead;
h->frames.i_bframe_delay = h->param.i_bframe ? (h->param.i_bframe_pyramid ? 2 : 1) : 0;
h->frames.i_max_ref0 = h->param.i_frame_reference; h->frames.i_max_ref0 = h->param.i_frame_reference;
h->frames.i_max_ref1 = h->sps->vui.i_num_reorder_frames; h->frames.i_max_ref1 = h->sps->vui.i_num_reorder_frames;
...@@ -1542,7 +1551,7 @@ static inline void x264_reference_hierarchy_reset( x264_t *h ) ...@@ -1542,7 +1551,7 @@ static inline void x264_reference_hierarchy_reset( x264_t *h )
/* look for delay frames -- chain must only contain frames that are disposable */ /* look for delay frames -- chain must only contain frames that are disposable */
for( i = 0; h->frames.current[i] && IS_DISPOSABLE( h->frames.current[i]->i_type ); i++ ) for( i = 0; h->frames.current[i] && IS_DISPOSABLE( h->frames.current[i]->i_type ); i++ )
b_hasdelayframe |= h->frames.current[i]->i_dts b_hasdelayframe |= h->frames.current[i]->i_coded
!= h->frames.current[i]->i_frame + h->sps->vui.i_num_reorder_frames; != h->frames.current[i]->i_frame + h->sps->vui.i_num_reorder_frames;
if( h->param.i_bframe_pyramid != X264_B_PYRAMID_STRICT && !b_hasdelayframe ) if( h->param.i_bframe_pyramid != X264_B_PYRAMID_STRICT && !b_hasdelayframe )
...@@ -2040,6 +2049,9 @@ int x264_encoder_encode( x264_t *h, ...@@ -2040,6 +2049,9 @@ int x264_encoder_encode( x264_t *h,
fenc->i_frame = h->frames.i_input++; fenc->i_frame = h->frames.i_input++;
if( h->frames.i_bframe_delay && fenc->i_frame == h->frames.i_bframe_delay )
h->frames.i_bframe_delay_time = fenc->i_pts;
if( h->frames.b_have_lowres ) if( h->frames.b_have_lowres )
{ {
if( h->param.analyse.i_weighted_pred == X264_WEIGHTP_FAKE || h->param.analyse.i_weighted_pred == X264_WEIGHTP_SMART ) if( h->param.analyse.i_weighted_pred == X264_WEIGHTP_FAKE || h->param.analyse.i_weighted_pred == X264_WEIGHTP_SMART )
...@@ -2308,7 +2320,9 @@ static int x264_encoder_frame_end( x264_t *h, x264_t *thread_current, ...@@ -2308,7 +2320,9 @@ static int x264_encoder_frame_end( x264_t *h, x264_t *thread_current,
pic_out->i_type = X264_TYPE_P; pic_out->i_type = X264_TYPE_P;
else else
pic_out->i_type = X264_TYPE_B; pic_out->i_type = X264_TYPE_B;
pic_out->i_pts = h->fenc->i_pts; pic_out->i_pts = h->fenc->i_pts;
pic_out->i_dts = h->fenc->i_dts - h->frames.i_bframe_delay_time;
pic_out->img.i_plane = h->fdec->i_plane; pic_out->img.i_plane = h->fdec->i_plane;
for(i = 0; i < 3; i++) for(i = 0; i < 3; i++)
......
...@@ -180,12 +180,12 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param ) ...@@ -180,12 +180,12 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
} }
sps->vui.b_timing_info_present = 0; sps->vui.b_timing_info_present = 0;
if( param->i_fps_num > 0 && param->i_fps_den > 0) if( param->i_timebase_num > 0 && param->i_timebase_den > 0 )
{ {
sps->vui.b_timing_info_present = 1; sps->vui.b_timing_info_present = 1;
sps->vui.i_num_units_in_tick = param->i_fps_den; sps->vui.i_num_units_in_tick = param->i_timebase_num;
sps->vui.i_time_scale = param->i_fps_num * 2; sps->vui.i_time_scale = param->i_timebase_den * 2;
sps->vui.b_fixed_frame_rate = 1; sps->vui.b_fixed_frame_rate = !param->b_vfr_input;
} }
sps->vui.i_num_reorder_frames = param->i_bframe_pyramid ? 2 : param->i_bframe ? 1 : 0; sps->vui.i_num_reorder_frames = param->i_bframe_pyramid ? 2 : param->i_bframe ? 1 : 0;
......
...@@ -1327,17 +1327,22 @@ void x264_slicetype_decide( x264_t *h ) ...@@ -1327,17 +1327,22 @@ void x264_slicetype_decide( x264_t *h )
/* shift sequence to coded order. /* shift sequence to coded order.
use a small temporary list to avoid shifting the entire next buffer around */ use a small temporary list to avoid shifting the entire next buffer around */
int i_dts = h->lookahead->next.list[0]->i_frame; int i_coded = h->lookahead->next.list[0]->i_frame;
if( bframes ) if( bframes )
{ {
int index[] = { brefs+1, 1 }; int index[] = { brefs+1, 1 };
for( i = 0; i < bframes; i++ ) for( i = 0; i < bframes; i++ )
frames[ index[h->lookahead->next.list[i]->i_type == X264_TYPE_BREF]++ ] = h->lookahead->next.list[i]; {
int idx = index[h->lookahead->next.list[i]->i_type == X264_TYPE_BREF]++;
frames[idx] = h->lookahead->next.list[i];
frames[idx]->i_dts = h->lookahead->next.list[idx]->i_pts;
}
frames[0] = h->lookahead->next.list[bframes]; frames[0] = h->lookahead->next.list[bframes];
frames[0]->i_dts = h->lookahead->next.list[0]->i_pts;
memcpy( h->lookahead->next.list, frames, (bframes+1) * sizeof(x264_frame_t*) ); memcpy( h->lookahead->next.list, frames, (bframes+1) * sizeof(x264_frame_t*) );
} }
for( i = 0; i <= bframes; i++ ) for( i = 0; i <= bframes; i++ )
h->lookahead->next.list[i]->i_dts = i_dts++; h->lookahead->next.list[i]->i_coded = i_coded++;
} }
int x264_rc_analyse_slice( x264_t *h ) int x264_rc_analyse_slice( x264_t *h )
......
...@@ -117,7 +117,7 @@ static void avs_build_filter_sequence( char *filename_ext, const char *filter[AV ...@@ -117,7 +117,7 @@ static void avs_build_filter_sequence( char *filename_ext, const char *filter[AV
filter[i++] = all_purpose[j]; filter[i++] = all_purpose[j];
} }
static int open_file( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param ) static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt )
{ {
FILE *fh = fopen( psz_filename, "r" ); FILE *fh = fopen( psz_filename, "r" );
if( !fh ) if( !fh )
...@@ -175,7 +175,7 @@ static int open_file( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param ...@@ -175,7 +175,7 @@ static int open_file( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param
int i; int i;
for( i = 0; filter[i]; i++ ) for( i = 0; filter[i]; i++ )
{ {
fprintf( stderr, "avs [info]: Trying %s... ", filter[i] ); fprintf( stderr, "avs [info]: trying %s... ", filter[i] );
if( !h->func.avs_function_exists( h->env, filter[i] ) ) if( !h->func.avs_function_exists( h->env, filter[i] ) )
{ {
fprintf( stderr, "not found\n" ); fprintf( stderr, "not found\n" );
...@@ -183,7 +183,7 @@ static int open_file( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param ...@@ -183,7 +183,7 @@ static int open_file( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param
} }
if( !strncasecmp( filter[i], "FFmpegSource", 12 ) ) if( !strncasecmp( filter[i], "FFmpegSource", 12 ) )
{ {
fprintf( stderr, "Indexing... " ); fprintf( stderr, "indexing... " );
fflush( stderr ); fflush( stderr );
} }
res = h->func.avs_invoke( h->env, filter[i], arg, NULL ); res = h->func.avs_invoke( h->env, filter[i], arg, NULL );
...@@ -225,13 +225,13 @@ static int open_file( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param ...@@ -225,13 +225,13 @@ static int open_file( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param
{ {
h->func.avs_release_clip( h->clip ); h->func.avs_release_clip( h->clip );
fprintf( stderr, "avs %s\n", !avs_is_yv12( vi ) ? "[warning]: converting input clip to YV12" fprintf( stderr, "avs %s\n", !avs_is_yv12( vi ) ? "[warning]: converting input clip to YV12"
: "[info]: Avisynth 2.6+ detected, forcing conversion to YV12" ); : "[info]: avisynth 2.6+ detected, forcing conversion to YV12" );
const char *arg_name[2] = { NULL, "interlaced" }; const char *arg_name[2] = { NULL, "interlaced" };
AVS_Value arg_arr[2] = { res, avs_new_value_bool( p_param->b_interlaced ) }; AVS_Value arg_arr[2] = { res, avs_new_value_bool( info->interlaced ) };
AVS_Value res2 = h->func.avs_invoke( h->env, "ConvertToYV12", avs_new_value_array( arg_arr, 2 ), arg_name ); AVS_Value res2 = h->func.avs_invoke( h->env, "ConvertToYV12", avs_new_value_array( arg_arr, 2 ), arg_name );
if( avs_is_error( res2 ) ) if( avs_is_error( res2 ) )
{ {
fprintf( stderr, "avs [error]: Couldn't convert input clip to YV12\n" ); fprintf( stderr, "avs [error]: couldn't convert input clip to YV12\n" );
return -1; return -1;
} }
h->clip = h->func.avs_take_clip( res2, h->env ); h->clip = h->func.avs_take_clip( res2, h->env );
...@@ -240,17 +240,13 @@ static int open_file( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param ...@@ -240,17 +240,13 @@ static int open_file( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param
} }
h->func.avs_release_value( res ); h->func.avs_release_value( res );
p_param->i_width = vi->width; info->width = vi->width;
p_param->i_height = vi->height; info->height = vi->height;
p_param->i_fps_num = vi->fps_numerator; info->fps_num = vi->fps_numerator;
p_param->i_fps_den = vi->fps_denominator; info->fps_den = vi->fps_denominator;
h->num_frames = vi->num_frames; h->num_frames = vi->num_frames;
p_param->i_csp = X264_CSP_YV12; info->csp = X264_CSP_YV12;
info->vfr = 0;
fprintf( stderr, "avs [info]: %dx%d @ %.2f fps (%d frames)\n",
p_param->i_width, p_param->i_height,
(double)p_param->i_fps_num / p_param->i_fps_den,
h->num_frames );
*p_handle = h; *p_handle = h;
return 0; return 0;
......
/*****************************************************************************
* ffms.c: x264 ffmpegsource input module
*****************************************************************************
* Copyright (C) 2009 x264 project
*
* Authors: Mike Gurlitz <mike.gurlitz@gmail.com>
* Steven Walters <kemuri9@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
*****************************************************************************/
#include "muxers.h"
#include <ffms.h>
#undef DECLARE_ALIGNED
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#ifdef _WIN32
#include <windows.h>
#else
#define SetConso