All pastes #1616902 Raw Edit

Untitled

public diff v1 · immutable
#1616902 ·published 2009-10-13 00:06 UTC
rendered paste body
diff --git a/configure b/configureindex d26ace1..f451f33 100755--- a/configure+++ b/configure@@ -8,6 +8,7 @@ echo "available options:" echo "" echo "  --help                   print this message" echo "  --disable-avis-input     disables avisynth input (win32 only)"+echo "  --disable-lavc-input     disables libavcodec 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 +53,7 @@ includedir='${prefix}/include' DEVNULL='/dev/null'  avis_input="auto"+lavc_input="auto" mp4_output="auto" pthread="auto" asm="yes"@@ -101,6 +103,12 @@ for opt do         --disable-avis-input)             avis_input="no"             ;;+        --enable-lavc-input)+            lavc_input="yes"+            ;;+        --disable-lavc-input)+            lavc_input="no"+            ;;         --enable-mp4-output)             mp4_output="yes"             ;;@@ -423,6 +431,14 @@ if [ "$avis_input" = "yes" ] ; then     fi fi +if [ "$lavc_input" = "auto" ] ; then+    cc_check libavcodec/avcodec.h "-lavcodec" && cc_check libavformat/avformat.h "-lavformat" && lavc_input="yes" || lavc_input="no"+fi+if [ "$lavc_input" = "yes" ] ; then+    echo "#define LAVC_INPUT" >> config.h+    LDFLAGS="$LDFLAGS -lavcodec -lavformat -lavutil"+fi+ if [ "$pic" = "yes" ] ; then     CFLAGS="$CFLAGS -fPIC"     ASFLAGS="$ASFLAGS -DPIC"@@ -524,6 +540,7 @@ echo "Platform:   $ARCH" echo "System:     $SYS" echo "asm:        $asm" echo "avis input: $avis_input"+echo "lavc input: $lavc_input" echo "mp4 output: $mp4_output" echo "pthread:    $pthread" echo "debug:      $debug"diff --git a/muxers.c b/muxers.cindex c9b8dfa..a5cd8f8 100644--- a/muxers.c+++ b/muxers.c@@ -38,6 +38,12 @@ #include <gpac/isomedia.h> #endif +#ifdef LAVC_INPUT+#include <libavformat/avformat.h>+#include <libavcodec/avcodec.h>+#include <sys/stat.h>+#endif+ static int64_t gcd( int64_t a, int64_t b ) {     while( 1 )@@ -423,6 +429,159 @@ int close_file_avis( hnd_t handle ) } #endif +/* libavcodec file input */++#ifdef LAVC_INPUT+typedef struct+{+    AVFormatContext *context;+    const char *file;+    int stream_id, next_frame, frame_count;+    int64_t pts;+} lavc_input_t;++int decode_frame_lavc( lavc_input_t *h, AVFrame *frame )+{+    int finished = 0;+    AVPacket pkt;+    av_init_packet( &pkt );+    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 );+        h->pts = pkt.pts;+        av_free_packet( &pkt );+    }+    return finished;+}++int open_file_lavc( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param )+{+    int is_pipe = 0;+    struct stat pipe_s;+    lavc_input_t *h = malloc( sizeof(lavc_input_t) );+    av_register_all();+    h->context = avformat_alloc_context();+    h->next_frame = 0;+    h->file = psz_filename;+    if( strcmp( h->file, "-" ) )+    {+        if( stat(h->file, &pipe_s) != 0 )+            return -1;+        if( pipe_s.st_mode & S_IFIFO )+            is_pipe = 1;+    }+    else+    {+        h->file = "pipe:";+        is_pipe = 1;+    }+    if( is_pipe && !p_param->b_user_fps )+    {+        fprintf( stderr, "x264 [error]: Input file is not seekable but requires seeking to determine fps.\n" );+        fprintf( stderr, "x264 [error]: Specify an fps.\n" );+        return -1;+    }+    +    if( av_open_input_file( &h->context, h->file, 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;+    AVCodecContext *c = h->context->streams[i]->codec;+    if( avcodec_open( c, avcodec_find_decoder( c->codec_id ) ) != 0 )+        return -1;+    p_param->i_width = c->width;+    p_param->i_height = c->height;+    h->frame_count = -1;+    *p_handle = (hnd_t)h;+    +    if( !p_param->b_user_fps )+    {+        char index_fn[ strlen( psz_filename ) + 7 ];+        sprintf( index_fn, ".%s.index", psz_filename );+        FILE *f = fopen( index_fn, "r" );+        +        if( f )+        {+            struct stat index_s, input_s;+            stat( index_fn, &index_s );+            stat( psz_filename, &input_s );+            float fps;+            if( difftime( index_s.st_mtime, input_s.st_mtime ) > 0 && fscanf( f, "%d %f\n", &h->frame_count, &fps) > 0 )+            {+                p_param->i_fps_num = (int)(fps + .5);+                p_param->i_fps_den = 1000;+                fclose( f );+                return 0;+            }+            fclose( f );+        }+        +        AVFrame *frame = avcodec_alloc_frame();+        i = 0;+        char buf[200];+        int64_t start = x264_mdate();+        while( decode_frame_lavc( h, frame ) )+        {+            if( i ++ % 10 == 0 )+            {+                sprintf( buf, "Analyzing: %d frames: %.2f fps", i, i * 1000000. / (x264_mdate() - start) );+                fprintf( stderr, "%s  \r", buf );+                fflush( stderr ); // needed in windows+            }+        }+        av_free( frame );+        if( av_seek_frame( h->context, h->stream_id, 0, 0 ) < 0 )+            return -1;+        h->frame_count = i;+        double fps = (i - 1.)/h->pts * AV_TIME_BASE / 100;+        p_param->i_fps_num = (int)(fps * 1000 + .5);+        p_param->i_fps_den = 1000;+        +        f = fopen( index_fn, "w" );+        fprintf( f, "%d %f\n", h->frame_count, fps * 1000 );+        fclose( f );+    }+    return 0;+}++int get_frame_total_lavc( hnd_t handle )+{+    return ((lavc_input_t *)handle)->frame_count;+}++int read_frame_lavc( x264_picture_t *p_pic, hnd_t handle, int i_frame )+{+    lavc_input_t *h = handle;+    AVFrame *frame = avcodec_alloc_frame();+    while( i_frame >= h->next_frame )+    {+        if( decode_frame_lavc( h, frame ) == 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_lavc( hnd_t handle )+{+    lavc_input_t *h = handle;+    av_free( h->context );+    free( h );+    return 0;+}+#endif  #ifdef HAVE_PTHREAD typedef struct@@ -523,7 +682,10 @@ 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 LAVC_INPUT+    if( h->p_read_frame != read_frame_lavc )+    #endif+        x264_picture_clean( &h->pic );     free( h->next_args );     free( h );     return 0;diff --git a/muxers.h b/muxers.hindex aaede1c..62872bd 100644--- a/muxers.h+++ b/muxers.h@@ -41,6 +41,11 @@ int get_frame_total_avis( hnd_t handle ); int read_frame_avis( x264_picture_t *p_pic, hnd_t handle, int i_frame ); int close_file_avis( hnd_t handle ); +int open_file_lavc( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param );+int get_frame_total_lavc( hnd_t handle );+int read_frame_lavc( x264_picture_t *p_pic, hnd_t handle, int i_frame );+int close_file_lavc( hnd_t handle );+ int open_file_thread( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param ); int get_frame_total_thread( hnd_t handle ); int read_frame_thread( x264_picture_t *p_pic, hnd_t handle, int i_frame );diff --git a/x264.c b/x264.cindex a440ab7..56a1d97 100644--- a/x264.c+++ b/x264.c@@ -399,6 +399,7 @@ static void Help( x264_param_t *defaults, int longhelp ) #define OPT_SLOWFIRSTPASS 267 #define OPT_FULLHELP 268 #define OPT_FPS 269+#define OPT_LAVC_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 +523,7 @@ static struct option long_options[] =     { "transfer",    required_argument, NULL, 0 },     { "colormatrix", required_argument, NULL, 0 },     { "chromaloc",   required_argument, NULL, 0 },+    { "lavc-input",        no_argument, NULL, OPT_LAVC_INPUT},     {0, 0, 0, 0} }; @@ -537,6 +539,7 @@ static int  Parse( int argc, char **argv,     char *profile = NULL;     int b_avis = 0;     int b_y4m = 0;+    int b_lavc = 0;     int b_thread_input = 0;     int b_turbo = 1;     int b_pass1 = 0;@@ -863,6 +866,9 @@ static int  Parse( int argc, char **argv,             case OPT_FPS:                 b_user_fps = 1;                 goto generic_option;+            case OPT_LAVC_INPUT:+                b_lavc = 1;+                break;             default: generic_option:             {@@ -960,7 +966,7 @@ generic_option:     if( !strncasecmp( psz, ".y4m", 4 ) )         b_y4m = 1; -    if( !(b_avis || b_y4m) ) // raw yuv+    if( !(b_avis || b_y4m || b_lavc) ) // raw yuv     {         if( optind > argc - 1 )         {@@ -984,7 +990,7 @@ generic_option:         }     } -    if( !(b_avis || b_y4m) && ( !param->i_width || !param->i_height ) )+    if( !(b_avis || b_y4m || b_lavc ) && ( !param->i_width || !param->i_height ) )     {         fprintf( stderr, "x264 [error]: Rawyuv input requires a resolution.\n" );         return -1;@@ -1013,6 +1019,19 @@ generic_option:             p_read_frame = read_frame_y4m;             p_close_infile = close_file_y4m;         }+        if( b_lavc )+        {+#ifdef LAVC_INPUT+            param->b_user_fps = b_user_fps;+            p_open_infile = open_file_lavc;+            p_get_frame_total = get_frame_total_lavc;+            p_read_frame = read_frame_lavc;+            p_close_infile = close_file_lavc;+#else+            fprintf( stderr, "x264 [error]: not compiled with libavcodec input support\n" );+            return -1;+#endif+        }          if( p_open_infile( psz_filename, &opt->hin, param ) )         {@@ -1168,9 +1187,14 @@ static int  Encode( x264_param_t *param, cli_opt_t *opt )     int64_t i_file;     int     i_frame_size;     int     i_update_interval;+    int     b_lavc;      opt->b_progress &= param->i_log_level < X264_LOG_DEBUG;     i_frame_total = p_get_frame_total( opt->hin );+    if( i_frame_total == -1 ) {+        b_lavc = 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 )@@ -1246,7 +1270,8 @@ static int  Encode( x264_param_t *param, cli_opt_t *opt )     }      i_end = x264_mdate();-    x264_picture_clean( &pic );+    if( !b_lavc )+        x264_picture_clean( &pic );     /* Erase progress indicator before printing encoding stats. */     if( opt->b_progress )         fprintf( stderr, "                                                                               \r" );diff --git a/x264.h b/x264.hindex 7bc2d36..d96477d 100644--- a/x264.h+++ b/x264.h@@ -187,6 +187,7 @@ typedef struct x264_param_t      int         i_fps_num;     int         i_fps_den;+    int         b_user_fps;      /* Bitstream parameters */     int         i_frame_reference;  /* Maximum number of reference frames */