All pastes #1620972 Raw Edit

Mine

public diff v1 · immutable
#1620972 ·published 2009-10-15 00:03 UTC
rendered paste body
diff --git a/configure b/configureindex d26ace1..35c50c0 100755--- a/configure+++ b/configure@@ -8,6 +8,8 @@ echo "available options:" echo "" echo "  --help                   print this message" echo "  --disable-avis-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-pthread        disables multithreaded encoding" echo "  --disable-asm            disables assembly optimizations on x86 and arm"@@ -52,6 +54,8 @@ includedir='${prefix}/include' DEVNULL='/dev/null'  avis_input="auto"+lavf_input="auto"+ffms_input="auto" mp4_output="auto" pthread="auto" asm="yes"@@ -101,6 +105,18 @@ for opt do         --disable-avis-input)             avis_input="no"             ;;+        --enable-lavf-input)+            lavf_input="yes"+            ;;+        --disable-lavf-input)+            lavf_input="no"+            ;;+        --enable-ffms-input)+            ffms_input="yes"+            ;;+        --disable-ffms-input)+            ffms_input="no"+            ;;         --enable-mp4-output)             mp4_output="yes"             ;;@@ -423,6 +439,24 @@ if [ "$avis_input" = "yes" ] ; then     fi fi +if [ "$lavf_input" = "auto" ] ; then+	lavf_input="no"+	cc_check "libavformat/avformat.h" "-lavformat" && lavf_input="yes"+fi+if [ "$lavf_input" = "yes" ] ; then+    echo "#define LAVF_INPUT" >> config.h+    LDFLAGS="$LDFLAGS -lavformat -lavcodec -lavutil"+fi++if [ "$ffms_input" = "auto" ] ; then+	ffms_input="no"+	[ "$lavf_input" = "yes" ] && cc_check "ffms.h" "-lFFMS2" && ffms_input="yes"+fi+if [ "$ffms_input" = "yes" ] ; then+    echo "#define FFMS_INPUT" >> config.h+    LDFLAGS="$LDFLAGS -lFFMS2"+fi+ if [ "$pic" = "yes" ] ; then     CFLAGS="$CFLAGS -fPIC"     ASFLAGS="$ASFLAGS -DPIC"@@ -524,6 +558,8 @@ echo "Platform:   $ARCH" echo "System:     $SYS" echo "asm:        $asm" echo "avis input: $avis_input"+echo "lavf input: $lavf_input"+echo "ffms input: $ffms_input" echo "mp4 output: $mp4_output" echo "pthread:    $pthread" echo "debug:      $debug"diff --git a/muxers.c b/muxers.cindex c9b8dfa..23df313 100644--- a/muxers.c+++ b/muxers.c@@ -38,6 +38,14 @@ #include <gpac/isomedia.h> #endif +#ifdef FFMS_INPUT+#include <ffms.h>+#endif++#ifdef LAVF_INPUT+#include <libavformat/avformat.h>+#endif+ static int64_t gcd( int64_t a, int64_t b ) {     while( 1 )@@ -328,6 +336,142 @@ int close_file_y4m(hnd_t handle)     return 0; } +/* libavformat input file support */++#ifdef LAVF_INPUT+typedef struct+{+    AVFormatContext *context;+    int stream_id, next_frame;+} lavf_input_t;++int open_file_lavf( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param )+{+    lavf_input_t *h = malloc( sizeof(lavf_input_t) );+    av_register_all();+    if( av_open_input_file( &h->context, psz_filename, NULL, 0, NULL ) != 0 || av_find_stream_info( h->context ) < 0 )+        return -1;+    int i = 0;+    while( i < h->context->nb_streams && h->context->streams[i]->codec->codec_type != CODEC_TYPE_VIDEO )+        i++;+    if( i == h->context->nb_streams )+        return -1;+    h->stream_id = i;+    h->next_frame = 0;+    *p_handle = (hnd_t)h;+    AVCodecContext *c = h->context->streams[i]->codec;+    p_param->i_width = c->width;+    p_param->i_height = c->height;+    if( avcodec_open( c, avcodec_find_decoder( c->codec_id ) ) != 0 )+        return -1;+    return 0;+}++int get_frame_total_lavf( hnd_t handle )+{+    return 0;+}++int read_frame_lavf( x264_picture_t *p_pic, hnd_t handle, int i_frame )+{+    lavf_input_t *h = handle;+    AVFrame *frame = avcodec_alloc_frame();+    AVPacket pkt;+    av_init_packet( &pkt );+    while( i_frame >= h->next_frame )+    {+        int finished = 0;+        while( !finished && av_read_frame( h->context, &pkt ) >= 0 )+        {+            if( pkt.stream_index == h->stream_id )+                avcodec_decode_video2( h->context->streams[h->stream_id]->codec, frame, &finished, &pkt );+        }+        if( finished == 0 )+            return -1;+        h->next_frame ++;+    }+    int i;+    for( i = 0; i < 3; i ++ )+    {+        p_pic->img.plane[i] = frame->data[i];+        p_pic->img.i_stride[i] = frame->linesize[i];+    }+    av_free( frame );+    return 0;++}++int close_file_lavf( hnd_t handle )+{+    free( handle );+    return 0;+}+#endif++/* ffmpegsource input file support */++#ifdef FFMS_INPUT+typedef struct+{+    FFMS_VideoSource *video_source;+    int total_frames;+} ffms_input_t;++int open_file_ffms( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param )+{+    ffms_input_t *h = malloc( sizeof(ffms_input_t) );+    *p_handle = (hnd_t)h;+    FFMS_Init( 0 );+    FFMS_ErrorInfo e;+    FFMS_Index *index = FFMS_MakeIndex( psz_filename, 0, 0, NULL, NULL, 0, NULL, NULL, &e );+    if( index == NULL )+        return -1;+    int trackno = FFMS_GetFirstTrackOfType( index, FFMS_TYPE_VIDEO, &e );+    h->video_source = FFMS_CreateVideoSource( psz_filename, trackno, index, 1, FFMS_SEEK_NORMAL, &e );+    FFMS_DestroyIndex( index );+    FFMS_VideoProperties *videop = FFMS_GetVideoProperties( h->video_source );+    h->total_frames = videop->NumFrames;+    // int64_t pixfmt = (int64_t)1 << FFMS_GetPixFmt("yuv420p");+    const FFMS_Frame *frame = FFMS_GetFrame( h->video_source, 0, &e );+    // FFMS_SetOutputFormatV( h->video_source, pixfmt, frame->EncodedWidth, frame->EncodedHeight, FFMS_RESIZER_BICUBIC, &e );+    p_param->i_width = frame->EncodedWidth;+    p_param->i_height = frame->EncodedHeight;+    p_param->i_fps_den = videop->FPSDenominator;+    p_param->i_fps_num = videop->FPSNumerator;+    p_param->vui.i_sar_height = videop->SARDen;+    p_param->vui.i_sar_width = videop->SARNum;+    return 0;+}++int get_frame_total_ffms( hnd_t handle )+{+    return ((ffms_input_t *)handle)->total_frames;+}++int read_frame_ffms( x264_picture_t *p_pic, hnd_t handle, int i_frame )+{+    ffms_input_t *h = handle;+    FFMS_ErrorInfo e;+    e.BufferSize = 0;+    FFMS_Frame *frame = FFMS_GetFrame( h->video_source, i_frame, &e );+    int i;+    for( i = 0; i < 3; i ++ )+    {+        p_pic->img.plane[i] = frame->Data[i];+        p_pic->img.i_stride[i] = frame->Linesize[i];+    }+    return 0;+}++int close_file_ffms( hnd_t handle )+{+    ffms_input_t *h = handle;+    FFMS_DestroyVideoSource( h->video_source );+    free( h );+    return 0;+}+#endif+ /* avs/avi input file support under cygwin */  #ifdef AVIS_INPUT@@ -485,21 +629,19 @@ int read_frame_thread( x264_picture_t *p_pic, hnd_t handle, int i_frame ) {     thread_input_t *h = handle;     int ret = 0;--    if( h->next_frame >= 0 )+    if( h->next_frame >= 0 ) // every time but the first     {-        x264_pthread_join( h->tid, NULL );+        x264_pthread_join( h->tid, NULL ); // wait for frame to finish         ret |= h->next_args->status;         h->in_progress = 0;     }-     if( h->next_frame == i_frame )     {         XCHG( x264_picture_t, *p_pic, h->pic );     }     else     {-        ret |= h->p_read_frame( p_pic, h->p_handle, i_frame );+        ret |= h->p_read_frame( p_pic, h->p_handle, i_frame ); // read frame w/o thread     }      if( !h->frame_total || i_frame+1 < h->frame_total )@@ -507,7 +649,7 @@ int read_frame_thread( x264_picture_t *p_pic, hnd_t handle, int i_frame )         h->next_frame =         h->next_args->i_frame = i_frame+1;         h->next_args->pic = &h->pic;-        if( x264_pthread_create( &h->tid, NULL, (void*)read_frame_thread_int, h->next_args ) )+        if( x264_pthread_create( &h->tid, NULL, (void*)read_frame_thread_int, h->next_args ) ) // read _next_ frame in thread             return -1;         h->in_progress = 1;     }@@ -523,7 +665,13 @@ int close_file_thread( hnd_t handle )     if( h->in_progress )         x264_pthread_join( h->tid, NULL );     h->p_close_infile( h->p_handle );-    x264_picture_clean( &h->pic );+#ifdef LAVF_INPUT+    if( h->p_read_frame != read_frame_lavf )+#ifdef FFMS_INPUT+        if( h->p_read_frame != read_frame_ffms )+#endif+#endif+            x264_picture_clean( &h->pic );     free( h->next_args );     free( h );     return 0;@@ -1045,4 +1193,3 @@ int close_file_mkv( hnd_t handle )      return ret; }-diff --git a/muxers.h b/muxers.hindex aaede1c..000e086 100644--- a/muxers.h+++ b/muxers.h@@ -36,6 +36,16 @@ int get_frame_total_y4m( hnd_t handle ); int read_frame_y4m( x264_picture_t *p_pic, hnd_t handle, int i_frame ); int close_file_y4m( hnd_t handle ); +int open_file_lavf( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param );+int get_frame_total_lavf( hnd_t handle );+int read_frame_lavf( x264_picture_t *p_pic, hnd_t handle, int i_frame );+int close_file_lavf( hnd_t handle );++int open_file_ffms( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param );+int get_frame_total_ffms( hnd_t handle );+int read_frame_ffms( x264_picture_t *p_pic, hnd_t handle, int i_frame );+int close_file_ffms( hnd_t handle );+ int open_file_avis( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param ); int get_frame_total_avis( hnd_t handle ); int read_frame_avis( x264_picture_t *p_pic, hnd_t handle, int i_frame );diff --git a/x264.c b/x264.cindex a440ab7..659cfd8 100644--- a/x264.c+++ b/x264.c@@ -40,6 +40,10 @@ #define SetConsoleTitle(t) #endif +#ifdef LAVF_INPUT+#include <sys/stat.h>+#endif+ uint8_t *mux_buffer = NULL; int mux_buffer_size = 0; @@ -59,6 +63,7 @@ typedef struct {     hnd_t hin;     hnd_t hout;     FILE *qpfile;+    int b_lavf; } cli_opt_t;  /* input file operation function pointers */@@ -399,6 +404,7 @@ static void Help( x264_param_t *defaults, int longhelp ) #define OPT_SLOWFIRSTPASS 267 #define OPT_FULLHELP 268 #define OPT_FPS 269+#define OPT_LAVF_INPUT 270  static char short_options[] = "8A:B:b:f:hI:i:m:o:p:q:r:t:Vvw"; static struct option long_options[] =@@ -522,6 +528,7 @@ static struct option long_options[] =     { "transfer",    required_argument, NULL, 0 },     { "colormatrix", required_argument, NULL, 0 },     { "chromaloc",   required_argument, NULL, 0 },+    { "lavf-input",        no_argument, NULL, OPT_LAVF_INPUT },     {0, 0, 0, 0} }; @@ -845,6 +852,9 @@ static int  Parse( int argc, char **argv,                 fprintf( stderr, "x264 [warning]: not compiled with visualization support\n" ); #endif                 break;+            case OPT_LAVF_INPUT:+                opt->b_lavf = 1;+                break;             case OPT_TUNE:             case OPT_PRESET:                 break;@@ -960,7 +970,7 @@ generic_option:     if( !strncasecmp( psz, ".y4m", 4 ) )         b_y4m = 1; -    if( !(b_avis || b_y4m) ) // raw yuv+    if( !(b_avis || b_y4m || opt->b_lavf) ) // raw yuv     {         if( optind > argc - 1 )         {@@ -984,7 +994,7 @@ generic_option:         }     } -    if( !(b_avis || b_y4m) && ( !param->i_width || !param->i_height ) )+    if( !(b_avis || b_y4m || opt->b_lavf) && ( !param->i_width || !param->i_height ) )     {         fprintf( stderr, "x264 [error]: Rawyuv input requires a resolution.\n" );         return -1;@@ -1013,6 +1023,54 @@ generic_option:             p_read_frame = read_frame_y4m;             p_close_infile = close_file_y4m;         }+        if( opt->b_lavf )+        {+#ifdef LAVF_INPUT+            int b_use_pipe = 0;+            if( strcmp( psz_filename, "-") )+            {+                struct stat pipe_s;+                stat( psz_filename, &pipe_s );+                b_use_pipe = (pipe_s.st_mode & S_IFIFO) != 0;+            }+            else+            {+                b_use_pipe = 1;+                psz_filename = "pipe:";+            }+#ifdef FFMS_INPUT+            if( !b_use_pipe )+            {+                opt->b_lavf = 2;+                p_open_infile = open_file_ffms;+                p_get_frame_total = get_frame_total_ffms;+                p_read_frame = read_frame_ffms;+                p_close_infile = close_file_ffms;+            }+            else+            {+#endif+                if( !b_user_fps )+                {+#ifdef FFMS_INPUT+                    fprintf( stderr, "x264 [error]: Input file is a pipe. Specify an fps.\n" );+#else+                    fprintf( stderr, "x264 [error]: Libavformat cannot determine fps. Specify an fps.\n" );+#endif+                    return -1;+                }+                p_open_infile = open_file_lavf;+                p_get_frame_total = get_frame_total_lavf;+                p_read_frame = read_frame_lavf;+                p_close_infile = close_file_lavf;+#ifdef FFMS_INPUT+            }+#endif+#else+            fprintf( stderr, "x264 [error]: not compiled with libavformat input support\n" );+            return -1;+#endif+        }          if( p_open_infile( psz_filename, &opt->hin, param ) )         {@@ -1171,6 +1229,8 @@ static int  Encode( x264_param_t *param, cli_opt_t *opt )      opt->b_progress &= param->i_log_level < X264_LOG_DEBUG;     i_frame_total = p_get_frame_total( opt->hin );+    if( opt->b_lavf == 1 )+        i_frame_total = opt->i_seek;     i_frame_total -= opt->i_seek;     if( ( i_frame_total == 0 || param->i_frame_total < i_frame_total )         && param->i_frame_total > 0 )@@ -1218,7 +1278,6 @@ static int  Encode( x264_param_t *param, cli_opt_t *opt )             pic.i_type = X264_TYPE_AUTO;             pic.i_qpplus1 = 0;         }-         i_frame_size = Encode_frame( h, opt->hout, &pic );         if( i_frame_size < 0 )             return -1;@@ -1246,7 +1305,8 @@ static int  Encode( x264_param_t *param, cli_opt_t *opt )     }      i_end = x264_mdate();-    x264_picture_clean( &pic );+    if( !opt->b_lavf )+        x264_picture_clean( &pic );     /* Erase progress indicator before printing encoding stats. */     if( opt->b_progress )         fprintf( stderr, "                                                                               \r" );