diff --git a/input/ffms.c b/input/ffms.c new file mode 100644 index 0000000..3fa5026 --- /dev/null +++ b/input/ffms.c @@ -0,0 +1,91 @@ +/***************************************************************************** + * ffms.c: x264 ffmpegsource input module + ***************************************************************************** + * Copyright (C) 2003-2009 x264 project + * + * Authors: Laurent Aimar + * Loren Merritt + * + * 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 + +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 = 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; + 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; + if( !h ) + return 0; + FFMS_DestroyVideoSource( h->video_source ); + free( h ); + return 0; +} + +cli_input_t ffms_input = { open_file, get_frame_total, read_frame, close_file }; diff --git a/input/lavf.c b/input/lavf.c new file mode 100644 index 0000000..ad6fb1c --- /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 + * Loren Merritt + * + * 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 + +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 0; +} + +cli_input_t lavf_input = { open_file, get_frame_total, read_frame, close_file };