All pastes #1654173 Raw Edit

Miscellany

public diff v1 · immutable
#1654173 ·published 2009-11-03 02:41 UTC
rendered paste body
diff --git a/Makefile b/Makefileindex 3de0b61..966a867 100644--- a/Makefile+++ b/Makefile@@ -26,6 +26,14 @@ ifneq ($(findstring HAVE_PTHREAD, $(CFLAGS)),) SRCCLI += input/thread.c endif +ifneq ($(findstring FFMS_INPUT, $(MUXERS)),)+SRCCLI += input/ffms.c+endif++ifneq ($(findstring LAVF_INPUT, $(MUXERS)),)+SRCCLI += input/lavf.c+endif+ ifneq ($(findstring MP4_OUTPUT, $(MUXERS)),) SRCCLI += output/mp4.c endifdiff --git a/common/common.c b/common/common.cindex fc8b06a..1e277d2 100644--- a/common/common.c+++ b/common/common.c@@ -610,6 +610,8 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value )         p->b_repeat_headers = atobool(value);     OPT("annexb")         p->b_annexb = atobool(value);+    OPT("ffms-index")+        p->psz_ffms_index = strdup(value);     else         return X264_PARAM_BAD_NAME; #undef OPTdiff --git a/configure b/configureindex d26ace1..040e796 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-ffms-input     disables ffmpegsource input"+echo "  --disable-lavf-input     disables libavformat 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"+ffms_input="auto"+lavf_input="auto" mp4_output="auto" pthread="auto" asm="yes"@@ -101,6 +105,18 @@ for opt do         --disable-avis-input)             avis_input="no"             ;;+        --enable-ffms-input)+            ffms_input="yes"+            ;;+        --disable-ffms-input)+            ffms_input="no"+            ;;+        --enable-lavf-input)+            lavf_input="yes"+            ;;+        --disable-lavf-input)+            lavf_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 "ffms input: $ffms_input"+echo "lavf input: $lavf_input" echo "mp4 output: $mp4_output" echo "pthread:    $pthread" echo "debug:      $debug"diff --git a/input/ffms.c b/input/ffms.cnew file mode 100644index 0000000..93ded14--- /dev/null+++ b/input/ffms.c@@ -0,0 +1,104 @@+/*****************************************************************************+ * ffms.c: x264 ffmpegsource input module+ *****************************************************************************+ * Copyright (C) 2003-2009 x264 project+ *+ * Authors: Laurent Aimar <fenrir@via.ecp.fr>+ *          Loren Merritt <lorenm@u.washington.edu>+ *+ * 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>+#include <sys/stat.h>++typedef struct+{+    FFMS_VideoSource *video_source;+    int total_frames;+} ffms_hnd_t;++static int open_file( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param )+{+    ffms_hnd_t *h = malloc( sizeof(ffms_hnd_t) );+    if( !h )+        return -1;+    FFMS_Init( 0 );+    FFMS_ErrorInfo e;+    e.BufferSize = 0;+    //e.Buffer = malloc( e.BufferSize );+    FFMS_Index *index = NULL;+    if( p_param->psz_ffms_index != NULL )+    {+        struct stat index_s, input_s;+        if( stat( p_param->psz_ffms_index, &index_s ) == 0 )+        {+            stat( psz_filename, &input_s );+            if( input_s.st_mtime < index_s.st_mtime )+                index = FFMS_ReadIndex( p_param->psz_ffms_index, &e );+        }+    }+    if( index == NULL ) {+        index = FFMS_MakeIndex( psz_filename, 0, 0, NULL, NULL, 0, NULL, NULL, &e );+        if( p_param->psz_ffms_index != NULL )+            FFMS_WriteIndex( p_param->psz_ffms_index, index, &e );+    }+    x264_free( p_param->psz_ffms_index );+    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;+    const FFMS_Frame *frame = FFMS_GetFrame( h->video_source, 0, &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;+    *p_handle = h;+    return 0;+}++static int get_frame_total( hnd_t handle )+{+    return ((ffms_hnd_t *)handle)->total_frames;+}++static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame )+{+    ffms_hnd_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;+}++static int close_file( hnd_t handle )+{+    ffms_hnd_t *h = handle;+    FFMS_DestroyVideoSource( h->video_source );+    free( h );+    return -1;+}++cli_input_t ffms_input = { open_file, get_frame_total, read_frame, close_file };diff --git a/input/input.h b/input/input.hindex 87d5386..1134ae7 100644--- a/input/input.h+++ b/input/input.h@@ -36,5 +36,7 @@ extern cli_input_t yuv_input; extern cli_input_t y4m_input; extern cli_input_t avis_input; extern cli_input_t thread_input;+extern cli_input_t ffms_input;+extern cli_input_t lavf_input;  #endifdiff --git a/input/lavf.c b/input/lavf.cnew file mode 100644index 0000000..0396fe4--- /dev/null+++ b/input/lavf.c@@ -0,0 +1,94 @@+/*****************************************************************************+ * lavf.c: x264 libavformat input module+ *****************************************************************************+ * Copyright (C) 2003-2009 x264 project+ *+ * Authors: Laurent Aimar <fenrir@via.ecp.fr>+ *          Loren Merritt <lorenm@u.washington.edu>+ *+ * 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 <libavformat/avformat.h>++typedef struct+{+    AVFormatContext *context;+    int stream_id, next_frame;+} lavf_hnd_t;++static int open_file( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param )+{+    lavf_hnd_t *h = malloc( sizeof(lavf_hnd_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;+}++static int get_frame_total( hnd_t handle )+{+    return 0;+}++static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame )+{+    lavf_hnd_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;+}++static int close_file( hnd_t handle )+{+    free( handle );+    return -1;+}++cli_input_t lavf_input = { open_file, get_frame_total, read_frame, close_file };diff --git a/input/thread.c b/input/thread.cindex a9330dc..54f9631 100644--- a/input/thread.c+++ b/input/thread.c@@ -116,8 +116,8 @@ static int close_file( hnd_t handle )     thread_hnd_t *h = handle;     if( h->in_progress )         x264_pthread_join( h->tid, NULL );-    h->input.close_file( h->p_handle );-    x264_picture_clean( &h->pic );+    if( h->input.close_file( h->p_handle ) == 0 )+        x264_picture_clean( &h->pic );     free( h->next_args );     free( h );     return 0;diff --git a/x264.c b/x264.cindex c1728f1..4446f98 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; @@ -56,6 +60,7 @@ static void    SigIntHandler( int a ) typedef struct {     int b_progress;     int i_seek;+    int b_lavf;     hnd_t hin;     hnd_t hout;     FILE *qpfile;@@ -128,6 +133,7 @@ static void Help( x264_param_t *defaults, int longhelp )         "Infile can be raw YUV 4:2:0 (in which case resolution is required),\n"         "  or YUV4MPEG 4:2:0 (*.y4m),\n"         "  or AVI or Avisynth if compiled with AVIS support (%s).\n"+        "  or any libavformat supported file if compiled with libavformat support (%s).\n"         "Outfile type is selected by filename:\n"         " .264 -> Raw bytestream\n"         " .mkv -> Matroska\n"@@ -146,6 +152,11 @@ static void Help( x264_param_t *defaults, int longhelp )         "no", #endif #ifdef MP4_OUTPUT+        "yes",+#else+        "no",+#endif+#ifdef FFMS_INPUT         "yes" #else         "no"@@ -377,6 +388,8 @@ static void Help( x264_param_t *defaults, int longhelp )     H2( "      --dump-yuv <string>     Save reconstructed frames\n" );     H2( "      --sps-id <integer>      Set SPS and PPS id numbers [%d]\n", defaults->i_sps_id );     H2( "      --aud                   Use access unit delimiters\n" );+    H1( "      --lavf-input            Use libavformat to open the input file\n" );+    H2( "      --ffms-index <string>   Filename for FFmpegSource index file\n" );     H0( "\n" ); } @@ -394,6 +407,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[] =@@ -517,6 +531,8 @@ 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 },+    { "ffms-index",   required_argument, NULL, 0 },     {0, 0, 0, 0} }; @@ -830,6 +846,9 @@ static int  Parse( int argc, char **argv,             case OPT_SLOWFIRSTPASS:                 b_turbo = 0;                 break;+            case OPT_LAVF_INPUT:+                opt->b_lavf = 1;+                break;             case 'r':                 b_user_ref = 1;                 goto generic_option;@@ -936,7 +955,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 )         {@@ -960,7 +979,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;@@ -981,6 +1000,31 @@ generic_option:         }         if( b_y4m )             input = y4m_input;+        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:";+            }+            input = lavf_input;+#ifdef FFMS_INPUT+            if( !b_use_pipe )+                input = ffms_input;+#endif+#else+            fprintf( stderr, "x264 [error]: not compiled with libavformat input support\n" );+            return -1;+#endif+        }          if( input.open_file( psz_filename, &opt->hin, param ) )         {@@ -1209,7 +1253,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" );diff --git a/x264.h b/x264.hindex 0c10c8c..82a4104 100644--- a/x264.h+++ b/x264.h@@ -312,6 +312,8 @@ typedef struct x264_param_t     int i_slice_max_mbs;     /* Max number of MBs per slice; overrides i_slice_count. */     int i_slice_count;       /* Number of slices per frame: forces rectangular slices. */ +    char *psz_ffms_index;+     /* Optional callback for freeing this x264_param_t when it is done being used.      * Only used when the x264_param_t sits in memory for an indefinite period of time,      * i.e. when an x264_param_t is passed to x264_t in an x264_picture_t or in zones.