#0 0x000000000045e199 in x264_plane_copy_mmxext () #1 0x00000000004253da in x264_frame_copy_picture (h=0xa30080, dst=0xff8500, src=0x7fff3ef94630) at common/frame.c:233 #2 0x0000000000413123 in x264_encoder_encode (h=0xa30080, pp_nal=, pi_nal=, pic_in=0x7fff3ef94630, pic_out=) at encoder/encoder.c:1678 #3 0x0000000000402c56 in Encode_frame (h=0x7f026803cb50, hout=0x9cd010, pic=0x18) at x264.c:1130 #4 0x00000000004043f9 in main (argc=, argv=) at x264.c:1236 diff --git a/muxers.c b/muxers.c index 7100877..86b20e9 100644 --- a/muxers.c +++ b/muxers.c @@ -41,6 +41,9 @@ #include #endif +#include +#include + static int64_t gcd( int64_t a, int64_t b ) { while( 1 ) @@ -426,6 +429,82 @@ int close_file_avis( hnd_t handle ) } #endif +/* libavcodec file input */ +typedef struct +{ + AVFormatContext *context; + const char *file; + int stream_id, next_frame; +} lavc_input_t; + +int open_file_lavc( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param ) +{ + lavc_input_t *h = malloc( sizeof(lavc_input_t) ); + av_register_all(); + h->context = avformat_alloc_context(); + h->context->flags |= AVSEEK_FLAG_ANY; + h->next_frame = 0; + h->file = psz_filename; + 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; + 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; + *p_handle = (hnd_t)h; + return 0; +} + +int get_frame_total_lavc( hnd_t handle ) +{ + return 0; +} + +int read_frame_lavc( x264_picture_t *p_pic, hnd_t handle, int i_frame ) +{ + int width, height, finished = 0; + AVPacket pkt; + lavc_input_t *h = handle; + av_init_packet( &pkt ); + while( i_frame < h->next_frame ) + { + av_read_frame( h->context, &pkt ); + if( pkt.stream_index == h->stream_id ) + h->next_frame ++; + av_free_packet( &pkt ); + } + av_init_packet( &pkt ); + AVFrame *frame = avcodec_alloc_frame(); + 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 ); + av_free_packet( &pkt ); + } + width = h->context->streams[h->stream_id]->codec->width; + height = h->context->streams[h->stream_id]->codec->height; + h->next_frame ++; + memcpy( p_pic->img.plane[0], frame->data[0], 3 * width * height / 2); + int i; + for( i = 0; i < 3; 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 ); + return 0; +} #ifdef HAVE_PTHREAD typedef struct diff --git a/muxers.h b/muxers.h index 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.c index f7786ce..cd49fc5 100644 --- a/x264.c +++ b/x264.c @@ -538,6 +538,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; @@ -959,8 +960,10 @@ generic_option: b_avis = 1; if( !strncasecmp( psz, ".y4m", 4 ) ) b_y4m = 1; + if( !strncasecmp( psz, ".mkv", 4 ) ) + b_lavc = 1; - if( !(b_avis || b_y4m) ) // raw yuv + if( !(b_avis || b_y4m || b_lavc) ) // raw yuv { if( optind > argc - 1 ) { @@ -984,7 +987,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 +1016,13 @@ generic_option: p_read_frame = read_frame_y4m; p_close_infile = close_file_y4m; } + if( b_lavc ) + { + 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; + } if( p_open_infile( psz_filename, &opt->hin, param ) ) { @@ -1171,6 +1181,10 @@ 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( i_frame_total == -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 )