2001-07-22 17:37:44 +03:00
/*
2011-04-23 16:19:17 +03:00
* ffmpeg main
2003-06-07 21:34:02 +03:00
* Copyright ( c ) 2000 - 2003 Fabrice Bellard
2001-07-22 17:37:44 +03:00
*
2006-10-07 18:30:46 +03:00
* This file is part of FFmpeg .
*
* FFmpeg is free software ; you can redistribute it and / or
2002-05-26 01:25:13 +03:00
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
2006-10-07 18:30:46 +03:00
* version 2.1 of the License , or ( at your option ) any later version .
2001-07-22 17:37:44 +03:00
*
2006-10-07 18:30:46 +03:00
* FFmpeg is distributed in the hope that it will be useful ,
2001-07-22 17:37:44 +03:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
2002-05-26 01:25:13 +03:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
2001-07-22 17:37:44 +03:00
*
2002-05-26 01:25:13 +03:00
* You should have received a copy of the GNU Lesser General Public
2006-10-07 18:30:46 +03:00
* License along with FFmpeg ; if not , write to the Free Software
2006-01-13 00:43:26 +02:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2001-07-22 17:37:44 +03:00
*/
2007-06-10 17:34:56 +03:00
2007-07-02 10:43:23 +03:00
# include "config.h"
# include <ctype.h>
# include <string.h>
# include <math.h>
# include <stdlib.h>
# include <errno.h>
2006-11-22 14:15:58 +02:00
# include <signal.h>
2004-05-12 19:51:39 +03:00
# include <limits.h>
2008-08-15 01:01:59 +03:00
# include <unistd.h>
2008-05-09 14:56:36 +03:00
# include "libavformat/avformat.h"
# include "libavdevice/avdevice.h"
# include "libswscale/swscale.h"
2011-02-03 15:58:59 +02:00
# include "libavutil/opt.h"
2008-07-31 16:11:07 +03:00
# include "libavcodec/audioconvert.h"
2011-02-07 15:37:08 +02:00
# include "libavutil/audioconvert.h"
# include "libavutil/parseutils.h"
# include "libavutil/samplefmt.h"
2010-07-01 21:49:44 +03:00
# include "libavutil/colorspace.h"
2008-05-09 14:56:36 +03:00
# include "libavutil/fifo.h"
2010-11-01 00:48:44 +02:00
# include "libavutil/intreadwrite.h"
2010-01-30 21:10:26 +02:00
# include "libavutil/pixdesc.h"
2008-05-09 14:56:36 +03:00
# include "libavutil/avstring.h"
2010-03-09 17:10:23 +02:00
# include "libavutil/libm.h"
2008-05-09 14:56:36 +03:00
# include "libavformat/os_support.h"
2001-08-16 01:29:44 +03:00
2011-04-09 04:09:49 +03:00
# include "libavformat/ffm.h" // not public API
2010-05-07 12:43:21 +03:00
# if CONFIG_AVFILTER
2011-05-01 15:47:05 +03:00
# include "libavfilter / avcodec.h"
2010-05-07 12:43:21 +03:00
# include "libavfilter / avfilter.h"
# include "libavfilter / avfiltergraph.h"
# include "libavfilter / vsrc_buffer.h"
# endif
2009-01-14 01:44:16 +02:00
# if HAVE_SYS_RESOURCE_H
2008-05-11 14:17:23 +03:00
# include <sys/types.h>
2010-02-23 00:21:58 +02:00
# include <sys/time.h>
2008-05-08 03:44:42 +03:00
# include <sys/resource.h>
2009-01-14 01:44:16 +02:00
# elif HAVE_GETPROCESSTIMES
2007-07-13 19:11:36 +03:00
# include <windows.h>
# endif
2010-02-23 00:21:58 +02:00
# if HAVE_GETPROCESSMEMORYINFO
# include <windows.h>
# include <psapi.h>
# endif
2007-07-13 19:11:36 +03:00
2009-01-14 01:44:16 +02:00
# if HAVE_SYS_SELECT_H
2008-09-26 05:13:38 +03:00
# include <sys/select.h>
# endif
2011-03-30 21:58:13 +03:00
# if HAVE_TERMIOS_H
# include <fcntl.h>
# include <sys/ioctl.h>
# include <sys/time.h>
# include <termios.h>
# elif HAVE_KBHIT
2007-07-11 17:07:55 +03:00
# include <conio.h>
2001-08-14 00:43:02 +03:00
# endif
2002-05-26 01:25:13 +03:00
# include <time.h>
2001-07-22 17:37:44 +03:00
2003-06-07 21:34:02 +03:00
# include "cmdutils.h"
2010-10-01 16:55:13 +03:00
# include "libavutil/avassert.h"
2004-09-22 20:50:53 +03:00
2011-04-23 16:19:17 +03:00
const char program_name [ ] = " ffmpeg " ;
2008-05-29 11:48:51 +03:00
const int program_birth_year = 2000 ;
2007-09-27 09:38:40 +03:00
2001-07-22 17:37:44 +03:00
/* select an input stream for an output stream */
typedef struct AVStreamMap {
int file_index ;
int stream_index ;
2005-05-26 11:59:05 +03:00
int sync_file_index ;
int sync_stream_index ;
2001-07-22 17:37:44 +03:00
} AVStreamMap ;
2010-09-24 18:40:53 +03:00
/**
* select an input file for an output file
*/
2004-07-21 04:35:32 +03:00
typedef struct AVMetaDataMap {
2010-11-02 08:01:28 +02:00
int file ; //< file index
char type ; //< type of metadata to copy -- (g)lobal, (s)tream, (c)hapter or (p)rogram
int index ; //< stream/chapter/program number
2004-07-21 04:35:32 +03:00
} AVMetaDataMap ;
2010-11-12 08:56:19 +02:00
typedef struct AVChapterMap {
int in_file ;
int out_file ;
} AVChapterMap ;
2008-05-01 18:12:00 +03:00
static const OptionDef options [ ] ;
2001-07-22 17:37:44 +03:00
2010-01-27 21:11:31 +02:00
# define MAX_FILES 100
2010-10-02 00:56:09 +03:00
# define MAX_STREAMS 1024 /* arbitrary sanity check value */
2001-07-22 17:37:44 +03:00
2009-12-05 17:14:01 +02:00
static const char * last_asked_format = NULL ;
2001-07-22 17:37:44 +03:00
static AVFormatContext * input_files [ MAX_FILES ] ;
2004-06-12 01:03:16 +03:00
static int64_t input_files_ts_offset [ MAX_FILES ] ;
2010-10-02 00:36:13 +03:00
static double * input_files_ts_scale [ MAX_FILES ] = { NULL } ;
2010-10-02 00:41:27 +03:00
static AVCodec * * input_codecs = NULL ;
2001-07-22 17:37:44 +03:00
static int nb_input_files = 0 ;
2010-10-02 00:41:27 +03:00
static int nb_input_codecs = 0 ;
2010-10-02 00:36:13 +03:00
static int nb_input_files_ts_scale [ MAX_FILES ] = { 0 } ;
2001-07-22 17:37:44 +03:00
static AVFormatContext * output_files [ MAX_FILES ] ;
2010-10-02 00:51:12 +03:00
static AVCodec * * output_codecs = NULL ;
2001-07-22 17:37:44 +03:00
static int nb_output_files = 0 ;
2010-10-02 00:51:12 +03:00
static int nb_output_codecs = 0 ;
2001-07-22 17:37:44 +03:00
2010-10-02 00:52:09 +03:00
static AVStreamMap * stream_maps = NULL ;
2001-07-22 17:37:44 +03:00
static int nb_stream_maps ;
2010-11-02 08:01:28 +02:00
/* first item specifies output metadata, second is input */
static AVMetaDataMap ( * meta_data_maps ) [ 2 ] = NULL ;
2004-07-21 04:35:32 +03:00
static int nb_meta_data_maps ;
2010-11-22 09:32:23 +02:00
static int metadata_global_autocopy = 1 ;
2010-11-02 08:12:54 +02:00
static int metadata_streams_autocopy = 1 ;
static int metadata_chapters_autocopy = 1 ;
2004-07-21 04:35:32 +03:00
2010-11-12 08:56:19 +02:00
static AVChapterMap * chapter_maps = NULL ;
static int nb_chapter_maps ;
2010-07-01 01:35:57 +03:00
/* indexed by output file stream index */
2010-10-02 00:34:59 +03:00
static int * streamid_map = NULL ;
static int nb_streamid_map = 0 ;
2010-07-01 01:35:57 +03:00
2005-01-04 15:27:35 +02:00
static int frame_width = 0 ;
static int frame_height = 0 ;
2003-04-29 04:51:38 +03:00
static float frame_aspect_ratio = 0 ;
2005-04-25 21:29:06 +03:00
static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE ;
2011-04-03 03:14:00 +03:00
static int frame_bits_per_raw_sample = 0 ;
2010-11-12 13:04:40 +02:00
static enum AVSampleFormat audio_sample_fmt = AV_SAMPLE_FMT_NONE ;
2005-06-03 17:31:45 +03:00
static int max_frames [ 4 ] = { INT_MAX , INT_MAX , INT_MAX , INT_MAX } ;
2008-07-14 00:59:58 +03:00
static AVRational frame_rate ;
2003-10-07 14:32:40 +03:00
static float video_qscale = 0 ;
2003-10-31 12:25:21 +02:00
static uint16_t * intra_matrix = NULL ;
static uint16_t * inter_matrix = NULL ;
2008-01-02 12:22:36 +02:00
static const char * video_rc_override_string = NULL ;
2001-07-22 17:37:44 +03:00
static int video_disable = 0 ;
2005-03-17 03:25:01 +02:00
static int video_discard = 0 ;
2007-08-08 17:34:51 +03:00
static char * video_codec_name = NULL ;
2010-06-03 21:40:31 +03:00
static unsigned int video_codec_tag = 0 ;
2009-12-16 14:08:01 +02:00
static char * video_language = NULL ;
2001-07-22 17:37:44 +03:00
static int same_quality = 0 ;
2001-08-11 21:58:18 +03:00
static int do_deinterlace = 0 ;
2003-12-30 18:07:57 +02:00
static int top_field_first = - 1 ;
2004-04-23 22:06:30 +03:00
static int me_threshold = 0 ;
2004-06-06 00:08:45 +03:00
static int intra_dc_precision = 8 ;
2006-07-14 00:13:49 +03:00
static int loop_input = 0 ;
2005-06-18 04:52:24 +03:00
static int loop_output = AVFMT_NOOUTPUTLOOP ;
2005-12-18 22:01:02 +02:00
static int qp_hist = 0 ;
2010-05-07 12:43:21 +03:00
# if CONFIG_AVFILTER
static char * vfilters = NULL ;
# endif
2001-07-22 17:37:44 +03:00
static int intra_only = 0 ;
static int audio_sample_rate = 44100 ;
2008-11-29 21:32:42 +02:00
static int64_t channel_layout = 0 ;
2005-08-21 23:27:00 +03:00
# define QSCALE_NONE -99999
static float audio_qscale = QSCALE_NONE ;
2001-07-22 17:37:44 +03:00
static int audio_disable = 0 ;
static int audio_channels = 1 ;
2007-08-08 17:34:51 +03:00
static char * audio_codec_name = NULL ;
2010-06-03 21:40:31 +03:00
static unsigned int audio_codec_tag = 0 ;
2005-06-03 17:31:45 +03:00
static char * audio_language = NULL ;
2007-07-25 22:47:44 +03:00
static int subtitle_disable = 0 ;
2007-08-08 17:34:51 +03:00
static char * subtitle_codec_name = NULL ;
2005-06-03 17:31:45 +03:00
static char * subtitle_language = NULL ;
2010-06-03 21:40:31 +03:00
static unsigned int subtitle_codec_tag = 0 ;
2001-07-22 17:37:44 +03:00
2011-04-14 14:32:36 +03:00
static int data_disable = 0 ;
static char * data_codec_name = NULL ;
static unsigned int data_codec_tag = 0 ;
2004-10-17 00:27:42 +03:00
static float mux_preload = 0.5 ;
static float mux_max_delay = 0.7 ;
2004-10-07 01:29:30 +03:00
2008-07-19 01:23:29 +03:00
static int64_t recording_time = INT64_MAX ;
2003-10-21 13:55:24 +03:00
static int64_t start_time = 0 ;
2010-06-23 01:54:39 +03:00
static int64_t recording_timestamp = 0 ;
2004-06-12 01:03:16 +03:00
static int64_t input_ts_offset = 0 ;
2001-07-22 17:37:44 +03:00
static int file_overwrite = 0 ;
2010-10-16 18:25:02 +03:00
static AVMetadata * metadata ;
2001-07-31 02:19:22 +03:00
static int do_benchmark = 0 ;
2001-09-23 20:14:51 +03:00
static int do_hex_dump = 0 ;
2003-11-10 20:54:17 +02:00
static int do_pkt_dump = 0 ;
2002-02-27 00:14:27 +02:00
static int do_psnr = 0 ;
2002-10-10 20:09:01 +03:00
static int do_pass = 0 ;
2011-04-21 01:46:20 +03:00
static const char * pass_logfilename_prefix ;
2002-10-11 12:19:34 +03:00
static int audio_stream_copy = 0 ;
static int video_stream_copy = 0 ;
2005-06-03 17:31:45 +03:00
static int subtitle_stream_copy = 0 ;
2011-04-14 14:32:36 +03:00
static int data_stream_copy = 0 ;
2008-07-13 19:19:23 +03:00
static int video_sync_method = - 1 ;
2004-06-30 17:47:29 +03:00
static int audio_sync_method = 0 ;
2007-08-07 03:03:50 +03:00
static float audio_drift_threshold = 0.1 ;
2004-06-12 06:41:36 +03:00
static int copy_ts = 0 ;
2011-05-11 01:57:42 +03:00
static int copy_tb = 0 ;
2008-12-14 17:02:27 +02:00
static int opt_shortest = 0 ;
2005-06-27 03:04:03 +03:00
static int video_global_header = 0 ;
2007-04-25 16:55:11 +03:00
static char * vstats_filename ;
2007-09-06 23:11:02 +03:00
static FILE * vstats_file ;
2007-10-27 21:46:25 +03:00
static int opt_programid = 0 ;
2008-12-22 10:22:22 +02:00
static int copy_initial_nonkeyframes = 0 ;
2002-10-10 20:09:01 +03:00
2003-03-07 14:37:49 +02:00
static int rate_emu = 0 ;
2003-01-23 20:44:26 +02:00
static int video_channel = 0 ;
2007-05-21 12:50:17 +03:00
static char * video_standard ;
2003-01-23 12:31:32 +02:00
2005-03-23 04:10:23 +02:00
static int audio_volume = 256 ;
2003-01-23 00:40:52 +02:00
2008-09-05 02:23:44 +03:00
static int exit_on_error = 0 ;
2003-08-29 23:51:10 +03:00
static int using_stdin = 0 ;
2003-09-03 15:13:43 +03:00
static int verbose = 1 ;
2011-04-22 19:49:44 +03:00
static int run_as_daemon = 0 ;
2004-02-13 19:54:10 +02:00
static int thread_count = 1 ;
2004-03-14 21:40:43 +02:00
static int q_pressed = 0 ;
2004-04-15 16:57:55 +03:00
static int64_t video_size = 0 ;
static int64_t audio_size = 0 ;
static int64_t extra_size = 0 ;
2004-06-12 01:03:16 +03:00
static int nb_frames_dup = 0 ;
static int nb_frames_drop = 0 ;
2004-06-18 06:03:32 +03:00
static int input_sync ;
2008-12-14 17:02:27 +02:00
static uint64_t limit_filesize = 0 ;
2008-09-28 20:34:03 +03:00
static int force_fps = 0 ;
2010-10-19 00:47:15 +03:00
static char * forced_key_frames = NULL ;
2003-08-29 23:51:10 +03:00
2007-08-07 03:26:37 +03:00
static float dts_delta_threshold = 10 ;
2004-11-11 20:09:28 +02:00
2007-06-26 18:52:54 +03:00
static int64_t timer_start ;
2005-09-11 14:10:25 +03:00
2009-04-13 06:55:26 +03:00
static uint8_t * audio_buf ;
static uint8_t * audio_out ;
2011-01-25 01:36:17 +02:00
static unsigned int allocated_audio_out_size , allocated_audio_buf_size ;
2009-04-13 06:55:26 +03:00
static short * samples ;
2006-07-06 18:04:46 +03:00
static AVBitStreamFilterContext * video_bitstream_filters = NULL ;
static AVBitStreamFilterContext * audio_bitstream_filters = NULL ;
2008-01-28 23:13:40 +02:00
static AVBitStreamFilterContext * subtitle_bitstream_filters = NULL ;
2004-11-11 20:09:28 +02:00
2008-12-26 21:25:24 +02:00
# define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
2001-07-22 17:37:44 +03:00
2005-05-26 11:59:05 +03:00
struct AVInputStream ;
2001-07-22 17:37:44 +03:00
typedef struct AVOutputStream {
int file_index ; /* file index */
int index ; /* stream index in the output file */
int source_index ; /* AVInputStream index */
AVStream * st ; /* stream in the output file */
2002-10-21 20:42:47 +03:00
int encoding_needed ; /* true if encoding needed for this stream */
int frame_number ;
/* input pts and corresponding output pts
for A / V sync */
2005-05-26 11:59:05 +03:00
//double sync_ipts; /* dts from the AVPacket of the demuxer in second units */
struct AVInputStream * sync_ist ; /* input stream to sync against */
2004-05-29 05:06:32 +03:00
int64_t sync_opts ; /* output frame counter, could be changed to some true timestamp */ //FIXME look at frame_number
2010-10-16 13:06:13 +03:00
AVBitStreamFilterContext * bitstream_filters ;
2001-07-22 17:37:44 +03:00
/* video only */
2006-04-10 12:04:15 +03:00
int video_resample ;
2011-05-06 12:30:27 +03:00
AVFrame resample_frame ; /* temporary frame for image resampling */
2006-08-02 14:50:38 +03:00
struct SwsContext * img_resample_ctx ; /* for image resampling */
int resample_height ;
2009-06-19 17:43:36 +03:00
int resample_width ;
2009-06-26 04:08:26 +03:00
int resample_pix_fmt ;
2002-12-05 11:00:18 +02:00
2011-04-17 02:47:24 +03:00
float frame_aspect_ratio ;
2011-04-01 18:30:45 +03:00
2010-10-19 00:47:15 +03:00
/* forced key frames */
int64_t * forced_kf_pts ;
int forced_kf_count ;
int forced_kf_index ;
2001-07-22 17:37:44 +03:00
/* audio only */
int audio_resample ;
ReSampleContext * resample ; /* for audio resampling */
2010-12-12 18:18:50 +02:00
int resample_sample_fmt ;
int resample_channels ;
int resample_sample_rate ;
2008-08-03 03:37:07 +03:00
int reformat_pair ;
AVAudioConvert * reformat_ctx ;
2009-03-08 16:16:55 +02:00
AVFifoBuffer * fifo ; /* for compression: one audio fifo per codec */
2002-10-10 20:09:01 +03:00
FILE * logfile ;
2011-02-15 00:02:10 +02:00
# if CONFIG_AVFILTER
AVFilterContext * output_video_filter ;
AVFilterContext * input_video_filter ;
AVFilterBufferRef * picref ;
char * avfilter ;
AVFilterGraph * graph ;
# endif
2011-05-10 05:01:29 +03:00
2011-05-09 17:36:57 +03:00
int sws_flags ;
2001-07-22 17:37:44 +03:00
} AVOutputStream ;
2010-10-16 13:06:10 +03:00
static AVOutputStream * * output_streams_for_file [ MAX_FILES ] = { NULL } ;
static int nb_output_streams_for_file [ MAX_FILES ] = { 0 } ;
2001-07-22 17:37:44 +03:00
typedef struct AVInputStream {
int file_index ;
int index ;
AVStream * st ;
int discard ; /* true if stream data should be discarded */
int decoding_needed ; /* true if the packets must be decoded in 'raw_fifo' */
2003-02-11 18:35:48 +02:00
int64_t sample_index ; /* current sample */
2003-03-07 14:37:49 +02:00
int64_t start ; /* time when read started */
2003-11-10 20:54:17 +02:00
int64_t next_pts ; /* synthetic pts for cases where pkt.pts
is not defined */
2003-07-31 01:37:43 +03:00
int64_t pts ; /* current pts */
2004-06-30 20:53:05 +03:00
int is_start ; /* is 1 at the start and after a discontinuity */
2010-01-27 15:27:18 +02:00
int showed_multi_packet_warning ;
2010-02-08 11:04:06 +02:00
int is_past_recording_time ;
2010-05-07 12:43:21 +03:00
# if CONFIG_AVFILTER
AVFrame * filter_frame ;
int has_filter_frame ;
# endif
2001-07-22 17:37:44 +03:00
} AVInputStream ;
typedef struct AVInputFile {
int eof_reached ; /* true if eof reached */
int ist_index ; /* index of first stream in ist_table */
int buffer_size ; /* current total buffer size */
2002-05-20 19:32:49 +03:00
int nb_streams ; /* nb streams we are aware of */
2001-07-22 17:37:44 +03:00
} AVInputFile ;
2011-03-30 21:58:13 +03:00
# if HAVE_TERMIOS_H
/* init terminal so that we can grab keys */
static struct termios oldtty ;
# endif
2010-05-07 12:43:21 +03:00
# if CONFIG_AVFILTER
2011-04-03 22:54:57 +03:00
static int configure_video_filters ( AVInputStream * ist , AVOutputStream * ost )
2010-05-07 12:43:21 +03:00
{
2010-05-11 20:23:06 +03:00
AVFilterContext * last_filter , * filter ;
2010-05-07 12:43:21 +03:00
/** filter graph containing all filters including input & output */
AVCodecContext * codec = ost - > st - > codec ;
AVCodecContext * icodec = ist - > st - > codec ;
2010-10-12 21:40:26 +03:00
FFSinkContext ffsink_ctx = { . pix_fmt = codec - > pix_fmt } ;
2011-01-31 21:48:35 +02:00
AVRational sample_aspect_ratio ;
2010-05-07 12:43:21 +03:00
char args [ 255 ] ;
2010-08-24 18:48:11 +03:00
int ret ;
2010-05-07 12:43:21 +03:00
2011-02-15 00:02:10 +02:00
ost - > graph = avfilter_graph_alloc ( ) ;
2010-05-07 12:43:21 +03:00
2011-01-31 21:48:35 +02:00
if ( ist - > st - > sample_aspect_ratio . num ) {
sample_aspect_ratio = ist - > st - > sample_aspect_ratio ;
} else
sample_aspect_ratio = ist - > st - > codec - > sample_aspect_ratio ;
snprintf ( args , 255 , " %d:%d:%d:%d:%d:%d:%d " , ist - > st - > codec - > width ,
ist - > st - > codec - > height , ist - > st - > codec - > pix_fmt , 1 , AV_TIME_BASE ,
sample_aspect_ratio . num , sample_aspect_ratio . den ) ;
2011-02-15 00:02:10 +02:00
ret = avfilter_graph_create_filter ( & ost - > input_video_filter , avfilter_get_by_name ( " buffer " ) ,
" src " , args , NULL , ost - > graph ) ;
2010-12-02 22:12:27 +02:00
if ( ret < 0 )
2010-08-24 18:48:11 +03:00
return ret ;
2011-02-15 00:02:10 +02:00
ret = avfilter_graph_create_filter ( & ost - > output_video_filter , & ffsink ,
" out " , NULL , & ffsink_ctx , ost - > graph ) ;
2010-12-02 22:12:27 +02:00
if ( ret < 0 )
2010-08-24 18:48:11 +03:00
return ret ;
2011-02-15 00:02:10 +02:00
last_filter = ost - > input_video_filter ;
2010-05-07 12:43:21 +03:00
2010-10-18 16:34:46 +03:00
if ( codec - > width ! = icodec - > width | | codec - > height ! = icodec - > height ) {
2010-05-11 20:16:52 +03:00
snprintf ( args , 255 , " %d:%d:flags=0x%X " ,
2010-05-07 15:16:23 +03:00
codec - > width ,
codec - > height ,
2011-05-09 17:36:57 +03:00
ost - > sws_flags ) ;
2010-12-02 22:12:27 +02:00
if ( ( ret = avfilter_graph_create_filter ( & filter , avfilter_get_by_name ( " scale " ) ,
2011-02-15 00:02:10 +02:00
NULL , args , NULL , ost - > graph ) ) < 0 )
2010-08-24 18:48:11 +03:00
return ret ;
if ( ( ret = avfilter_link ( last_filter , 0 , filter , 0 ) ) < 0 )
return ret ;
2010-05-11 20:23:06 +03:00
last_filter = filter ;
2010-05-07 12:43:21 +03:00
}
2011-05-09 17:36:57 +03:00
snprintf ( args , sizeof ( args ) , " flags=0x%X " , ost - > sws_flags ) ;
2011-02-15 00:02:10 +02:00
ost - > graph - > scale_sws_opts = av_strdup ( args ) ;
2010-07-03 06:11:04 +03:00
2011-02-15 00:02:10 +02:00
if ( ost - > avfilter ) {
2010-05-07 12:43:21 +03:00
AVFilterInOut * outputs = av_malloc ( sizeof ( AVFilterInOut ) ) ;
AVFilterInOut * inputs = av_malloc ( sizeof ( AVFilterInOut ) ) ;
outputs - > name = av_strdup ( " in " ) ;
2010-11-07 20:40:18 +02:00
outputs - > filter_ctx = last_filter ;
2010-05-07 12:43:21 +03:00
outputs - > pad_idx = 0 ;
outputs - > next = NULL ;
inputs - > name = av_strdup ( " out " ) ;
2011-02-15 00:02:10 +02:00
inputs - > filter_ctx = ost - > output_video_filter ;
2010-05-07 12:43:21 +03:00
inputs - > pad_idx = 0 ;
inputs - > next = NULL ;
2011-02-15 00:02:10 +02:00
if ( ( ret = avfilter_graph_parse ( ost - > graph , ost - > avfilter , inputs , outputs , NULL ) ) < 0 )
2010-08-24 18:48:11 +03:00
return ret ;
2011-02-15 00:02:10 +02:00
av_freep ( & ost - > avfilter ) ;
2010-05-07 12:43:21 +03:00
} else {
2011-02-15 00:02:10 +02:00
if ( ( ret = avfilter_link ( last_filter , 0 , ost - > output_video_filter , 0 ) ) < 0 )
2010-08-24 18:48:11 +03:00
return ret ;
2010-05-07 12:43:21 +03:00
}
2011-02-15 00:02:10 +02:00
if ( ( ret = avfilter_graph_config ( ost - > graph , NULL ) ) < 0 )
2010-08-24 18:48:11 +03:00
return ret ;
2010-05-07 12:43:21 +03:00
2011-02-15 00:02:10 +02:00
codec - > width = ost - > output_video_filter - > inputs [ 0 ] - > w ;
codec - > height = ost - > output_video_filter - > inputs [ 0 ] - > h ;
2011-01-31 21:48:35 +02:00
codec - > sample_aspect_ratio = ost - > st - > sample_aspect_ratio =
2011-04-17 02:47:24 +03:00
ost - > frame_aspect_ratio ? // overriden by the -aspect cli option
av_d2q ( ost - > frame_aspect_ratio * codec - > height / codec - > width , 255 ) :
2011-02-15 00:02:10 +02:00
ost - > output_video_filter - > inputs [ 0 ] - > sample_aspect_ratio ;
2010-05-07 12:43:21 +03:00
return 0 ;
}
# endif /* CONFIG_AVFILTER */
2001-07-22 17:37:44 +03:00
static void term_exit ( void )
{
2010-09-24 18:39:10 +03:00
av_log ( NULL , AV_LOG_QUIET , " " ) ;
2011-03-30 21:58:13 +03:00
# if HAVE_TERMIOS_H
2011-04-22 19:49:44 +03:00
if ( ! run_as_daemon )
2011-04-18 14:10:52 +03:00
tcsetattr ( 0 , TCSANOW , & oldtty ) ;
2011-03-30 21:58:13 +03:00
# endif
2010-03-20 03:02:45 +02:00
}
2001-07-22 17:37:44 +03:00
2009-07-27 16:01:44 +03:00
static volatile int received_sigterm = 0 ;
2003-04-10 21:21:06 +03:00
static void
sigterm_handler ( int sig )
{
received_sigterm = sig ;
2011-03-25 03:26:49 +02:00
q_pressed + + ;
2003-04-10 21:21:06 +03:00
term_exit ( ) ;
}
2001-07-22 17:37:44 +03:00
static void term_init ( void )
{
2011-03-30 21:58:13 +03:00
# if HAVE_TERMIOS_H
2011-04-22 19:49:44 +03:00
if ( ! run_as_daemon ) {
2011-03-30 21:58:13 +03:00
struct termios tty ;
tcgetattr ( 0 , & tty ) ;
oldtty = tty ;
atexit ( term_exit ) ;
tty . c_iflag & = ~ ( IGNBRK | BRKINT | PARMRK | ISTRIP
| INLCR | IGNCR | ICRNL | IXON ) ;
tty . c_oflag | = OPOST ;
tty . c_lflag & = ~ ( ECHO | ECHONL | ICANON | IEXTEN ) ;
tty . c_cflag & = ~ ( CSIZE | PARENB ) ;
tty . c_cflag | = CS8 ;
tty . c_cc [ VMIN ] = 1 ;
tty . c_cc [ VTIME ] = 0 ;
tcsetattr ( 0 , TCSANOW , & tty ) ;
signal ( SIGQUIT , sigterm_handler ) ; /* Quit (POSIX). */
2011-04-18 14:10:52 +03:00
}
2011-03-30 21:58:13 +03:00
# endif
2003-04-10 21:21:06 +03:00
signal ( SIGINT , sigterm_handler ) ; /* Interrupt (ANSI). */
signal ( SIGTERM , sigterm_handler ) ; /* Termination (ANSI). */
2010-01-20 08:42:39 +02:00
# ifdef SIGXCPU
signal ( SIGXCPU , sigterm_handler ) ;
# endif
2001-07-22 17:37:44 +03:00
}
/* read a key without blocking */
static int read_key ( void )
{
2011-03-30 21:58:13 +03:00
# if HAVE_TERMIOS_H
int n = 1 ;
unsigned char ch ;
struct timeval tv ;
fd_set rfds ;
2011-04-22 19:49:44 +03:00
if ( run_as_daemon )
2011-04-18 14:10:52 +03:00
return - 1 ;
2011-03-30 21:58:13 +03:00
FD_ZERO ( & rfds ) ;
FD_SET ( 0 , & rfds ) ;
tv . tv_sec = 0 ;
tv . tv_usec = 0 ;
n = select ( 1 , & rfds , NULL , NULL , & tv ) ;
if ( n > 0 ) {
n = read ( 0 , & ch , 1 ) ;
if ( n = = 1 )
return ch ;
return n ;
}
# elif HAVE_KBHIT
2007-07-11 17:07:55 +03:00
if ( kbhit ( ) )
return ( getch ( ) ) ;
2006-11-22 14:15:58 +02:00
# endif
2001-07-22 17:37:44 +03:00
return - 1 ;
}
2004-03-14 21:40:43 +02:00
static int decode_interrupt_cb ( void )
{
2011-03-07 18:25:38 +02:00
q_pressed + = read_key ( ) = = ' q ' ;
return q_pressed > 1 ;
2004-03-14 21:40:43 +02:00
}
2010-07-25 17:42:32 +03:00
static int ffmpeg_exit ( int ret )
2008-04-15 01:31:49 +03:00
{
int i ;
/* close files */
for ( i = 0 ; i < nb_output_files ; i + + ) {
AVFormatContext * s = output_files [ i ] ;
2008-04-21 04:22:25 +03:00
if ( ! ( s - > oformat - > flags & AVFMT_NOFILE ) & & s - > pb )
2011-02-21 23:45:20 +02:00
avio_close ( s - > pb ) ;
2011-02-04 12:04:18 +02:00
avformat_free_context ( s ) ;
2010-10-16 13:06:10 +03:00
av_free ( output_streams_for_file [ i ] ) ;
2008-04-15 01:31:49 +03:00
}
2010-10-02 00:36:13 +03:00
for ( i = 0 ; i < nb_input_files ; i + + ) {
2008-04-15 01:31:49 +03:00
av_close_input_file ( input_files [ i ] ) ;
2010-10-02 00:36:13 +03:00
av_free ( input_files_ts_scale [ i ] ) ;
}
2008-04-15 01:31:49 +03:00
av_free ( intra_matrix ) ;
av_free ( inter_matrix ) ;
if ( vstats_file )
fclose ( vstats_file ) ;
av_free ( vstats_filename ) ;
2010-10-02 00:34:59 +03:00
av_free ( streamid_map ) ;
2010-10-02 00:41:27 +03:00
av_free ( input_codecs ) ;
2010-10-02 00:51:12 +03:00
av_free ( output_codecs ) ;
2010-10-02 00:52:09 +03:00
av_free ( stream_maps ) ;
2010-10-28 23:28:22 +03:00
av_free ( meta_data_maps ) ;
2008-04-15 01:31:49 +03:00
av_free ( video_codec_name ) ;
av_free ( audio_codec_name ) ;
av_free ( subtitle_codec_name ) ;
2011-04-14 14:32:36 +03:00
av_free ( data_codec_name ) ;
2008-04-15 01:31:49 +03:00
av_free ( video_standard ) ;
2010-10-02 11:44:33 +03:00
uninit_opts ( ) ;
2009-04-13 06:55:26 +03:00
av_free ( audio_buf ) ;
av_free ( audio_out ) ;
2009-12-08 16:48:36 +02:00
allocated_audio_buf_size = allocated_audio_out_size = 0 ;
2009-04-13 06:55:26 +03:00
av_free ( samples ) ;
2009-04-13 06:47:12 +03:00
2010-05-07 12:43:21 +03:00
# if CONFIG_AVFILTER
avfilter_uninit ( ) ;
# endif
2008-04-15 01:31:49 +03:00
if ( received_sigterm ) {
fprintf ( stderr ,
" Received signal %d: terminating. \n " ,
( int ) received_sigterm ) ;
exit ( 255 ) ;
}
2008-04-15 01:35:32 +03:00
exit ( ret ) ; /* not all OS-es handle main() return value */
return ret ;
2010-10-02 00:29:37 +03:00
}
/* similar to ff_dynarray_add() and av_fast_realloc() */
static void * grow_array ( void * array , int elem_size , int * size , int new_size )
{
if ( new_size > = INT_MAX / elem_size ) {
fprintf ( stderr , " Array too big. \n " ) ;
ffmpeg_exit ( 1 ) ;
}
if ( * size < new_size ) {
uint8_t * tmp = av_realloc ( array , new_size * elem_size ) ;
if ( ! tmp ) {
fprintf ( stderr , " Could not alloc buffer. \n " ) ;
ffmpeg_exit ( 1 ) ;
}
memset ( tmp + * size * elem_size , 0 , ( new_size - * size ) * elem_size ) ;
* size = new_size ;
return tmp ;
}
return array ;
2008-04-15 01:31:49 +03:00
}
2010-03-30 22:37:07 +03:00
static void choose_sample_fmt ( AVStream * st , AVCodec * codec )
{
if ( codec & & codec - > sample_fmts ) {
2010-11-12 13:04:40 +02:00
const enum AVSampleFormat * p = codec - > sample_fmts ;
2010-03-30 22:37:07 +03:00
for ( ; * p ! = - 1 ; p + + ) {
if ( * p = = st - > codec - > sample_fmt )
break ;
}
2011-01-14 16:50:55 +02:00
if ( * p = = - 1 ) {
av_log ( NULL , AV_LOG_WARNING ,
" Incompatible sample format '%s' for codec '%s', auto-selecting format '%s' \n " ,
av_get_sample_fmt_name ( st - > codec - > sample_fmt ) ,
codec - > name ,
av_get_sample_fmt_name ( codec - > sample_fmts [ 0 ] ) ) ;
2010-03-30 22:37:07 +03:00
st - > codec - > sample_fmt = codec - > sample_fmts [ 0 ] ;
2011-01-14 16:50:55 +02:00
}
2010-03-30 22:37:07 +03:00
}
}
2010-04-22 12:40:51 +03:00
static void choose_sample_rate ( AVStream * st , AVCodec * codec )
{
if ( codec & & codec - > supported_samplerates ) {
const int * p = codec - > supported_samplerates ;
2010-07-04 02:24:37 +03:00
int best = 0 ;
2010-04-22 12:40:51 +03:00
int best_dist = INT_MAX ;
for ( ; * p ; p + + ) {
int dist = abs ( st - > codec - > sample_rate - * p ) ;
if ( dist < best_dist ) {
best_dist = dist ;
best = * p ;
}
}
2010-04-30 03:06:36 +03:00
if ( best_dist ) {
av_log ( st - > codec , AV_LOG_WARNING , " Requested sampling rate unsupported using closest supported (%d) \n " , best ) ;
}
2010-04-22 12:40:51 +03:00
st - > codec - > sample_rate = best ;
}
}
2010-03-30 22:37:07 +03:00
static void choose_pixel_fmt ( AVStream * st , AVCodec * codec )
{
if ( codec & & codec - > pix_fmts ) {
const enum PixelFormat * p = codec - > pix_fmts ;
2011-01-05 06:52:32 +02:00
if ( st - > codec - > strict_std_compliance < = FF_COMPLIANCE_UNOFFICIAL ) {
if ( st - > codec - > codec_id = = CODEC_ID_MJPEG ) {
p = ( const enum PixelFormat [ ] ) { PIX_FMT_YUVJ420P , PIX_FMT_YUVJ422P , PIX_FMT_YUV420P , PIX_FMT_YUV422P , PIX_FMT_NONE } ;
} else if ( st - > codec - > codec_id = = CODEC_ID_LJPEG ) {
p = ( const enum PixelFormat [ ] ) { PIX_FMT_YUVJ420P , PIX_FMT_YUVJ422P , PIX_FMT_YUVJ444P , PIX_FMT_YUV420P , PIX_FMT_YUV422P , PIX_FMT_YUV444P , PIX_FMT_BGRA , PIX_FMT_NONE } ;
}
}
2010-03-30 22:37:07 +03:00
for ( ; * p ! = - 1 ; p + + ) {
if ( * p = = st - > codec - > pix_fmt )
break ;
}
2011-03-26 16:26:45 +02:00
if ( * p = = - 1 ) {
2011-04-06 00:22:08 +03:00
if ( st - > codec - > pix_fmt ! = PIX_FMT_NONE )
2011-03-26 16:26:45 +02:00
av_log ( NULL , AV_LOG_WARNING ,
" Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s' \n " ,
av_pix_fmt_descriptors [ st - > codec - > pix_fmt ] . name ,
codec - > name ,
av_pix_fmt_descriptors [ codec - > pix_fmts [ 0 ] ] . name ) ;
2010-03-30 22:37:07 +03:00
st - > codec - > pix_fmt = codec - > pix_fmts [ 0 ] ;
2011-03-26 16:26:45 +02:00
}
2010-03-30 22:37:07 +03:00
}
}
2010-10-29 17:48:38 +03:00
static AVOutputStream * new_output_stream ( AVFormatContext * oc , int file_idx )
{
int idx = oc - > nb_streams - 1 ;
AVOutputStream * ost ;
output_streams_for_file [ file_idx ] =
grow_array ( output_streams_for_file [ file_idx ] ,
sizeof ( * output_streams_for_file [ file_idx ] ) ,
& nb_output_streams_for_file [ file_idx ] ,
oc - > nb_streams ) ;
ost = output_streams_for_file [ file_idx ] [ idx ] =
av_mallocz ( sizeof ( AVOutputStream ) ) ;
if ( ! ost ) {
fprintf ( stderr , " Could not alloc output stream \n " ) ;
ffmpeg_exit ( 1 ) ;
}
ost - > file_index = file_idx ;
ost - > index = idx ;
2011-05-09 17:36:57 +03:00
ost - > sws_flags = av_get_int ( sws_opts , " sws_flags " , NULL ) ;
2010-10-29 17:48:38 +03:00
return ost ;
}
2003-02-10 11:44:47 +02:00
static int read_ffserver_streams ( AVFormatContext * s , const char * filename )
2001-07-22 17:37:44 +03:00
{
2002-05-20 19:32:49 +03:00
int i , err ;
2001-07-22 17:37:44 +03:00
AVFormatContext * ic ;
2008-06-09 03:24:29 +03:00
int nopts = 0 ;
2001-07-22 17:37:44 +03:00
2002-05-20 19:32:49 +03:00
err = av_open_input_file ( & ic , filename , NULL , FFM_PACKET_SIZE , NULL ) ;
if ( err < 0 )
return err ;
2001-07-22 17:37:44 +03:00
/* copy stream format */
2010-10-29 17:54:18 +03:00
s - > nb_streams = 0 ;
2011-05-21 05:39:20 +03:00
s - > streams = av_mallocz ( sizeof ( * s - > streams ) * ic - > nb_streams ) ;
2001-07-22 17:37:44 +03:00
for ( i = 0 ; i < ic - > nb_streams ; i + + ) {
AVStream * st ;
2010-04-01 00:02:34 +03:00
AVCodec * codec ;
2002-12-04 12:04:03 +02:00
2010-10-29 17:54:18 +03:00
s - > nb_streams + + ;
2005-10-13 02:38:39 +03:00
// FIXME: a more elegant solution is needed
2003-07-03 20:02:03 +03:00
st = av_mallocz ( sizeof ( AVStream ) ) ;
2001-07-22 17:37:44 +03:00
memcpy ( st , ic - > streams [ i ] , sizeof ( AVStream ) ) ;
2005-10-13 02:38:39 +03:00
st - > codec = avcodec_alloc_context ( ) ;
2009-09-12 20:22:56 +03:00
if ( ! st - > codec ) {
print_error ( filename , AVERROR ( ENOMEM ) ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-09-12 20:22:56 +03:00
}
2010-04-01 00:02:34 +03:00
avcodec_copy_context ( st - > codec , ic - > streams [ i ] - > codec ) ;
2001-07-22 17:37:44 +03:00
s - > streams [ i ] = st ;
2008-06-12 04:43:52 +03:00
2010-04-01 00:02:34 +03:00
codec = avcodec_find_encoder ( st - > codec - > codec_id ) ;
if ( st - > codec - > codec_type = = AVMEDIA_TYPE_AUDIO ) {
if ( audio_stream_copy ) {
st - > stream_copy = 1 ;
} else
choose_sample_fmt ( st , codec ) ;
} else if ( st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO ) {
if ( video_stream_copy ) {
st - > stream_copy = 1 ;
} else
choose_pixel_fmt ( st , codec ) ;
}
2008-06-12 04:43:52 +03:00
2008-06-09 03:24:29 +03:00
if ( st - > codec - > flags & CODEC_FLAG_BITEXACT )
nopts = 1 ;
2010-10-29 17:54:18 +03:00
new_output_stream ( s , nb_output_files ) ;
2001-07-22 17:37:44 +03:00
}
2008-06-09 03:24:29 +03:00
if ( ! nopts )
s - > timestamp = av_gettime ( ) ;
2001-07-22 17:37:44 +03:00
av_close_input_file ( ic ) ;
return 0 ;
}
2005-05-26 11:59:05 +03:00
static double
get_sync_ipts ( const AVOutputStream * ost )
{
const AVInputStream * ist = ost - > sync_ist ;
2007-08-03 22:21:50 +03:00
return ( double ) ( ist - > pts - start_time ) / AV_TIME_BASE ;
2005-05-26 11:59:05 +03:00
}
2006-07-06 18:04:46 +03:00
static void write_frame ( AVFormatContext * s , AVPacket * pkt , AVCodecContext * avctx , AVBitStreamFilterContext * bsfc ) {
2007-11-01 03:59:22 +02:00
int ret ;
2006-07-06 18:04:46 +03:00
while ( bsfc ) {
AVPacket new_pkt = * pkt ;
int a = av_bitstream_filter_filter ( bsfc , avctx , NULL ,
& new_pkt . data , & new_pkt . size ,
pkt - > data , pkt - > size ,
2010-03-31 15:29:58 +03:00
pkt - > flags & AV_PKT_FLAG_KEY ) ;
2008-01-21 15:36:20 +02:00
if ( a > 0 ) {
2006-07-06 18:04:46 +03:00
av_free_packet ( pkt ) ;
new_pkt . destruct = av_destruct_packet ;
2008-01-21 15:36:20 +02:00
} else if ( a < 0 ) {
2008-01-22 10:52:57 +02:00
fprintf ( stderr , " %s failed for stream %d, codec %s " ,
bsfc - > filter - > name , pkt - > stream_index ,
avctx - > codec ? avctx - > codec - > name : " copy " ) ;
2008-01-21 15:36:20 +02:00
print_error ( " " , a ) ;
2008-09-05 02:23:44 +03:00
if ( exit_on_error )
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2006-07-06 18:04:46 +03:00
}
* pkt = new_pkt ;
bsfc = bsfc - > next ;
}
2007-11-01 03:59:22 +02:00
ret = av_interleaved_write_frame ( s , pkt ) ;
if ( ret < 0 ) {
print_error ( " av_interleaved_write_frame() " , ret ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2007-11-01 03:59:22 +02:00
}
2006-07-06 18:04:46 +03:00
}
2003-01-11 07:05:47 +02:00
# define MAX_AUDIO_PACKET_SIZE (128 * 1024)
2001-07-22 17:37:44 +03:00
2005-12-17 20:14:38 +02:00
static void do_audio_out ( AVFormatContext * s ,
AVOutputStream * ost ,
2001-07-22 17:37:44 +03:00
AVInputStream * ist ,
unsigned char * buf , int size )
{
2003-02-11 18:35:48 +02:00
uint8_t * buftmp ;
2009-12-08 16:28:28 +02:00
int64_t audio_out_size , audio_buf_size ;
2010-01-23 03:25:19 +02:00
int64_t allocated_for_size = size ;
2003-03-20 03:32:17 +02:00
2010-12-12 18:18:50 +02:00
int size_out , frame_bytes , ret , resample_changed ;
2005-07-18 01:24:36 +03:00
AVCodecContext * enc = ost - > st - > codec ;
2007-12-15 09:04:17 +02:00
AVCodecContext * dec = ist - > st - > codec ;
2010-11-03 22:19:34 +02:00
int osize = av_get_bits_per_sample_fmt ( enc - > sample_fmt ) / 8 ;
int isize = av_get_bits_per_sample_fmt ( dec - > sample_fmt ) / 8 ;
2009-12-08 16:28:28 +02:00
const int coded_bps = av_get_bits_per_sample ( enc - > codec - > id ) ;
2010-01-23 03:25:19 +02:00
need_realloc :
audio_buf_size = ( allocated_for_size + isize * dec - > channels - 1 ) / ( isize * dec - > channels ) ;
2009-12-08 16:28:28 +02:00
audio_buf_size = ( audio_buf_size * enc - > sample_rate + dec - > sample_rate ) / dec - > sample_rate ;
2009-12-14 21:28:33 +02:00
audio_buf_size = audio_buf_size * 2 + 10000 ; //safety factors for the deprecated resampling API
2010-06-10 22:40:56 +03:00
audio_buf_size = FFMAX ( audio_buf_size , enc - > frame_size ) ;
2009-12-08 16:28:28 +02:00
audio_buf_size * = osize * enc - > channels ;
audio_out_size = FFMAX ( audio_buf_size , enc - > frame_size * osize * enc - > channels ) ;
if ( coded_bps > 8 * osize )
audio_out_size = audio_out_size * coded_bps / ( 8 * osize ) ;
audio_out_size + = FF_MIN_BUFFER_SIZE ;
if ( audio_out_size > INT_MAX | | audio_buf_size > INT_MAX ) {
fprintf ( stderr , " Buffer sizes too large \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-12-08 16:28:28 +02:00
}
2001-07-22 17:37:44 +03:00
2009-12-08 16:48:36 +02:00
av_fast_malloc ( & audio_buf , & allocated_audio_buf_size , audio_buf_size ) ;
av_fast_malloc ( & audio_out , & allocated_audio_out_size , audio_out_size ) ;
2009-12-08 16:50:46 +02:00
if ( ! audio_buf | | ! audio_out ) {
fprintf ( stderr , " Out of memory in do_audio_out \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-12-08 16:50:46 +02:00
}
2003-03-20 03:32:17 +02:00
2007-12-15 09:04:17 +02:00
if ( enc - > channels ! = dec - > channels )
ost - > audio_resample = 1 ;
2010-12-12 18:18:50 +02:00
resample_changed = ost - > resample_sample_fmt ! = dec - > sample_fmt | |
ost - > resample_channels ! = dec - > channels | |
ost - > resample_sample_rate ! = dec - > sample_rate ;
if ( ( ost - > audio_resample & & ! ost - > resample ) | | resample_changed ) {
if ( resample_changed ) {
av_log ( NULL , AV_LOG_INFO , " Input stream #%d.%d frame changed from rate:%d fmt:%s ch:%d to rate:%d fmt:%s ch:%d \n " ,
ist - > file_index , ist - > index ,
ost - > resample_sample_rate , av_get_sample_fmt_name ( ost - > resample_sample_fmt ) , ost - > resample_channels ,
dec - > sample_rate , av_get_sample_fmt_name ( dec - > sample_fmt ) , dec - > channels ) ;
ost - > resample_sample_fmt = dec - > sample_fmt ;
ost - > resample_channels = dec - > channels ;
ost - > resample_sample_rate = dec - > sample_rate ;
if ( ost - > resample )
audio_resample_close ( ost - > resample ) ;
}
2011-01-23 03:06:59 +02:00
/* if audio_sync_method is >1 the resampler is needed for audio drift compensation */
if ( audio_sync_method < = 1 & &
ost - > resample_sample_fmt = = enc - > sample_fmt & &
2010-12-12 18:18:50 +02:00
ost - > resample_channels = = enc - > channels & &
ost - > resample_sample_rate = = enc - > sample_rate ) {
ost - > resample = NULL ;
ost - > audio_resample = 0 ;
} else {
2010-12-12 18:19:40 +02:00
if ( dec - > sample_fmt ! = AV_SAMPLE_FMT_S16 )
fprintf ( stderr , " Warning, using s16 intermediate sample format for resampling \n " ) ;
ost - > resample = av_audio_resample_init ( enc - > channels , dec - > channels ,
enc - > sample_rate , dec - > sample_rate ,
enc - > sample_fmt , dec - > sample_fmt ,
16 , 10 , 0 , 0.8 ) ;
if ( ! ost - > resample ) {
fprintf ( stderr , " Can not resample %d channels @ %d Hz to %d channels @ %d Hz \n " ,
dec - > channels , dec - > sample_rate ,
enc - > channels , enc - > sample_rate ) ;
ffmpeg_exit ( 1 ) ;
}
2010-12-12 18:18:50 +02:00
}
2007-12-15 09:04:17 +02:00
}
2010-11-12 13:04:40 +02:00
# define MAKE_SFMT_PAIR(a,b) ((a)+AV_SAMPLE_FMT_NB*(b))
2009-02-12 00:57:10 +02:00
if ( ! ost - > audio_resample & & dec - > sample_fmt ! = enc - > sample_fmt & &
2008-08-03 03:37:07 +03:00
MAKE_SFMT_PAIR ( enc - > sample_fmt , dec - > sample_fmt ) ! = ost - > reformat_pair ) {
if ( ost - > reformat_ctx )
av_audio_convert_free ( ost - > reformat_ctx ) ;
ost - > reformat_ctx = av_audio_convert_alloc ( enc - > sample_fmt , 1 ,
dec - > sample_fmt , 1 , NULL , 0 ) ;
if ( ! ost - > reformat_ctx ) {
fprintf ( stderr , " Cannot convert %s sample format to %s sample format \n " ,
2010-11-03 22:19:34 +02:00
av_get_sample_fmt_name ( dec - > sample_fmt ) ,
av_get_sample_fmt_name ( enc - > sample_fmt ) ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2008-08-03 03:37:07 +03:00
}
ost - > reformat_pair = MAKE_SFMT_PAIR ( enc - > sample_fmt , dec - > sample_fmt ) ;
}
2004-06-30 17:47:29 +03:00
if ( audio_sync_method ) {
2005-12-17 20:14:38 +02:00
double delta = get_sync_ipts ( ost ) * enc - > sample_rate - ost - > sync_opts
2010-09-18 23:16:56 +03:00
- av_fifo_size ( ost - > fifo ) / ( enc - > channels * 2 ) ;
double idelta = delta * dec - > sample_rate / enc - > sample_rate ;
2010-09-18 23:19:18 +03:00
int byte_delta = ( ( int ) idelta ) * 2 * dec - > channels ;
2004-06-30 20:53:05 +03:00
2004-06-30 17:47:29 +03:00
//FIXME resample delay
if ( fabs ( delta ) > 50 ) {
2007-08-07 03:03:50 +03:00
if ( ist - > is_start | | fabs ( delta ) > audio_drift_threshold * enc - > sample_rate ) {
2004-06-30 20:53:05 +03:00
if ( byte_delta < 0 ) {
2004-07-02 16:25:04 +03:00
byte_delta = FFMAX ( byte_delta , - size ) ;
2004-06-30 20:53:05 +03:00
size + = byte_delta ;
buf - = byte_delta ;
if ( verbose > 2 )
fprintf ( stderr , " discarding %d audio samples \n " , ( int ) - delta ) ;
if ( ! size )
return ;
ist - > is_start = 0 ;
} else {
static uint8_t * input_tmp = NULL ;
input_tmp = av_realloc ( input_tmp , byte_delta + size ) ;
2010-01-23 03:25:19 +02:00
if ( byte_delta > allocated_for_size - size ) {
allocated_for_size = byte_delta + ( int64_t ) size ;
goto need_realloc ;
}
ist - > is_start = 0 ;
2004-06-30 20:53:05 +03:00
memset ( input_tmp , 0 , byte_delta ) ;
memcpy ( input_tmp + byte_delta , buf , size ) ;
buf = input_tmp ;
size + = byte_delta ;
if ( verbose > 2 )
fprintf ( stderr , " adding %d audio samples of silence \n " , ( int ) delta ) ;
}
} else if ( audio_sync_method > 1 ) {
2007-02-25 12:27:12 +02:00
int comp = av_clip ( delta , - audio_sync_method , audio_sync_method ) ;
2010-10-01 00:57:31 +03:00
av_assert0 ( ost - > audio_resample ) ;
2004-06-30 20:53:05 +03:00
if ( verbose > 2 )
fprintf ( stderr , " compensating audio timestamp drift:%f compensation:%d in:%d \n " , delta , comp , enc - > sample_rate ) ;
2009-03-08 16:16:55 +02:00
// fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2));
2004-06-30 20:53:05 +03:00
av_resample_compensate ( * ( struct AVResampleContext * * ) ost - > resample , comp , enc - > sample_rate ) ;
}
2005-12-17 20:14:38 +02:00
}
2004-06-30 17:47:29 +03:00
} else
2005-05-26 11:59:05 +03:00
ost - > sync_opts = lrintf ( get_sync_ipts ( ost ) * enc - > sample_rate )
2010-09-18 23:16:56 +03:00
- av_fifo_size ( ost - > fifo ) / ( enc - > channels * 2 ) ; //FIXME wrong
2001-07-22 17:37:44 +03:00
if ( ost - > audio_resample ) {
buftmp = audio_buf ;
2005-12-17 20:14:38 +02:00
size_out = audio_resample ( ost - > resample ,
2001-07-22 17:37:44 +03:00
( short * ) buftmp , ( short * ) buf ,
2010-09-18 23:16:56 +03:00
size / ( dec - > channels * isize ) ) ;
2008-09-04 13:18:04 +03:00
size_out = size_out * enc - > channels * osize ;
2001-07-22 17:37:44 +03:00
} else {
buftmp = buf ;
size_out = size ;
}
2009-02-12 00:57:10 +02:00
if ( ! ost - > audio_resample & & dec - > sample_fmt ! = enc - > sample_fmt ) {
2008-08-03 03:37:07 +03:00
const void * ibuf [ 6 ] = { buftmp } ;
2009-12-07 18:26:37 +02:00
void * obuf [ 6 ] = { audio_buf } ;
2008-09-04 13:18:04 +03:00
int istride [ 6 ] = { isize } ;
int ostride [ 6 ] = { osize } ;
2008-08-03 03:37:07 +03:00
int len = size_out / istride [ 0 ] ;
if ( av_audio_convert ( ost - > reformat_ctx , obuf , ostride , ibuf , istride , len ) < 0 ) {
printf ( " av_audio_convert() failed \n " ) ;
2008-09-05 02:23:44 +03:00
if ( exit_on_error )
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2008-08-03 03:37:07 +03:00
return ;
}
2009-12-07 18:26:37 +02:00
buftmp = audio_buf ;
2008-09-04 13:18:04 +03:00
size_out = len * osize ;
2008-08-03 03:37:07 +03:00
}
2001-07-22 17:37:44 +03:00
/* now encode as many frames as possible */
2001-09-23 20:14:51 +03:00
if ( enc - > frame_size > 1 ) {
2001-07-22 17:37:44 +03:00
/* output resampled raw samples */
2009-03-08 16:16:55 +02:00
if ( av_fifo_realloc2 ( ost - > fifo , av_fifo_size ( ost - > fifo ) + size_out ) < 0 ) {
2008-08-19 21:49:57 +03:00
fprintf ( stderr , " av_fifo_realloc2() failed \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2008-08-19 21:49:57 +03:00
}
2009-03-08 16:16:55 +02:00
av_fifo_generic_write ( ost - > fifo , buftmp , size_out , NULL ) ;
2001-07-22 17:37:44 +03:00
2008-09-04 13:18:04 +03:00
frame_bytes = enc - > frame_size * osize * enc - > channels ;
2005-12-17 20:14:38 +02:00
2009-03-08 16:16:55 +02:00
while ( av_fifo_size ( ost - > fifo ) > = frame_bytes ) {
2004-05-29 05:06:32 +03:00
AVPacket pkt ;
av_init_packet ( & pkt ) ;
2009-03-09 19:47:47 +02:00
av_fifo_generic_read ( ost - > fifo , audio_buf , frame_bytes , NULL ) ;
2008-05-26 01:20:39 +03:00
2008-02-17 23:31:39 +02:00
//FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
2005-12-17 20:14:38 +02:00
ret = avcodec_encode_audio ( enc , audio_out , audio_out_size ,
2001-09-23 20:14:51 +03:00
( short * ) audio_buf ) ;
2009-01-11 18:15:34 +02:00
if ( ret < 0 ) {
fprintf ( stderr , " Audio encoding failed \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-01-11 18:15:34 +02:00
}
2004-04-15 16:57:55 +03:00
audio_size + = ret ;
2004-05-29 05:06:32 +03:00
pkt . stream_index = ost - > index ;
pkt . data = audio_out ;
pkt . size = ret ;
2005-09-11 11:24:36 +03:00
if ( enc - > coded_frame & & enc - > coded_frame - > pts ! = AV_NOPTS_VALUE )
2005-05-01 00:43:59 +03:00
pkt . pts = av_rescale_q ( enc - > coded_frame - > pts , enc - > time_base , ost - > st - > time_base ) ;
2010-03-31 15:29:58 +03:00
pkt . flags | = AV_PKT_FLAG_KEY ;
2010-10-16 13:06:13 +03:00
write_frame ( s , & pkt , enc , ost - > bitstream_filters ) ;
2005-12-17 20:14:38 +02:00
2004-06-30 17:47:29 +03:00
ost - > sync_opts + = enc - > frame_size ;
2001-07-22 17:37:44 +03:00
}
} else {
2004-05-29 05:06:32 +03:00
AVPacket pkt ;
av_init_packet ( & pkt ) ;
2004-06-30 17:47:29 +03:00
2008-09-04 13:18:04 +03:00
ost - > sync_opts + = size_out / ( osize * enc - > channels ) ;
2004-06-30 17:47:29 +03:00
2001-09-23 20:14:51 +03:00
/* output a pcm frame */
2008-09-04 13:18:04 +03:00
/* determine the size of the coded buffer */
size_out / = osize ;
if ( coded_bps )
2009-12-08 16:10:49 +02:00
size_out = size_out * coded_bps / 8 ;
2008-09-04 13:18:04 +03:00
2009-12-08 16:18:15 +02:00
if ( size_out > audio_out_size ) {
fprintf ( stderr , " Internal error, buffer size too small \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-12-08 16:18:15 +02:00
}
2008-02-17 23:31:39 +02:00
//FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
2005-12-17 20:14:38 +02:00
ret = avcodec_encode_audio ( enc , audio_out , size_out ,
2005-12-22 03:10:11 +02:00
( short * ) buftmp ) ;
2009-01-11 18:15:34 +02:00
if ( ret < 0 ) {
fprintf ( stderr , " Audio encoding failed \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-01-11 18:15:34 +02:00
}
2004-04-15 16:57:55 +03:00
audio_size + = ret ;
2004-05-29 05:06:32 +03:00
pkt . stream_index = ost - > index ;
pkt . data = audio_out ;
pkt . size = ret ;
2005-09-11 11:24:36 +03:00
if ( enc - > coded_frame & & enc - > coded_frame - > pts ! = AV_NOPTS_VALUE )
2005-05-01 00:43:59 +03:00
pkt . pts = av_rescale_q ( enc - > coded_frame - > pts , enc - > time_base , ost - > st - > time_base ) ;
2010-03-31 15:29:58 +03:00
pkt . flags | = AV_PKT_FLAG_KEY ;
2010-10-16 13:06:13 +03:00
write_frame ( s , & pkt , enc , ost - > bitstream_filters ) ;
2001-07-22 17:37:44 +03:00
}
}
2002-11-20 05:06:12 +02:00
static void pre_process_video_frame ( AVInputStream * ist , AVPicture * picture , void * * bufp )
{
AVCodecContext * dec ;
AVPicture * picture2 ;
AVPicture picture_tmp ;
2003-02-11 18:35:48 +02:00
uint8_t * buf = 0 ;
2002-11-20 05:06:12 +02:00
2005-07-18 01:24:36 +03:00
dec = ist - > st - > codec ;
2002-11-20 05:06:12 +02:00
/* deinterlace : must be done before any resize */
2009-03-03 16:09:10 +02:00
if ( do_deinterlace ) {
2002-11-20 05:06:12 +02:00
int size ;
/* create temporary picture */
size = avpicture_get_size ( dec - > pix_fmt , dec - > width , dec - > height ) ;
buf = av_malloc ( size ) ;
if ( ! buf )
return ;
2005-12-17 20:14:38 +02:00
2002-11-20 05:06:12 +02:00
picture2 = & picture_tmp ;
avpicture_fill ( picture2 , buf , dec - > pix_fmt , dec - > width , dec - > height ) ;
2009-05-31 23:19:16 +03:00
if ( avpicture_deinterlace ( picture2 , picture ,
dec - > pix_fmt , dec - > width , dec - > height ) < 0 ) {
/* if error, do not deinterlace */
fprintf ( stderr , " Deinterlacing failed \n " ) ;
av_free ( buf ) ;
buf = NULL ;
picture2 = picture ;
}
2002-11-20 05:06:12 +02:00
} else {
picture2 = picture ;
}
if ( picture ! = picture2 )
* picture = * picture2 ;
* bufp = buf ;
}
2002-10-21 20:42:47 +03:00
/* we begin to correct av delay at this threshold */
# define AV_DELAY_MAX 0.100
2001-07-22 17:37:44 +03:00
2005-12-17 20:14:38 +02:00
static void do_subtitle_out ( AVFormatContext * s ,
AVOutputStream * ost ,
2005-06-03 17:31:45 +03:00
AVInputStream * ist ,
AVSubtitle * sub ,
int64_t pts )
{
static uint8_t * subtitle_out = NULL ;
2009-08-26 13:22:27 +03:00
int subtitle_out_max_size = 1024 * 1024 ;
2005-06-03 17:31:45 +03:00
int subtitle_out_size , nb , i ;
AVCodecContext * enc ;
AVPacket pkt ;
if ( pts = = AV_NOPTS_VALUE ) {
fprintf ( stderr , " Subtitle packets must have a pts \n " ) ;
2008-09-05 02:23:44 +03:00
if ( exit_on_error )
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2005-06-03 17:31:45 +03:00
return ;
}
2005-07-18 01:24:36 +03:00
enc = ost - > st - > codec ;
2005-06-03 17:31:45 +03:00
if ( ! subtitle_out ) {
subtitle_out = av_malloc ( subtitle_out_max_size ) ;
}
/* Note: DVB subtitle need one packet to draw them and one other
packet to clear them */
/* XXX: signal it in the codec context ? */
if ( enc - > codec_id = = CODEC_ID_DVB_SUBTITLE )
nb = 2 ;
else
nb = 1 ;
for ( i = 0 ; i < nb ; i + + ) {
2009-06-19 11:28:07 +03:00
sub - > pts = av_rescale_q ( pts , ist - > st - > time_base , AV_TIME_BASE_Q ) ;
2009-08-26 11:43:11 +03:00
// start_display_time is required to be 0
sub - > pts + = av_rescale_q ( sub - > start_display_time , ( AVRational ) { 1 , 1000 } , AV_TIME_BASE_Q ) ;
sub - > end_display_time - = sub - > start_display_time ;
sub - > start_display_time = 0 ;
2005-12-17 20:14:38 +02:00
subtitle_out_size = avcodec_encode_subtitle ( enc , subtitle_out ,
2005-06-03 17:31:45 +03:00
subtitle_out_max_size , sub ) ;
2009-08-15 03:37:31 +03:00
if ( subtitle_out_size < 0 ) {
fprintf ( stderr , " Subtitle encoding failed \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-08-15 03:37:31 +03:00
}
2005-12-17 20:14:38 +02:00
2005-06-03 17:31:45 +03:00
av_init_packet ( & pkt ) ;
pkt . stream_index = ost - > index ;
pkt . data = subtitle_out ;
pkt . size = subtitle_out_size ;
2009-08-26 11:43:11 +03:00
pkt . pts = av_rescale_q ( sub - > pts , AV_TIME_BASE_Q , ost - > st - > time_base ) ;
2005-06-03 17:31:45 +03:00
if ( enc - > codec_id = = CODEC_ID_DVB_SUBTITLE ) {
/* XXX: the pts correction is handled here. Maybe handling
it in the codec would be better */
if ( i = = 0 )
pkt . pts + = 90 * sub - > start_display_time ;
else
pkt . pts + = 90 * sub - > end_display_time ;
}
2010-10-16 13:06:13 +03:00
write_frame ( s , & pkt , ost - > st - > codec , ost - > bitstream_filters ) ;
2005-06-03 17:31:45 +03:00
}
}
2004-11-27 19:46:30 +02:00
static int bit_buffer_size = 1024 * 256 ;
2004-06-23 00:45:30 +03:00
static uint8_t * bit_buffer = NULL ;
2004-04-08 21:54:40 +03:00
2005-12-17 20:14:38 +02:00
static void do_video_out ( AVFormatContext * s ,
AVOutputStream * ost ,
2001-07-22 17:37:44 +03:00
AVInputStream * ist ,
2003-12-12 18:56:38 +02:00
AVFrame * in_picture ,
2004-06-30 17:47:29 +03:00
int * frame_size )
2001-07-22 17:37:44 +03:00
{
2011-05-06 12:10:02 +03:00
int nb_frames , i , ret , av_unused resample_changed ;
2011-05-06 12:06:58 +03:00
AVFrame * final_picture , * formatted_picture ;
2001-08-11 21:58:18 +03:00
AVCodecContext * enc , * dec ;
2010-03-15 04:32:21 +02:00
double sync_ipts ;
2005-12-17 20:14:38 +02:00
2005-07-18 01:24:36 +03:00
enc = ost - > st - > codec ;
dec = ist - > st - > codec ;
2001-07-22 17:37:44 +03:00
2010-03-15 04:32:21 +02:00
sync_ipts = get_sync_ipts ( ost ) / av_q2d ( enc - > time_base ) ;
2002-10-21 20:42:47 +03:00
/* by default, we output a single frame */
nb_frames = 1 ;
2003-01-17 06:14:50 +02:00
* frame_size = 0 ;
2009-11-26 01:33:47 +02:00
if ( video_sync_method ) {
2010-03-15 04:33:49 +02:00
double vdelta = sync_ipts - ost - > sync_opts ;
2004-05-29 05:06:32 +03:00
//FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
if ( vdelta < - 1.1 )
nb_frames = 0 ;
2009-02-27 16:53:29 +02:00
else if ( video_sync_method = = 2 | | ( video_sync_method < 0 & & ( s - > oformat - > flags & AVFMT_VARIABLE_FPS ) ) ) {
if ( vdelta < = - 0.6 ) {
nb_frames = 0 ;
} else if ( vdelta > 0.6 )
2010-11-20 10:03:58 +02:00
ost - > sync_opts = lrintf ( sync_ipts ) ;
2009-02-27 16:53:29 +02:00
} else if ( vdelta > 1.1 )
2004-11-04 21:02:14 +02:00
nb_frames = lrintf ( vdelta ) ;
2009-02-27 16:44:58 +02:00
//fprintf(stderr, "vdelta:%f, ost->sync_opts:%"PRId64", ost->sync_ipts:%f nb_frames:%d\n", vdelta, ost->sync_opts, get_sync_ipts(ost), nb_frames);
2004-06-15 16:49:12 +03:00
if ( nb_frames = = 0 ) {
+ + nb_frames_drop ;
if ( verbose > 2 )
fprintf ( stderr , " *** drop! \n " ) ;
2004-07-25 12:30:56 +03:00
} else if ( nb_frames > 1 ) {
2009-12-14 14:37:24 +02:00
nb_frames_dup + = nb_frames - 1 ;
2004-06-15 16:49:12 +03:00
if ( verbose > 2 )
2004-07-25 12:30:56 +03:00
fprintf ( stderr , " *** %d dup! \n " , nb_frames - 1 ) ;
2004-06-15 16:49:12 +03:00
}
} else
2010-03-15 04:32:21 +02:00
ost - > sync_opts = lrintf ( sync_ipts ) ;
2003-07-12 10:37:05 +03:00
2010-03-31 02:30:55 +03:00
nb_frames = FFMIN ( nb_frames , max_frames [ AVMEDIA_TYPE_VIDEO ] - ost - > frame_number ) ;
2005-12-17 20:14:38 +02:00
if ( nb_frames < = 0 )
2001-07-22 17:37:44 +03:00
return ;
2002-03-19 08:30:41 +02:00
2010-05-07 12:43:21 +03:00
formatted_picture = in_picture ;
2006-04-10 12:04:15 +03:00
final_picture = formatted_picture ;
2011-05-06 12:10:02 +03:00
# if !CONFIG_AVFILTER
2011-04-17 00:11:01 +03:00
resample_changed = ost - > resample_width ! = dec - > width | |
ost - > resample_height ! = dec - > height | |
ost - > resample_pix_fmt ! = dec - > pix_fmt ;
if ( resample_changed ) {
2011-04-16 23:58:13 +03:00
av_log ( NULL , AV_LOG_INFO ,
" Input stream #%d.%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s \n " ,
ist - > file_index , ist - > index ,
2011-04-17 02:38:09 +03:00
ost - > resample_width , ost - > resample_height , avcodec_get_pix_fmt_name ( ost - > resample_pix_fmt ) ,
dec - > width , dec - > height , avcodec_get_pix_fmt_name ( dec - > pix_fmt ) ) ;
2011-05-02 10:35:38 +03:00
ost - > resample_width = dec - > width ;
ost - > resample_height = dec - > height ;
ost - > resample_pix_fmt = dec - > pix_fmt ;
2009-12-04 18:20:00 +02:00
}
2011-05-02 10:35:38 +03:00
ost - > video_resample = dec - > width ! = enc - > width | |
dec - > height ! = enc - > height | |
dec - > pix_fmt ! = enc - > pix_fmt ;
2001-07-22 17:37:44 +03:00
if ( ost - > video_resample ) {
2011-05-06 12:30:27 +03:00
final_picture = & ost - > resample_frame ;
2011-05-02 10:35:38 +03:00
if ( ! ost - > img_resample_ctx | | resample_changed ) {
/* initialize the destination picture */
2011-05-06 12:30:27 +03:00
if ( ! ost - > resample_frame . data [ 0 ] ) {
avcodec_get_frame_defaults ( & ost - > resample_frame ) ;
if ( avpicture_alloc ( ( AVPicture * ) & ost - > resample_frame , enc - > pix_fmt ,
2011-05-02 10:35:38 +03:00
enc - > width , enc - > height ) ) {
fprintf ( stderr , " Cannot allocate temp picture, check pix fmt \n " ) ;
ffmpeg_exit ( 1 ) ;
}
}
2009-06-19 17:43:36 +03:00
/* initialize a new scaler context */
sws_freeContext ( ost - > img_resample_ctx ) ;
2011-05-06 12:14:15 +03:00
ost - > img_resample_ctx = sws_getContext ( dec - > width , dec - > height , dec - > pix_fmt ,
enc - > width , enc - > height , enc - > pix_fmt ,
2011-05-10 05:01:29 +03:00
ost - > sws_flags , NULL , NULL , NULL ) ;
2009-06-19 17:43:36 +03:00
if ( ost - > img_resample_ctx = = NULL ) {
fprintf ( stderr , " Cannot get resampling context \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-06-19 17:43:36 +03:00
}
}
2006-08-02 14:50:38 +03:00
sws_scale ( ost - > img_resample_ctx , formatted_picture - > data , formatted_picture - > linesize ,
2011-05-06 12:30:27 +03:00
0 , ost - > resample_height , ost - > resample_frame . data , ost - > resample_frame . linesize ) ;
2006-04-10 13:16:13 +03:00
}
2010-05-07 12:43:21 +03:00
# endif
2006-04-10 12:04:15 +03:00
2001-07-22 17:37:44 +03:00
/* duplicates frame if needed */
2002-10-21 20:42:47 +03:00
for ( i = 0 ; i < nb_frames ; i + + ) {
2004-05-29 05:06:32 +03:00
AVPacket pkt ;
av_init_packet ( & pkt ) ;
pkt . stream_index = ost - > index ;
2003-03-16 23:03:20 +02:00
if ( s - > oformat - > flags & AVFMT_RAWPICTURE ) {
/* raw pictures are written as AVPicture structure to
avoid any copies . We support temorarily the older
method . */
2003-10-18 06:19:44 +03:00
AVFrame * old_frame = enc - > coded_frame ;
2005-12-22 03:10:11 +02:00
enc - > coded_frame = dec - > coded_frame ; //FIXME/XXX remove this hack
2004-05-29 05:06:32 +03:00
pkt . data = ( uint8_t * ) final_picture ;
pkt . size = sizeof ( AVPicture ) ;
2007-12-26 22:38:28 +02:00
pkt . pts = av_rescale_q ( ost - > sync_opts , enc - > time_base , ost - > st - > time_base ) ;
2010-03-31 15:29:58 +03:00
pkt . flags | = AV_PKT_FLAG_KEY ;
2004-05-29 05:06:32 +03:00
2010-10-16 13:06:13 +03:00
write_frame ( s , & pkt , ost - > st - > codec , ost - > bitstream_filters ) ;
2005-12-22 03:10:11 +02:00
enc - > coded_frame = old_frame ;
2003-03-16 23:03:20 +02:00
} else {
2002-12-09 14:03:43 +02:00
AVFrame big_picture ;
2004-04-17 22:41:49 +03:00
big_picture = * final_picture ;
2003-12-12 18:56:38 +02:00
/* better than nothing: use input picture interlaced
settings */
big_picture . interlaced_frame = in_picture - > interlaced_frame ;
2011-05-06 18:59:15 +03:00
if ( ost - > st - > codec - > flags & ( CODEC_FLAG_INTERLACED_DCT | CODEC_FLAG_INTERLACED_ME ) ) {
2003-12-30 18:07:57 +02:00
if ( top_field_first = = - 1 )
big_picture . top_field_first = in_picture - > top_field_first ;
else
2004-06-02 20:17:44 +03:00
big_picture . top_field_first = top_field_first ;
2003-12-30 18:07:57 +02:00
}
2003-12-12 18:56:38 +02:00
2001-07-22 17:37:44 +03:00
/* handles sameq here. This is not correct because it may
not be a global option */
2010-07-25 17:41:06 +03:00
big_picture . quality = same_quality ? ist - > st - > quality : ost - > st - > quality ;
2004-04-23 22:06:30 +03:00
if ( ! me_threshold )
big_picture . pict_type = 0 ;
2004-06-15 16:49:12 +03:00
// big_picture.pts = AV_NOPTS_VALUE;
2005-05-01 00:43:59 +03:00
big_picture . pts = ost - > sync_opts ;
// big_picture.pts= av_rescale(ost->sync_opts, AV_TIME_BASE*(int64_t)enc->time_base.num, enc->time_base.den);
2006-11-02 00:39:58 +02:00
//av_log(NULL, AV_LOG_DEBUG, "%"PRId64" -> encoder\n", ost->sync_opts);
2010-10-19 00:47:15 +03:00
if ( ost - > forced_kf_index < ost - > forced_kf_count & &
big_picture . pts > = ost - > forced_kf_pts [ ost - > forced_kf_index ] ) {
2011-04-28 02:40:44 +03:00
big_picture . pict_type = AV_PICTURE_TYPE_I ;
2010-10-19 00:47:15 +03:00
ost - > forced_kf_index + + ;
}
2005-12-17 20:14:38 +02:00
ret = avcodec_encode_video ( enc ,
2004-11-27 19:46:30 +02:00
bit_buffer , bit_buffer_size ,
2002-12-04 12:04:03 +02:00
& big_picture ) ;
2009-01-11 18:11:02 +02:00
if ( ret < 0 ) {
2006-09-26 17:04:36 +03:00
fprintf ( stderr , " Video encoding failed \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2006-09-26 17:04:36 +03:00
}
2009-05-30 05:48:47 +03:00
2005-01-10 22:29:39 +02:00
if ( ret > 0 ) {
2004-06-23 00:45:30 +03:00
pkt . data = bit_buffer ;
2004-05-29 05:06:32 +03:00
pkt . size = ret ;
2008-05-28 14:34:26 +03:00
if ( enc - > coded_frame - > pts ! = AV_NOPTS_VALUE )
2005-05-01 00:43:59 +03:00
pkt . pts = av_rescale_q ( enc - > coded_frame - > pts , enc - > time_base , ost - > st - > time_base ) ;
2006-11-02 00:39:58 +02:00
/*av_log(NULL, AV_LOG_DEBUG, "encoder -> %"PRId64"/%"PRId64"\n",
2005-05-01 00:43:59 +03:00
pkt . pts ! = AV_NOPTS_VALUE ? av_rescale ( pkt . pts , enc - > time_base . den , AV_TIME_BASE * ( int64_t ) enc - > time_base . num ) : - 1 ,
pkt . dts ! = AV_NOPTS_VALUE ? av_rescale ( pkt . dts , enc - > time_base . den , AV_TIME_BASE * ( int64_t ) enc - > time_base . num ) : - 1 ) ; */
2004-06-15 16:49:12 +03:00
2008-05-28 14:34:26 +03:00
if ( enc - > coded_frame - > key_frame )
2010-03-31 15:29:58 +03:00
pkt . flags | = AV_PKT_FLAG_KEY ;
2010-10-16 13:06:13 +03:00
write_frame ( s , & pkt , ost - > st - > codec , ost - > bitstream_filters ) ;
2004-05-29 05:06:32 +03:00
* frame_size = ret ;
2008-07-18 16:52:23 +03:00
video_size + = ret ;
2009-05-30 05:48:47 +03:00
//fprintf(stderr,"\nFrame: %3d size: %5d type: %d",
// enc->frame_number-1, ret, enc->pict_type);
2004-05-29 05:06:32 +03:00
/* if two pass, output log */
if ( ost - > logfile & & enc - > stats_out ) {
fprintf ( ost - > logfile , " %s " , enc - > stats_out ) ;
}
2002-10-10 20:09:01 +03:00
}
2001-07-22 17:37:44 +03:00
}
2004-06-15 16:49:12 +03:00
ost - > sync_opts + + ;
2002-10-21 20:42:47 +03:00
ost - > frame_number + + ;
2001-07-22 17:37:44 +03:00
}
}
2002-12-04 23:13:02 +02:00
static double psnr ( double d ) {
2003-02-10 11:44:47 +02:00
return - 10.0 * log ( d ) / log ( 10.0 ) ;
2002-12-04 23:13:02 +02:00
}
2005-12-17 20:14:38 +02:00
static void do_video_stats ( AVFormatContext * os , AVOutputStream * ost ,
2002-10-21 20:42:47 +03:00
int frame_size )
2002-03-19 08:30:41 +02:00
{
AVCodecContext * enc ;
int frame_number ;
double ti1 , bitrate , avg_bitrate ;
2005-12-17 20:14:38 +02:00
2007-04-25 16:55:11 +03:00
/* this is executed just the first time do_video_stats is called */
2007-09-06 23:11:02 +03:00
if ( ! vstats_file ) {
vstats_file = fopen ( vstats_filename , " w " ) ;
if ( ! vstats_file ) {
2007-04-25 16:48:36 +03:00
perror ( " fopen " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2007-04-25 16:48:36 +03:00
}
}
2005-07-18 01:24:36 +03:00
enc = ost - > st - > codec ;
2010-03-31 02:30:55 +03:00
if ( enc - > codec_type = = AVMEDIA_TYPE_VIDEO ) {
2002-10-21 20:42:47 +03:00
frame_number = ost - > frame_number ;
2007-09-06 23:11:02 +03:00
fprintf ( vstats_file , " frame= %5d q= %2.1f " , frame_number , enc - > coded_frame - > quality / ( float ) FF_QP2LAMBDA ) ;
2002-12-04 23:13:02 +02:00
if ( enc - > flags & CODEC_FLAG_PSNR )
2007-09-06 23:11:02 +03:00
fprintf ( vstats_file , " PSNR= %6.2f " , psnr ( enc - > coded_frame - > error [ 0 ] / ( enc - > width * enc - > height * 255.0 * 255.0 ) ) ) ;
2005-12-17 20:14:38 +02:00
2007-09-06 23:11:02 +03:00
fprintf ( vstats_file , " f_size= %6d " , frame_size ) ;
2002-10-21 20:42:47 +03:00
/* compute pts value */
2005-05-01 00:43:59 +03:00
ti1 = ost - > sync_opts * av_q2d ( enc - > time_base ) ;
2002-03-19 08:30:41 +02:00
if ( ti1 < 0.01 )
ti1 = 0.01 ;
2005-12-17 20:14:38 +02:00
2005-05-01 00:43:59 +03:00
bitrate = ( frame_size * 8 ) / av_q2d ( enc - > time_base ) / 1000.0 ;
2004-04-15 16:57:55 +03:00
avg_bitrate = ( double ) ( video_size * 8 ) / ti1 / 1000.0 ;
2007-09-06 23:11:02 +03:00
fprintf ( vstats_file , " s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s " ,
2004-04-15 16:57:55 +03:00
( double ) video_size / 1024 , ti1 , bitrate , avg_bitrate ) ;
2011-04-29 17:37:23 +03:00
fprintf ( vstats_file , " type= %c \n " , av_get_picture_type_char ( enc - > coded_frame - > pict_type ) ) ;
2002-03-19 08:30:41 +02:00
}
2002-10-21 20:42:47 +03:00
}
2003-02-10 11:44:47 +02:00
static void print_report ( AVFormatContext * * output_files ,
2005-12-22 03:10:11 +02:00
AVOutputStream * * ost_table , int nb_ostreams ,
int is_last_report )
2002-10-21 20:42:47 +03:00
{
char buf [ 1024 ] ;
AVOutputStream * ost ;
2009-04-17 18:15:25 +03:00
AVFormatContext * oc ;
2003-02-11 18:35:48 +02:00
int64_t total_size ;
2002-10-21 20:42:47 +03:00
AVCodecContext * enc ;
int frame_number , vid , i ;
double bitrate , ti1 , pts ;
2003-02-11 18:35:48 +02:00
static int64_t last_time = - 1 ;
2005-12-18 22:01:02 +02:00
static int qp_histogram [ 52 ] ;
2005-12-17 20:14:38 +02:00
2002-10-21 20:42:47 +03:00
if ( ! is_last_report ) {
2003-02-11 18:35:48 +02:00
int64_t cur_time ;
2002-10-21 20:42:47 +03:00
/* display the report every 0.5 seconds */
cur_time = av_gettime ( ) ;
if ( last_time = = - 1 ) {
last_time = cur_time ;
return ;
2005-12-17 20:14:38 +02:00
}
2002-10-21 20:42:47 +03:00
if ( ( cur_time - last_time ) < 500000 )
return ;
last_time = cur_time ;
}
2002-03-19 08:30:41 +02:00
2002-10-21 20:42:47 +03:00
oc = output_files [ 0 ] ;
2011-03-04 20:57:36 +02:00
total_size = avio_size ( oc - > pb ) ;
if ( total_size < 0 ) // FIXME improve avio_size() so it works with non seekable output too
2011-03-03 21:11:45 +02:00
total_size = avio_tell ( oc - > pb ) ;
2005-12-17 20:14:38 +02:00
2002-10-21 20:42:47 +03:00
buf [ 0 ] = ' \0 ' ;
ti1 = 1e10 ;
vid = 0 ;
for ( i = 0 ; i < nb_ostreams ; i + + ) {
2011-04-06 22:17:32 +03:00
float q = - 1 ;
2002-10-21 20:42:47 +03:00
ost = ost_table [ i ] ;
2005-07-18 01:24:36 +03:00
enc = ost - > st - > codec ;
2011-04-06 22:17:32 +03:00
if ( ! ost - > st - > stream_copy & & enc - > coded_frame )
q = enc - > coded_frame - > quality / ( float ) FF_QP2LAMBDA ;
2010-03-31 02:30:55 +03:00
if ( vid & & enc - > codec_type = = AVMEDIA_TYPE_VIDEO ) {
2011-04-06 22:17:32 +03:00
snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " q=%2.1f " , q ) ;
2002-11-20 05:06:12 +02:00
}
2010-03-31 02:30:55 +03:00
if ( ! vid & & enc - > codec_type = = AVMEDIA_TYPE_VIDEO ) {
2007-03-16 18:13:54 +02:00
float t = ( av_gettime ( ) - timer_start ) / 1000000.0 ;
2002-10-21 20:42:47 +03:00
frame_number = ost - > frame_number ;
2007-03-16 18:13:54 +02:00
snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " frame=%5d fps=%3d q=%3.1f " ,
2011-04-06 22:17:32 +03:00
frame_number , ( t > 1 ) ? ( int ) ( frame_number / t + 0.5 ) : 0 , q ) ;
2003-12-30 01:08:30 +02:00
if ( is_last_report )
2005-01-12 02:16:25 +02:00
snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " L " ) ;
2008-05-28 14:34:26 +03:00
if ( qp_hist ) {
2005-12-18 22:01:02 +02:00
int j ;
2011-04-06 22:17:32 +03:00
int qp = lrintf ( q ) ;
2008-10-22 00:40:24 +03:00
if ( qp > = 0 & & qp < FF_ARRAY_ELEMS ( qp_histogram ) )
2005-12-18 22:01:02 +02:00
qp_histogram [ qp ] + + ;
for ( j = 0 ; j < 32 ; j + + )
snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %X " , ( int ) lrintf ( log ( qp_histogram [ j ] + 1 ) / log ( 2 ) ) ) ;
}
2003-12-30 01:08:30 +02:00
if ( enc - > flags & CODEC_FLAG_PSNR ) {
int j ;
double error , error_sum = 0 ;
double scale , scale_sum = 0 ;
char type [ 3 ] = { ' Y ' , ' U ' , ' V ' } ;
2005-01-12 02:16:25 +02:00
snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " PSNR= " ) ;
2003-12-30 01:08:30 +02:00
for ( j = 0 ; j < 3 ; j + + ) {
if ( is_last_report ) {
error = enc - > error [ j ] ;
scale = enc - > width * enc - > height * 255.0 * 255.0 * frame_number ;
} else {
error = enc - > coded_frame - > error [ j ] ;
scale = enc - > width * enc - > height * 255.0 * 255.0 ;
}
if ( j ) scale / = 4 ;
error_sum + = error ;
scale_sum + = scale ;
2005-01-12 02:16:25 +02:00
snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %c:%2.2f " , type [ j ] , psnr ( error / scale ) ) ;
2003-12-30 01:08:30 +02:00
}
2005-01-12 02:16:25 +02:00
snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " *:%2.2f " , psnr ( error_sum / scale_sum ) ) ;
2003-12-30 01:08:30 +02:00
}
2002-10-21 20:42:47 +03:00
vid = 1 ;
}
/* compute min output value */
2007-07-17 16:04:22 +03:00
pts = ( double ) ost - > st - > pts . val * av_q2d ( ost - > st - > time_base ) ;
2002-10-26 22:23:22 +03:00
if ( ( pts < ti1 ) & & ( pts > 0 ) )
2002-10-21 20:42:47 +03:00
ti1 = pts ;
}
if ( ti1 < 0.01 )
ti1 = 0.01 ;
2005-12-17 20:14:38 +02:00
2011-04-18 14:04:33 +03:00
if ( verbose > 0 | | is_last_report ) {
2003-09-03 15:13:43 +03:00
bitrate = ( double ) ( total_size * 8 ) / ti1 / 1000.0 ;
2005-12-17 20:14:38 +02:00
snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) ,
2008-05-21 20:44:51 +03:00
" size=%8.0fkB time=%0.2f bitrate=%6.1fkbits/s " ,
2002-10-21 20:42:47 +03:00
( double ) total_size / 1024 , ti1 , bitrate ) ;
2004-06-12 01:03:16 +03:00
2009-12-14 14:40:10 +02:00
if ( nb_frames_dup | | nb_frames_drop )
2005-12-22 03:10:11 +02:00
snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " dup=%d drop=%d " ,
nb_frames_dup , nb_frames_drop ) ;
2005-12-17 20:14:38 +02:00
2004-04-11 16:50:42 +03:00
if ( verbose > = 0 )
fprintf ( stderr , " %s \r " , buf ) ;
2002-10-21 20:42:47 +03:00
fflush ( stderr ) ;
}
2005-12-17 20:14:38 +02:00
2004-04-15 16:57:55 +03:00
if ( is_last_report & & verbose > = 0 ) {
int64_t raw = audio_size + video_size + extra_size ;
2003-09-03 15:13:43 +03:00
fprintf ( stderr , " \n " ) ;
2004-04-15 16:57:55 +03:00
fprintf ( stderr , " video:%1.0fkB audio:%1.0fkB global headers:%1.0fkB muxing overhead %f%% \n " ,
video_size / 1024.0 ,
audio_size / 1024.0 ,
extra_size / 1024.0 ,
100.0 * ( total_size - raw ) / raw
) ;
}
2002-03-19 08:30:41 +02:00
}
2011-04-05 02:07:23 +03:00
static void generate_silence ( uint8_t * buf , enum AVSampleFormat sample_fmt , size_t size )
{
int fill_char = 0x00 ;
if ( sample_fmt = = AV_SAMPLE_FMT_U8 )
fill_char = 0x80 ;
memset ( buf , fill_char , size ) ;
}
2003-12-15 16:43:44 +02:00
/* pkt = NULL means EOF (needed to flush decoder buffers) */
static int output_packet ( AVInputStream * ist , int ist_index ,
AVOutputStream * * ost_table , int nb_ostreams ,
2004-04-27 02:06:29 +03:00
const AVPacket * pkt )
2003-12-15 16:43:44 +02:00
{
AVFormatContext * os ;
AVOutputStream * ost ;
2009-04-10 15:53:22 +03:00
int ret , i ;
2011-05-10 08:53:46 +03:00
int got_output ;
2003-12-15 16:43:44 +02:00
AVFrame picture ;
2011-04-20 14:13:09 +03:00
void * buffer_to_free = NULL ;
2006-01-26 00:10:13 +02:00
static unsigned int samples_size = 0 ;
2005-06-03 17:31:45 +03:00
AVSubtitle subtitle , * subtitle_to_free ;
2010-10-10 05:17:26 +03:00
int64_t pkt_pts = AV_NOPTS_VALUE ;
2010-05-07 12:43:21 +03:00
# if CONFIG_AVFILTER
2010-05-11 20:25:18 +03:00
int frame_available ;
2010-05-07 12:43:21 +03:00
# endif
2009-04-10 15:53:22 +03:00
AVPacket avpkt ;
2010-11-03 22:19:34 +02:00
int bps = av_get_bits_per_sample_fmt ( ist - > st - > codec - > sample_fmt ) > > 3 ;
2009-04-10 15:53:22 +03:00
2008-02-17 21:08:15 +02:00
if ( ist - > next_pts = = AV_NOPTS_VALUE )
ist - > next_pts = ist - > pts ;
2003-12-15 16:43:44 +02:00
if ( pkt = = NULL ) {
/* EOF handling */
2009-04-12 01:04:52 +03:00
av_init_packet ( & avpkt ) ;
2009-04-10 15:53:22 +03:00
avpkt . data = NULL ;
avpkt . size = 0 ;
2003-12-15 16:43:44 +02:00
goto handle_eof ;
2009-04-12 01:04:52 +03:00
} else {
avpkt = * pkt ;
2003-12-15 16:43:44 +02:00
}
2008-02-17 19:55:53 +02:00
if ( pkt - > dts ! = AV_NOPTS_VALUE )
ist - > next_pts = ist - > pts = av_rescale_q ( pkt - > dts , ist - > st - > time_base , AV_TIME_BASE_Q ) ;
2010-10-10 05:17:26 +03:00
if ( pkt - > pts ! = AV_NOPTS_VALUE )
pkt_pts = av_rescale_q ( pkt - > pts , ist - > st - > time_base , AV_TIME_BASE_Q ) ;
2008-02-17 19:55:53 +02:00
2008-07-14 00:39:18 +03:00
//while we have more to decode or while the decoder did output something on EOF
2011-05-10 08:53:46 +03:00
while ( avpkt . size > 0 | | ( ! pkt & & got_output ) ) {
2010-01-07 03:15:16 +02:00
uint8_t * data_buf , * decoded_data_buf ;
int data_size , decoded_data_size ;
2003-12-15 16:43:44 +02:00
handle_eof :
2008-02-17 19:55:53 +02:00
ist - > pts = ist - > next_pts ;
2008-02-15 23:45:12 +02:00
2009-09-16 18:08:26 +03:00
if ( avpkt . size & & avpkt . size ! = pkt - > size & &
2010-02-06 02:10:42 +02:00
( ( ! ist - > showed_multi_packet_warning & & verbose > 0 ) | | verbose > 1 ) ) {
2008-02-17 21:38:47 +02:00
fprintf ( stderr , " Multiple frames in a packet from stream %d \n " , pkt - > stream_index ) ;
2010-01-27 15:27:18 +02:00
ist - > showed_multi_packet_warning = 1 ;
}
2008-02-17 21:38:47 +02:00
2003-12-15 16:43:44 +02:00
/* decode the packet if needed */
2010-01-07 03:15:16 +02:00
decoded_data_buf = NULL ; /* fail safe */
decoded_data_size = 0 ;
data_buf = avpkt . data ;
data_size = avpkt . size ;
2005-06-03 17:31:45 +03:00
subtitle_to_free = NULL ;
2003-12-15 16:43:44 +02:00
if ( ist - > decoding_needed ) {
2005-07-18 01:24:36 +03:00
switch ( ist - > st - > codec - > codec_type ) {
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_AUDIO : {
2008-08-12 08:59:12 +03:00
if ( pkt & & samples_size < FFMAX ( pkt - > size * sizeof ( * samples ) , AVCODEC_MAX_AUDIO_FRAME_SIZE ) ) {
samples_size = FFMAX ( pkt - > size * sizeof ( * samples ) , AVCODEC_MAX_AUDIO_FRAME_SIZE ) ;
av_free ( samples ) ;
samples = av_malloc ( samples_size ) ;
}
2010-01-07 03:15:16 +02:00
decoded_data_size = samples_size ;
2003-12-15 16:43:44 +02:00
/* XXX: could avoid copy if PCM 16 bits with same
endianness as CPU */
2010-01-07 03:15:16 +02:00
ret = avcodec_decode_audio3 ( ist - > st - > codec , samples , & decoded_data_size ,
2009-04-10 15:53:22 +03:00
& avpkt ) ;
2003-12-15 16:43:44 +02:00
if ( ret < 0 )
goto fail_decode ;
2009-04-10 15:53:22 +03:00
avpkt . data + = ret ;
avpkt . size - = ret ;
2010-01-07 03:15:16 +02:00
data_size = ret ;
2011-05-10 08:53:46 +03:00
got_output = decoded_data_size > 0 ;
2003-12-15 16:43:44 +02:00
/* Some bug in mpeg audio decoder gives */
2010-01-07 03:15:16 +02:00
/* decoded_data_size < 0, it seems they are overflows */
2011-05-10 08:53:46 +03:00
if ( ! got_output ) {
2003-12-15 16:43:44 +02:00
/* no audio frame */
continue ;
}
2010-01-07 03:15:16 +02:00
decoded_data_buf = ( uint8_t * ) samples ;
ist - > next_pts + = ( ( int64_t ) AV_TIME_BASE / bps * decoded_data_size ) /
2005-07-18 01:24:36 +03:00
( ist - > st - > codec - > sample_rate * ist - > st - > codec - > channels ) ;
2004-08-14 17:51:10 +03:00
break ; }
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_VIDEO :
2010-01-07 03:15:16 +02:00
decoded_data_size = ( ist - > st - > codec - > width * ist - > st - > codec - > height * 3 ) / 2 ;
2003-12-15 16:43:44 +02:00
/* XXX: allocate picture correctly */
2004-02-25 19:35:52 +02:00
avcodec_get_frame_defaults ( & picture ) ;
2011-02-05 07:28:24 +02:00
avpkt . pts = pkt_pts ;
avpkt . dts = ist - > pts ;
2010-10-10 05:17:26 +03:00
pkt_pts = AV_NOPTS_VALUE ;
2004-02-25 19:35:52 +02:00
2009-04-10 15:53:22 +03:00
ret = avcodec_decode_video2 ( ist - > st - > codec ,
2011-05-10 08:53:46 +03:00
& picture , & got_output , & avpkt ) ;
2003-12-15 16:43:44 +02:00
ist - > st - > quality = picture . quality ;
2005-12-17 20:14:38 +02:00
if ( ret < 0 )
2003-12-15 16:43:44 +02:00
goto fail_decode ;
2011-05-10 08:53:46 +03:00
if ( ! got_output ) {
2003-12-15 16:43:44 +02:00
/* no picture yet */
goto discard_packet ;
}
2011-01-30 21:18:31 +02:00
ist - > next_pts = ist - > pts = picture . best_effort_timestamp ;
2005-07-18 01:24:36 +03:00
if ( ist - > st - > codec - > time_base . num ! = 0 ) {
2009-02-27 01:47:32 +02:00
int ticks = ist - > st - > parser ? ist - > st - > parser - > repeat_pict + 1 : ist - > st - > codec - > ticks_per_frame ;
2005-12-17 20:14:38 +02:00
ist - > next_pts + = ( ( int64_t ) AV_TIME_BASE *
2009-02-26 15:15:22 +02:00
ist - > st - > codec - > time_base . num * ticks ) /
2005-07-18 01:24:36 +03:00
ist - > st - > codec - > time_base . den ;
2003-12-15 16:43:44 +02:00
}
2009-04-10 15:53:22 +03:00
avpkt . size = 0 ;
2011-04-20 14:13:09 +03:00
buffer_to_free = NULL ;
pre_process_video_frame ( ist , ( AVPicture * ) & picture , & buffer_to_free ) ;
2003-12-15 16:43:44 +02:00
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_SUBTITLE :
2009-04-10 15:53:22 +03:00
ret = avcodec_decode_subtitle2 ( ist - > st - > codec ,
2011-05-10 08:53:46 +03:00
& subtitle , & got_output , & avpkt ) ;
2005-06-03 17:31:45 +03:00
if ( ret < 0 )
2003-12-15 16:43:44 +02:00
goto fail_decode ;
2011-05-10 08:53:46 +03:00
if ( ! got_output ) {
2005-06-03 17:31:45 +03:00
goto discard_packet ;
2003-12-15 16:43:44 +02:00
}
2005-06-03 17:31:45 +03:00
subtitle_to_free = & subtitle ;
2009-04-10 15:53:22 +03:00
avpkt . size = 0 ;
2005-06-03 17:31:45 +03:00
break ;
default :
goto fail_decode ;
}
} else {
2007-03-12 16:35:36 +02:00
switch ( ist - > st - > codec - > codec_type ) {
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_AUDIO :
2007-03-12 16:35:36 +02:00
ist - > next_pts + = ( ( int64_t ) AV_TIME_BASE * ist - > st - > codec - > frame_size ) /
2007-11-28 02:59:19 +02:00
ist - > st - > codec - > sample_rate ;
2007-03-12 16:35:36 +02:00
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_VIDEO :
2007-03-12 16:35:36 +02:00
if ( ist - > st - > codec - > time_base . num ! = 0 ) {
2009-02-27 01:47:32 +02:00
int ticks = ist - > st - > parser ? ist - > st - > parser - > repeat_pict + 1 : ist - > st - > codec - > ticks_per_frame ;
2007-03-12 16:35:36 +02:00
ist - > next_pts + = ( ( int64_t ) AV_TIME_BASE *
2009-02-26 15:15:22 +02:00
ist - > st - > codec - > time_base . num * ticks ) /
2007-03-12 16:35:36 +02:00
ist - > st - > codec - > time_base . den ;
2004-12-14 22:01:49 +02:00
}
2007-03-12 16:35:36 +02:00
break ;
2003-12-15 16:43:44 +02:00
}
2009-04-10 15:53:22 +03:00
ret = avpkt . size ;
avpkt . size = 0 ;
2007-03-12 16:35:36 +02:00
}
2003-12-15 16:43:44 +02:00
2010-05-07 12:43:21 +03:00
# if CONFIG_AVFILTER
2011-05-17 05:47:05 +03:00
if ( ist - > st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO ) {
2011-02-15 00:02:10 +02:00
for ( i = 0 ; i < nb_ostreams ; i + + ) {
ost = ost_table [ i ] ;
if ( ost - > input_video_filter & & ost - > source_index = = ist_index ) {
2011-04-29 14:04:47 +03:00
if ( ! picture . sample_aspect_ratio . num )
picture . sample_aspect_ratio = ist - > st - > sample_aspect_ratio ;
2011-05-02 10:52:11 +03:00
picture . pts = ist - > pts ;
2011-05-07 22:35:08 +03:00
2011-05-19 02:17:16 +03:00
av_vsrc_buffer_add_frame ( ost - > input_video_filter , & picture ) ;
2011-02-15 00:02:10 +02:00
}
}
2010-05-07 12:43:21 +03:00
}
# endif
2007-03-12 16:35:36 +02:00
// preprocess audio (volume)
2010-03-31 02:30:55 +03:00
if ( ist - > st - > codec - > codec_type = = AVMEDIA_TYPE_AUDIO ) {
2007-03-12 16:35:36 +02:00
if ( audio_volume ! = 256 ) {
short * volp ;
volp = samples ;
2010-01-07 03:15:16 +02:00
for ( i = 0 ; i < ( decoded_data_size / sizeof ( short ) ) ; i + + ) {
2007-03-12 16:35:36 +02:00
int v = ( ( * volp ) * audio_volume + 128 ) > > 8 ;
if ( v < - 32768 ) v = - 32768 ;
if ( v > 32767 ) v = 32767 ;
* volp + + = v ;
2005-03-23 03:59:17 +02:00
}
}
2007-03-12 16:35:36 +02:00
}
2005-03-23 03:59:17 +02:00
2007-03-12 16:35:36 +02:00
/* frame rate emulation */
2008-11-27 23:38:42 +02:00
if ( rate_emu ) {
2008-11-27 23:24:25 +02:00
int64_t pts = av_rescale ( ist - > pts , 1000000 , AV_TIME_BASE ) ;
2007-03-12 16:35:36 +02:00
int64_t now = av_gettime ( ) - ist - > start ;
if ( pts > now )
usleep ( pts - now ) ;
}
/* if output time reached then transcode raw format,
encode packets and output them */
if ( start_time = = 0 | | ist - > pts > = start_time )
for ( i = 0 ; i < nb_ostreams ; i + + ) {
int frame_size ;
2003-12-15 16:43:44 +02:00
2007-03-12 16:35:36 +02:00
ost = ost_table [ i ] ;
if ( ost - > source_index = = ist_index ) {
2011-02-15 00:02:10 +02:00
# if CONFIG_AVFILTER
frame_available = ist - > st - > codec - > codec_type ! = AVMEDIA_TYPE_VIDEO | |
! ost - > output_video_filter | | avfilter_poll_frame ( ost - > output_video_filter - > inputs [ 0 ] ) ;
while ( frame_available ) {
AVRational ist_pts_tb ;
if ( ist - > st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO & & ost - > output_video_filter )
get_filtered_video_frame ( ost - > output_video_filter , & picture , & ost - > picref , & ist_pts_tb ) ;
if ( ost - > picref )
ist - > pts = av_rescale_q ( ost - > picref - > pts , ist_pts_tb , AV_TIME_BASE_Q ) ;
# endif
2007-03-12 16:35:36 +02:00
os = output_files [ ost - > file_index ] ;
2003-12-15 16:43:44 +02:00
2007-03-12 16:35:36 +02:00
/* set the input output pts pairs */
//ost->sync_ipts = (double)(ist->pts + input_files_ts_offset[ist->file_index] - start_time)/ AV_TIME_BASE;
if ( ost - > encoding_needed ) {
2010-10-01 00:57:31 +03:00
av_assert0 ( ist - > decoding_needed ) ;
2007-03-12 16:35:36 +02:00
switch ( ost - > st - > codec - > codec_type ) {
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_AUDIO :
2010-01-07 03:15:16 +02:00
do_audio_out ( os , ost , ist , decoded_data_buf , decoded_data_size ) ;
2007-03-12 16:35:36 +02:00
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_VIDEO :
2010-05-07 12:43:21 +03:00
# if CONFIG_AVFILTER
2011-04-17 02:47:24 +03:00
if ( ost - > picref - > video & & ! ost - > frame_aspect_ratio )
2011-04-29 14:12:39 +03:00
ost - > st - > codec - > sample_aspect_ratio = ost - > picref - > video - > sample_aspect_ratio ;
2010-05-07 12:43:21 +03:00
# endif
2007-03-12 16:35:36 +02:00
do_video_out ( os , ost , ist , & picture , & frame_size ) ;
2007-04-25 16:55:11 +03:00
if ( vstats_filename & & frame_size )
2007-03-12 16:35:36 +02:00
do_video_stats ( os , ost , frame_size ) ;
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_SUBTITLE :
2007-03-12 16:35:36 +02:00
do_subtitle_out ( os , ost , ist , & subtitle ,
pkt - > pts ) ;
break ;
default :
2007-07-02 10:43:23 +03:00
abort ( ) ;
2007-03-12 16:35:36 +02:00
}
} else {
AVFrame avframe ; //FIXME/XXX remove this
AVPacket opkt ;
2009-04-09 03:13:59 +03:00
int64_t ost_tb_start_time = av_rescale_q ( start_time , AV_TIME_BASE_Q , ost - > st - > time_base ) ;
2007-03-12 16:35:36 +02:00
av_init_packet ( & opkt ) ;
2010-03-31 15:29:58 +03:00
if ( ( ! ost - > frame_number & & ! ( pkt - > flags & AV_PKT_FLAG_KEY ) ) & & ! copy_initial_nonkeyframes )
2011-03-16 22:37:41 +02:00
# if !CONFIG_AVFILTER
continue ;
# else
2011-02-19 18:30:04 +02:00
goto cont ;
2011-03-16 22:37:41 +02:00
# endif
2007-08-04 02:25:03 +03:00
2007-03-12 16:35:36 +02:00
/* no reencoding needed : output the packet directly */
/* force the input stream PTS */
avcodec_get_frame_defaults ( & avframe ) ;
ost - > st - > codec - > coded_frame = & avframe ;
2010-03-31 15:29:58 +03:00
avframe . key_frame = pkt - > flags & AV_PKT_FLAG_KEY ;
2007-03-12 16:35:36 +02:00
2010-03-31 02:30:55 +03:00
if ( ost - > st - > codec - > codec_type = = AVMEDIA_TYPE_AUDIO )
2007-03-12 16:35:36 +02:00
audio_size + = data_size ;
2010-03-31 02:30:55 +03:00
else if ( ost - > st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO ) {
2007-03-12 16:35:36 +02:00
video_size + = data_size ;
ost - > sync_opts + + ;
}
opkt . stream_index = ost - > index ;
if ( pkt - > pts ! = AV_NOPTS_VALUE )
2009-04-09 03:13:59 +03:00
opkt . pts = av_rescale_q ( pkt - > pts , ist - > st - > time_base , ost - > st - > time_base ) - ost_tb_start_time ;
2007-03-12 16:35:36 +02:00
else
opkt . pts = AV_NOPTS_VALUE ;
2008-06-22 04:36:15 +03:00
if ( pkt - > dts = = AV_NOPTS_VALUE )
2008-06-25 16:46:06 +03:00
opkt . dts = av_rescale_q ( ist - > pts , AV_TIME_BASE_Q , ost - > st - > time_base ) ;
2008-06-22 04:36:15 +03:00
else
opkt . dts = av_rescale_q ( pkt - > dts , ist - > st - > time_base , ost - > st - > time_base ) ;
2009-04-09 03:13:59 +03:00
opkt . dts - = ost_tb_start_time ;
2007-08-03 23:49:53 +03:00
2007-07-25 22:36:43 +03:00
opkt . duration = av_rescale_q ( pkt - > duration , ist - > st - > time_base , ost - > st - > time_base ) ;
2007-03-12 16:35:36 +02:00
opkt . flags = pkt - > flags ;
//FIXME remove the following 2 lines they shall be replaced by the bitstream filters
2010-02-03 16:53:14 +02:00
if ( ost - > st - > codec - > codec_id ! = CODEC_ID_H264
& & ost - > st - > codec - > codec_id ! = CODEC_ID_MPEG1VIDEO
& & ost - > st - > codec - > codec_id ! = CODEC_ID_MPEG2VIDEO
) {
2010-03-31 15:29:58 +03:00
if ( av_parser_change ( ist - > st - > parser , ost - > st - > codec , & opkt . data , & opkt . size , data_buf , data_size , pkt - > flags & AV_PKT_FLAG_KEY ) )
2010-01-07 02:50:34 +02:00
opkt . destruct = av_destruct_packet ;
2009-06-15 02:55:25 +03:00
} else {
opkt . data = data_buf ;
opkt . size = data_size ;
}
2007-03-12 16:35:36 +02:00
2010-10-16 13:06:13 +03:00
write_frame ( os , & opkt , ost - > st - > codec , ost - > bitstream_filters ) ;
2007-03-12 16:35:36 +02:00
ost - > st - > codec - > frame_number + + ;
ost - > frame_number + + ;
av_free_packet ( & opkt ) ;
2003-12-15 16:43:44 +02:00
}
2011-02-15 00:02:10 +02:00
# if CONFIG_AVFILTER
2011-03-16 22:37:41 +02:00
cont :
2011-02-15 00:02:10 +02:00
frame_available = ( ist - > st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO ) & &
ost - > output_video_filter & & avfilter_poll_frame ( ost - > output_video_filter - > inputs [ 0 ] ) ;
2011-05-19 20:01:38 +03:00
avfilter_unref_buffer ( ost - > picref ) ;
2011-02-15 00:02:10 +02:00
}
# endif
2003-12-15 16:43:44 +02:00
}
2007-03-12 16:35:36 +02:00
}
2010-05-07 12:43:21 +03:00
2007-03-12 16:35:36 +02:00
av_free ( buffer_to_free ) ;
/* XXX: allocate the subtitles in the codec ? */
if ( subtitle_to_free ) {
2010-12-31 02:01:37 +02:00
avsubtitle_free ( subtitle_to_free ) ;
2007-03-12 16:35:36 +02:00
subtitle_to_free = NULL ;
2003-12-15 16:43:44 +02:00
}
2007-03-12 16:35:36 +02:00
}
2003-12-15 16:43:44 +02:00
discard_packet :
2004-06-23 00:14:01 +03:00
if ( pkt = = NULL ) {
/* EOF handling */
2005-12-17 20:14:38 +02:00
2004-06-23 00:14:01 +03:00
for ( i = 0 ; i < nb_ostreams ; i + + ) {
ost = ost_table [ i ] ;
if ( ost - > source_index = = ist_index ) {
2005-07-18 01:24:36 +03:00
AVCodecContext * enc = ost - > st - > codec ;
2004-06-23 00:14:01 +03:00
os = output_files [ ost - > file_index ] ;
2005-12-17 20:14:38 +02:00
2010-03-31 02:30:55 +03:00
if ( ost - > st - > codec - > codec_type = = AVMEDIA_TYPE_AUDIO & & enc - > frame_size < = 1 )
2004-06-23 00:14:01 +03:00
continue ;
2010-03-31 02:30:55 +03:00
if ( ost - > st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO & & ( os - > oformat - > flags & AVFMT_RAWPICTURE ) )
2004-06-23 00:14:01 +03:00
continue ;
if ( ost - > encoding_needed ) {
for ( ; ; ) {
AVPacket pkt ;
2006-06-24 12:25:21 +03:00
int fifo_bytes ;
2004-06-23 00:14:01 +03:00
av_init_packet ( & pkt ) ;
pkt . stream_index = ost - > index ;
2005-12-17 20:14:38 +02:00
2005-07-18 01:24:36 +03:00
switch ( ost - > st - > codec - > codec_type ) {
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_AUDIO :
2009-03-08 16:16:55 +02:00
fifo_bytes = av_fifo_size ( ost - > fifo ) ;
2006-06-24 12:25:21 +03:00
ret = 0 ;
/* encode any samples remaining in fifo */
2009-05-23 07:07:25 +03:00
if ( fifo_bytes > 0 ) {
2010-11-03 22:19:34 +02:00
int osize = av_get_bits_per_sample_fmt ( enc - > sample_fmt ) > > 3 ;
2006-06-24 12:25:21 +03:00
int fs_tmp = enc - > frame_size ;
2009-05-23 07:07:25 +03:00
2010-06-10 22:40:56 +03:00
av_fifo_generic_read ( ost - > fifo , audio_buf , fifo_bytes , NULL ) ;
2009-05-23 07:07:25 +03:00
if ( enc - > codec - > capabilities & CODEC_CAP_SMALL_LAST_FRAME ) {
enc - > frame_size = fifo_bytes / ( osize * enc - > channels ) ;
} else { /* pad */
int frame_bytes = enc - > frame_size * osize * enc - > channels ;
2010-06-10 22:40:56 +03:00
if ( allocated_audio_buf_size < frame_bytes )
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2011-04-05 02:07:23 +03:00
generate_silence ( audio_buf + fifo_bytes , enc - > sample_fmt , frame_bytes - fifo_bytes ) ;
2009-05-23 07:07:25 +03:00
}
2010-06-10 22:40:56 +03:00
ret = avcodec_encode_audio ( enc , bit_buffer , bit_buffer_size , ( short * ) audio_buf ) ;
2009-04-14 03:20:52 +03:00
pkt . duration = av_rescale ( ( int64_t ) enc - > frame_size * ost - > st - > time_base . den ,
ost - > st - > time_base . num , enc - > sample_rate ) ;
2006-06-24 12:25:21 +03:00
enc - > frame_size = fs_tmp ;
2006-06-24 12:57:28 +03:00
}
if ( ret < = 0 ) {
2006-06-24 12:25:21 +03:00
ret = avcodec_encode_audio ( enc , bit_buffer , bit_buffer_size , NULL ) ;
}
2009-01-11 18:15:34 +02:00
if ( ret < 0 ) {
fprintf ( stderr , " Audio encoding failed \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-01-11 18:15:34 +02:00
}
2004-06-23 00:14:01 +03:00
audio_size + = ret ;
2010-03-31 15:29:58 +03:00
pkt . flags | = AV_PKT_FLAG_KEY ;
2004-06-23 00:14:01 +03:00
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_VIDEO :
2004-11-27 19:46:30 +02:00
ret = avcodec_encode_video ( enc , bit_buffer , bit_buffer_size , NULL ) ;
2009-01-11 18:15:34 +02:00
if ( ret < 0 ) {
fprintf ( stderr , " Video encoding failed \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-01-11 18:15:34 +02:00
}
2004-06-23 00:14:01 +03:00
video_size + = ret ;
if ( enc - > coded_frame & & enc - > coded_frame - > key_frame )
2010-03-31 15:29:58 +03:00
pkt . flags | = AV_PKT_FLAG_KEY ;
2004-06-23 00:14:01 +03:00
if ( ost - > logfile & & enc - > stats_out ) {
fprintf ( ost - > logfile , " %s " , enc - > stats_out ) ;
}
break ;
default :
ret = - 1 ;
}
2005-12-17 20:14:38 +02:00
2004-06-23 00:14:01 +03:00
if ( ret < = 0 )
break ;
2004-06-23 00:45:30 +03:00
pkt . data = bit_buffer ;
2004-06-23 00:14:01 +03:00
pkt . size = ret ;
2005-09-11 11:24:36 +03:00
if ( enc - > coded_frame & & enc - > coded_frame - > pts ! = AV_NOPTS_VALUE )
2005-05-01 00:43:59 +03:00
pkt . pts = av_rescale_q ( enc - > coded_frame - > pts , enc - > time_base , ost - > st - > time_base ) ;
2010-10-16 13:06:13 +03:00
write_frame ( os , & pkt , ost - > st - > codec , ost - > bitstream_filters ) ;
2004-06-23 00:14:01 +03:00
}
}
}
}
}
2005-12-17 20:14:38 +02:00
2003-12-15 16:43:44 +02:00
return 0 ;
fail_decode :
return - 1 ;
}
2007-08-20 11:12:08 +03:00
static void print_sdp ( AVFormatContext * * avc , int n )
{
char sdp [ 2048 ] ;
2011-04-08 12:36:12 +03:00
av_sdp_create ( avc , n , sdp , sizeof ( sdp ) ) ;
2007-08-20 11:12:08 +03:00
printf ( " SDP: \n %s \n " , sdp ) ;
2008-11-15 14:32:38 +02:00
fflush ( stdout ) ;
2007-08-20 11:12:08 +03:00
}
2003-12-15 16:43:44 +02:00
2010-03-19 09:44:38 +02:00
static int copy_chapters ( int infile , int outfile )
{
AVFormatContext * is = input_files [ infile ] ;
AVFormatContext * os = output_files [ outfile ] ;
int i ;
for ( i = 0 ; i < is - > nb_chapters ; i + + ) {
AVChapter * in_ch = is - > chapters [ i ] , * out_ch ;
int64_t ts_off = av_rescale_q ( start_time - input_files_ts_offset [ infile ] ,
AV_TIME_BASE_Q , in_ch - > time_base ) ;
int64_t rt = ( recording_time = = INT64_MAX ) ? INT64_MAX :
av_rescale_q ( recording_time , AV_TIME_BASE_Q , in_ch - > time_base ) ;
if ( in_ch - > end < ts_off )
continue ;
if ( rt ! = INT64_MAX & & in_ch - > start > rt + ts_off )
break ;
out_ch = av_mallocz ( sizeof ( AVChapter ) ) ;
if ( ! out_ch )
return AVERROR ( ENOMEM ) ;
out_ch - > id = in_ch - > id ;
out_ch - > time_base = in_ch - > time_base ;
out_ch - > start = FFMAX ( 0 , in_ch - > start - ts_off ) ;
out_ch - > end = FFMIN ( rt , in_ch - > end - ts_off ) ;
2010-11-02 08:12:54 +02:00
if ( metadata_chapters_autocopy )
2011-01-14 21:30:55 +02:00
av_metadata_copy ( & out_ch - > metadata , in_ch - > metadata , 0 ) ;
2010-03-19 09:44:38 +02:00
os - > nb_chapters + + ;
os - > chapters = av_realloc ( os - > chapters , sizeof ( AVChapter ) * os - > nb_chapters ) ;
if ( ! os - > chapters )
return AVERROR ( ENOMEM ) ;
os - > chapters [ os - > nb_chapters - 1 ] = out_ch ;
}
return 0 ;
}
2010-10-19 00:47:15 +03:00
static void parse_forced_key_frames ( char * kf , AVOutputStream * ost ,
AVCodecContext * avctx )
{
char * p ;
int n = 1 , i ;
int64_t t ;
for ( p = kf ; * p ; p + + )
if ( * p = = ' , ' )
n + + ;
ost - > forced_kf_count = n ;
ost - > forced_kf_pts = av_malloc ( sizeof ( * ost - > forced_kf_pts ) * n ) ;
if ( ! ost - > forced_kf_pts ) {
av_log ( NULL , AV_LOG_FATAL , " Could not allocate forced key frames array. \n " ) ;
ffmpeg_exit ( 1 ) ;
}
for ( i = 0 ; i < n ; i + + ) {
p = i ? strchr ( p , ' , ' ) + 1 : kf ;
t = parse_time_or_die ( " force_key_frames " , p , 1 ) ;
ost - > forced_kf_pts [ i ] = av_rescale_q ( t , AV_TIME_BASE_Q , avctx - > time_base ) ;
}
}
2001-07-22 17:37:44 +03:00
/*
* The following code is the main loop of the file converter
*/
2010-07-26 16:39:41 +03:00
static int transcode ( AVFormatContext * * output_files ,
2010-07-26 16:39:49 +03:00
int nb_output_files ,
AVFormatContext * * input_files ,
int nb_input_files ,
AVStreamMap * stream_maps , int nb_stream_maps )
2001-07-22 17:37:44 +03:00
{
2011-04-02 17:09:47 +03:00
int ret = 0 , i , j , k , n , nb_istreams = 0 , nb_ostreams = 0 , step ;
2001-07-22 17:37:44 +03:00
AVFormatContext * is , * os ;
AVCodecContext * codec , * icodec ;
AVOutputStream * ost , * * ost_table = NULL ;
AVInputStream * ist , * * ist_table = NULL ;
2001-08-14 00:43:02 +03:00
AVInputFile * file_table ;
2009-03-11 08:06:18 +02:00
char error [ 1024 ] ;
2002-05-30 05:38:57 +03:00
int key ;
2007-08-20 11:12:08 +03:00
int want_sdp = 1 ;
2009-03-03 21:50:04 +02:00
uint8_t no_packet [ MAX_FILES ] = { 0 } ;
int no_packet_count = 0 ;
2011-04-02 17:09:47 +03:00
int nb_frame_threshold [ AVMEDIA_TYPE_NB ] = { 0 } ;
int nb_streams [ AVMEDIA_TYPE_NB ] = { 0 } ;
2001-08-14 00:43:02 +03:00
2007-12-01 02:19:44 +02:00
file_table = av_mallocz ( nb_input_files * sizeof ( AVInputFile ) ) ;
2001-08-14 00:43:02 +03:00
if ( ! file_table )
goto fail ;
2005-12-17 20:14:38 +02:00
2001-07-22 17:37:44 +03:00
/* input stream init */
j = 0 ;
for ( i = 0 ; i < nb_input_files ; i + + ) {
is = input_files [ i ] ;
file_table [ i ] . ist_index = j ;
2002-05-20 19:32:49 +03:00
file_table [ i ] . nb_streams = is - > nb_streams ;
2001-07-22 17:37:44 +03:00
j + = is - > nb_streams ;
}
nb_istreams = j ;
ist_table = av_mallocz ( nb_istreams * sizeof ( AVInputStream * ) ) ;
if ( ! ist_table )
2001-08-14 00:43:02 +03:00
goto fail ;
2005-12-17 20:14:38 +02:00
2001-07-22 17:37:44 +03:00
for ( i = 0 ; i < nb_istreams ; i + + ) {
ist = av_mallocz ( sizeof ( AVInputStream ) ) ;
if ( ! ist )
goto fail ;
ist_table [ i ] = ist ;
}
j = 0 ;
for ( i = 0 ; i < nb_input_files ; i + + ) {
is = input_files [ i ] ;
for ( k = 0 ; k < is - > nb_streams ; k + + ) {
ist = ist_table [ j + + ] ;
ist - > st = is - > streams [ k ] ;
ist - > file_index = i ;
ist - > index = k ;
ist - > discard = 1 ; /* the stream is discarded by default
( changed later ) */
2003-03-07 14:37:49 +02:00
2008-11-27 23:38:42 +02:00
if ( rate_emu ) {
2003-03-07 14:37:49 +02:00
ist - > start = av_gettime ( ) ;
}
2001-07-22 17:37:44 +03:00
}
}
/* output stream init */
nb_ostreams = 0 ;
for ( i = 0 ; i < nb_output_files ; i + + ) {
os = output_files [ i ] ;
2010-12-27 09:46:44 +02:00
if ( ! os - > nb_streams & & ! ( os - > oformat - > flags & AVFMT_NOSTREAMS ) ) {
2011-02-16 10:52:35 +02:00
av_dump_format ( output_files [ i ] , i , output_files [ i ] - > filename , 1 ) ;
2008-11-18 01:27:05 +02:00
fprintf ( stderr , " Output file #%d does not contain any stream \n " , i ) ;
2010-07-18 21:20:41 +03:00
ret = AVERROR ( EINVAL ) ;
goto fail ;
2006-11-05 22:08:26 +02:00
}
2001-07-22 17:37:44 +03:00
nb_ostreams + = os - > nb_streams ;
}
if ( nb_stream_maps > 0 & & nb_stream_maps ! = nb_ostreams ) {
fprintf ( stderr , " Number of stream maps must match number of output streams \n " ) ;
2010-07-18 21:20:41 +03:00
ret = AVERROR ( EINVAL ) ;
goto fail ;
2001-07-22 17:37:44 +03:00
}
2003-05-05 23:39:24 +03:00
/* Sanity check the mapping args -- do the input files & streams exist? */
for ( i = 0 ; i < nb_stream_maps ; i + + ) {
int fi = stream_maps [ i ] . file_index ;
int si = stream_maps [ i ] . stream_index ;
2005-12-17 20:14:38 +02:00
2003-05-05 23:39:24 +03:00
if ( fi < 0 | | fi > nb_input_files - 1 | |
si < 0 | | si > file_table [ fi ] . nb_streams - 1 ) {
fprintf ( stderr , " Could not find input stream #%d.%d \n " , fi , si ) ;
2010-07-18 21:20:41 +03:00
ret = AVERROR ( EINVAL ) ;
goto fail ;
2003-05-05 23:39:24 +03:00
}
2005-05-26 11:59:05 +03:00
fi = stream_maps [ i ] . sync_file_index ;
si = stream_maps [ i ] . sync_stream_index ;
if ( fi < 0 | | fi > nb_input_files - 1 | |
si < 0 | | si > file_table [ fi ] . nb_streams - 1 ) {
fprintf ( stderr , " Could not find sync stream #%d.%d \n " , fi , si ) ;
2010-07-18 21:20:41 +03:00
ret = AVERROR ( EINVAL ) ;
goto fail ;
2005-05-26 11:59:05 +03:00
}
2003-05-05 23:39:24 +03:00
}
2005-12-17 20:14:38 +02:00
2001-07-22 17:37:44 +03:00
ost_table = av_mallocz ( sizeof ( AVOutputStream * ) * nb_ostreams ) ;
if ( ! ost_table )
goto fail ;
2011-04-02 17:09:47 +03:00
for ( k = 0 ; k < nb_output_files ; k + + ) {
os = output_files [ k ] ;
for ( i = 0 ; i < os - > nb_streams ; i + + , n + + ) {
nb_streams [ os - > streams [ i ] - > codec - > codec_type ] + + ;
}
}
for ( step = 1 < < 30 ; step ; step > > = 1 ) {
int found_streams [ AVMEDIA_TYPE_NB ] = { 0 } ;
for ( j = 0 ; j < AVMEDIA_TYPE_NB ; j + + )
nb_frame_threshold [ j ] + = step ;
for ( j = 0 ; j < nb_istreams ; j + + ) {
int skip = 0 ;
ist = ist_table [ j ] ;
if ( opt_programid ) {
int pi , si ;
AVFormatContext * f = input_files [ ist - > file_index ] ;
skip = 1 ;
for ( pi = 0 ; pi < f - > nb_programs ; pi + + ) {
AVProgram * p = f - > programs [ pi ] ;
if ( p - > id = = opt_programid )
for ( si = 0 ; si < p - > nb_stream_indexes ; si + + ) {
if ( f - > streams [ p - > stream_index [ si ] ] = = ist - > st )
skip = 0 ;
}
}
}
if ( ist - > discard & & ist - > st - > discard ! = AVDISCARD_ALL & & ! skip
& & nb_frame_threshold [ ist - > st - > codec - > codec_type ] < = ist - > st - > codec_info_nb_frames ) {
found_streams [ ist - > st - > codec - > codec_type ] + + ;
}
}
for ( j = 0 ; j < AVMEDIA_TYPE_NB ; j + + )
if ( found_streams [ j ] < nb_streams [ j ] )
nb_frame_threshold [ j ] - = step ;
}
2001-07-22 17:37:44 +03:00
n = 0 ;
for ( k = 0 ; k < nb_output_files ; k + + ) {
os = output_files [ k ] ;
2008-08-27 21:50:46 +03:00
for ( i = 0 ; i < os - > nb_streams ; i + + , n + + ) {
2001-07-22 17:37:44 +03:00
int found ;
2010-10-16 13:06:10 +03:00
ost = ost_table [ n ] = output_streams_for_file [ k ] [ i ] ;
2001-07-22 17:37:44 +03:00
ost - > st = os - > streams [ i ] ;
if ( nb_stream_maps > 0 ) {
2008-08-27 21:50:46 +03:00
ost - > source_index = file_table [ stream_maps [ n ] . file_index ] . ist_index +
stream_maps [ n ] . stream_index ;
2005-12-17 20:14:38 +02:00
2003-05-05 23:39:24 +03:00
/* Sanity check that the stream types match */
2005-07-18 01:24:36 +03:00
if ( ist_table [ ost - > source_index ] - > st - > codec - > codec_type ! = ost - > st - > codec - > codec_type ) {
2008-07-29 00:54:12 +03:00
int i = ost - > file_index ;
2011-02-16 10:52:35 +02:00
av_dump_format ( output_files [ i ] , i , output_files [ i ] - > filename , 1 ) ;
2003-05-05 23:39:24 +03:00
fprintf ( stderr , " Codec type mismatch for mapping #%d.%d -> #%d.%d \n " ,
2008-08-27 21:50:46 +03:00
stream_maps [ n ] . file_index , stream_maps [ n ] . stream_index ,
2003-05-05 23:39:24 +03:00
ost - > file_index , ost - > index ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2003-05-05 23:39:24 +03:00
}
2005-12-17 20:14:38 +02:00
2001-07-22 17:37:44 +03:00
} else {
2010-08-24 03:46:32 +03:00
/* get corresponding input stream index : we select the first one with the right type */
found = 0 ;
for ( j = 0 ; j < nb_istreams ; j + + ) {
int skip = 0 ;
ist = ist_table [ j ] ;
if ( opt_programid ) {
int pi , si ;
AVFormatContext * f = input_files [ ist - > file_index ] ;
skip = 1 ;
for ( pi = 0 ; pi < f - > nb_programs ; pi + + ) {
AVProgram * p = f - > programs [ pi ] ;
if ( p - > id = = opt_programid )
for ( si = 0 ; si < p - > nb_stream_indexes ; si + + ) {
if ( f - > streams [ p - > stream_index [ si ] ] = = ist - > st )
skip = 0 ;
}
2010-02-23 17:08:41 +02:00
}
2010-08-24 03:46:32 +03:00
}
if ( ist - > discard & & ist - > st - > discard ! = AVDISCARD_ALL & & ! skip & &
2011-04-02 17:09:47 +03:00
ist - > st - > codec - > codec_type = = ost - > st - > codec - > codec_type & &
nb_frame_threshold [ ist - > st - > codec - > codec_type ] < = ist - > st - > codec_info_nb_frames ) {
2010-08-24 03:46:32 +03:00
ost - > source_index = j ;
found = 1 ;
2011-04-02 17:09:47 +03:00
break ;
2001-07-22 17:37:44 +03:00
}
2010-08-24 03:46:32 +03:00
}
2007-10-27 21:50:08 +03:00
if ( ! found ) {
if ( ! opt_programid ) {
/* try again and reuse existing stream */
for ( j = 0 ; j < nb_istreams ; j + + ) {
ist = ist_table [ j ] ;
2010-02-23 17:08:41 +02:00
if ( ist - > st - > codec - > codec_type = = ost - > st - > codec - > codec_type
& & ist - > st - > discard ! = AVDISCARD_ALL ) {
2007-10-27 21:50:08 +03:00
ost - > source_index = j ;
found = 1 ;
}
}
2007-10-27 21:46:25 +03:00
}
2001-07-22 17:37:44 +03:00
if ( ! found ) {
2008-06-13 01:07:17 +03:00
int i = ost - > file_index ;
2011-02-16 10:52:35 +02:00
av_dump_format ( output_files [ i ] , i , output_files [ i ] - > filename , 1 ) ;
2001-07-22 17:37:44 +03:00
fprintf ( stderr , " Could not find input stream matching output stream #%d.%d \n " ,
ost - > file_index , ost - > index ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2001-07-22 17:37:44 +03:00
}
}
}
ist = ist_table [ ost - > source_index ] ;
ist - > discard = 0 ;
2005-05-26 11:59:05 +03:00
ost - > sync_ist = ( nb_stream_maps > 0 ) ?
2008-08-27 21:50:46 +03:00
ist_table [ file_table [ stream_maps [ n ] . sync_file_index ] . ist_index +
stream_maps [ n ] . sync_stream_index ] : ist ;
2001-07-22 17:37:44 +03:00
}
}
/* for each output stream, we compute the right encoding parameters */
for ( i = 0 ; i < nb_ostreams ; i + + ) {
ost = ost_table [ i ] ;
2007-08-04 19:03:39 +03:00
os = output_files [ ost - > file_index ] ;
2001-07-22 17:37:44 +03:00
ist = ist_table [ ost - > source_index ] ;
2005-07-18 01:24:36 +03:00
codec = ost - > st - > codec ;
icodec = ist - > st - > codec ;
2001-07-22 17:37:44 +03:00
2010-11-02 08:12:54 +02:00
if ( metadata_streams_autocopy )
2011-01-14 21:30:55 +02:00
av_metadata_copy ( & ost - > st - > metadata , ist - > st - > metadata ,
AV_METADATA_DONT_OVERWRITE ) ;
2007-07-25 22:39:27 +03:00
2008-03-07 21:25:09 +02:00
ost - > st - > disposition = ist - > st - > disposition ;
2009-04-24 02:30:16 +03:00
codec - > bits_per_raw_sample = icodec - > bits_per_raw_sample ;
2009-05-12 03:47:19 +03:00
codec - > chroma_sample_location = icodec - > chroma_sample_location ;
2008-03-07 21:25:09 +02:00
2002-10-11 12:19:34 +03:00
if ( ost - > st - > stream_copy ) {
2010-06-08 22:27:29 +03:00
uint64_t extra_size = ( uint64_t ) icodec - > extradata_size + FF_INPUT_BUFFER_PADDING_SIZE ;
if ( extra_size > INT_MAX )
goto fail ;
2002-10-11 12:19:34 +03:00
/* if stream_copy is selected, no need to decode or encode */
codec - > codec_id = icodec - > codec_id ;
codec - > codec_type = icodec - > codec_type ;
2007-08-04 19:03:39 +03:00
if ( ! codec - > codec_tag ) {
if ( ! os - > oformat - > codec_tag
2009-12-25 23:01:16 +02:00
| | av_codec_get_id ( os - > oformat - > codec_tag , icodec - > codec_tag ) = = codec - > codec_id
2007-08-04 19:03:39 +03:00
| | av_codec_get_tag ( os - > oformat - > codec_tag , icodec - > codec_id ) < = 0 )
codec - > codec_tag = icodec - > codec_tag ;
}
2002-10-11 12:19:34 +03:00
codec - > bit_rate = icodec - > bit_rate ;
2010-10-07 04:57:35 +03:00
codec - > rc_max_rate = icodec - > rc_max_rate ;
codec - > rc_buffer_size = icodec - > rc_buffer_size ;
2010-06-08 22:27:29 +03:00
codec - > extradata = av_mallocz ( extra_size ) ;
if ( ! codec - > extradata )
goto fail ;
memcpy ( codec - > extradata , icodec - > extradata , icodec - > extradata_size ) ;
2005-03-24 03:47:45 +02:00
codec - > extradata_size = icodec - > extradata_size ;
2011-01-18 17:02:15 +02:00
if ( ! copy_tb & & av_q2d ( icodec - > time_base ) * icodec - > ticks_per_frame > av_q2d ( ist - > st - > time_base ) & & av_q2d ( ist - > st - > time_base ) < 1.0 / 500 ) {
2006-10-31 02:39:02 +02:00
codec - > time_base = icodec - > time_base ;
2009-02-27 01:47:32 +02:00
codec - > time_base . num * = icodec - > ticks_per_frame ;
2010-07-03 13:12:22 +03:00
av_reduce ( & codec - > time_base . num , & codec - > time_base . den ,
codec - > time_base . num , codec - > time_base . den , INT_MAX ) ;
2009-02-27 01:47:32 +02:00
} else
2006-10-31 02:39:02 +02:00
codec - > time_base = ist - > st - > time_base ;
2002-10-11 12:19:34 +03:00
switch ( codec - > codec_type ) {
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_AUDIO :
2008-07-12 14:43:21 +03:00
if ( audio_volume ! = 256 ) {
fprintf ( stderr , " -acodec copy and -vol are incompatible (frames are not decoded) \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2008-07-12 14:43:21 +03:00
}
2008-11-29 21:32:42 +02:00
codec - > channel_layout = icodec - > channel_layout ;
2002-10-11 12:19:34 +03:00
codec - > sample_rate = icodec - > sample_rate ;
codec - > channels = icodec - > channels ;
2004-04-01 22:16:24 +03:00
codec - > frame_size = icodec - > frame_size ;
2011-03-24 18:00:21 +02:00
codec - > audio_service_type = icodec - > audio_service_type ;
2004-12-20 14:55:40 +02:00
codec - > block_align = icodec - > block_align ;
2007-08-04 02:23:42 +03:00
if ( codec - > block_align = = 1 & & codec - > codec_id = = CODEC_ID_MP3 )
codec - > block_align = 0 ;
2008-05-26 03:47:49 +03:00
if ( codec - > codec_id = = CODEC_ID_AC3 )
codec - > block_align = 0 ;
2002-10-11 12:19:34 +03:00
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_VIDEO :
2006-02-13 17:36:13 +02:00
codec - > pix_fmt = icodec - > pix_fmt ;
2002-10-11 12:19:34 +03:00
codec - > width = icodec - > width ;
codec - > height = icodec - > height ;
2005-03-22 20:15:55 +02:00
codec - > has_b_frames = icodec - > has_b_frames ;
2011-04-17 02:47:24 +03:00
if ( ! codec - > sample_aspect_ratio . num ) {
codec - > sample_aspect_ratio =
ost - > st - > sample_aspect_ratio =
ist - > st - > sample_aspect_ratio . num ? ist - > st - > sample_aspect_ratio :
ist - > st - > codec - > sample_aspect_ratio . num ?
ist - > st - > codec - > sample_aspect_ratio : ( AVRational ) { 0 , 1 } ;
}
2002-10-11 12:19:34 +03:00
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_SUBTITLE :
2009-01-18 01:54:27 +02:00
codec - > width = icodec - > width ;
codec - > height = icodec - > height ;
2005-06-03 17:31:45 +03:00
break ;
2011-04-14 14:32:36 +03:00
case AVMEDIA_TYPE_DATA :
break ;
2002-10-11 12:19:34 +03:00
default :
2007-07-02 10:43:23 +03:00
abort ( ) ;
2002-10-11 12:19:34 +03:00
}
} else {
switch ( codec - > codec_type ) {
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_AUDIO :
2009-03-08 16:16:55 +02:00
ost - > fifo = av_fifo_alloc ( 1024 ) ;
if ( ! ost - > fifo )
2001-07-22 17:37:44 +03:00
goto fail ;
2010-11-12 13:04:40 +02:00
ost - > reformat_pair = MAKE_SFMT_PAIR ( AV_SAMPLE_FMT_NONE , AV_SAMPLE_FMT_NONE ) ;
2007-12-15 09:04:17 +02:00
ost - > audio_resample = codec - > sample_rate ! = icodec - > sample_rate | | audio_sync_method > 1 ;
icodec - > request_channels = codec - > channels ;
2001-07-22 17:37:44 +03:00
ist - > decoding_needed = 1 ;
ost - > encoding_needed = 1 ;
2010-12-12 18:18:50 +02:00
ost - > resample_sample_fmt = icodec - > sample_fmt ;
ost - > resample_sample_rate = icodec - > sample_rate ;
ost - > resample_channels = icodec - > channels ;
2002-10-11 12:19:34 +03:00
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_VIDEO :
2009-06-12 11:15:37 +03:00
if ( ost - > st - > codec - > pix_fmt = = PIX_FMT_NONE ) {
2010-03-16 17:48:48 +02:00
fprintf ( stderr , " Video pixel format is unknown, stream cannot be encoded \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-06-12 11:15:37 +03:00
}
2011-04-17 00:18:22 +03:00
ost - > video_resample = codec - > width ! = icodec - > width | |
codec - > height ! = icodec - > height | |
codec - > pix_fmt ! = icodec - > pix_fmt ;
2006-04-20 15:57:19 +03:00
if ( ost - > video_resample ) {
2011-04-03 03:14:00 +03:00
codec - > bits_per_raw_sample = frame_bits_per_raw_sample ;
2001-07-22 17:37:44 +03:00
}
2010-10-18 16:34:46 +03:00
ost - > resample_height = icodec - > height ;
ost - > resample_width = icodec - > width ;
2009-12-04 18:20:00 +02:00
ost - > resample_pix_fmt = icodec - > pix_fmt ;
2001-07-22 17:37:44 +03:00
ost - > encoding_needed = 1 ;
ist - > decoding_needed = 1 ;
2010-05-07 12:43:21 +03:00
# if CONFIG_AVFILTER
2011-04-03 22:54:57 +03:00
if ( configure_video_filters ( ist , ost ) ) {
2010-05-07 12:43:21 +03:00
fprintf ( stderr , " Error opening filters! \n " ) ;
exit ( 1 ) ;
}
# endif
2002-10-11 12:19:34 +03:00
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_SUBTITLE :
2005-06-03 17:31:45 +03:00
ost - > encoding_needed = 1 ;
ist - > decoding_needed = 1 ;
break ;
2002-10-11 12:19:34 +03:00
default :
2007-07-02 10:43:23 +03:00
abort ( ) ;
2005-06-03 17:31:45 +03:00
break ;
2001-07-22 17:37:44 +03:00
}
2002-10-11 12:19:34 +03:00
/* two pass mode */
2011-04-21 01:46:20 +03:00
if ( ost - > encoding_needed & & codec - > codec_id ! = CODEC_ID_H264 & &
2002-10-11 12:19:34 +03:00
( codec - > flags & ( CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2 ) ) ) {
char logfilename [ 1024 ] ;
FILE * f ;
2005-12-17 20:14:38 +02:00
snprintf ( logfilename , sizeof ( logfilename ) , " %s-%d.log " ,
2008-12-26 21:28:42 +02:00
pass_logfilename_prefix ? pass_logfilename_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX ,
i ) ;
2002-10-11 12:19:34 +03:00
if ( codec - > flags & CODEC_FLAG_PASS1 ) {
2010-05-23 00:32:57 +03:00
f = fopen ( logfilename , " wb " ) ;
2002-10-11 12:19:34 +03:00
if ( ! f ) {
2008-12-01 10:35:07 +02:00
fprintf ( stderr , " Cannot write log file '%s' for pass-1 encoding: %s \n " , logfilename , strerror ( errno ) ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2002-10-11 12:19:34 +03:00
}
ost - > logfile = f ;
} else {
2010-04-02 01:34:22 +03:00
char * logbuffer ;
size_t logbuffer_size ;
if ( read_file ( logfilename , & logbuffer , & logbuffer_size ) < 0 ) {
fprintf ( stderr , " Error reading log file '%s' for pass-2 encoding \n " , logfilename ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2002-10-11 12:19:34 +03:00
}
codec - > stats_in = logbuffer ;
2002-10-10 20:09:01 +03:00
}
}
}
2010-03-31 02:30:55 +03:00
if ( codec - > codec_type = = AVMEDIA_TYPE_VIDEO ) {
2011-04-01 15:11:52 +03:00
/* maximum video buffer size is 6-bytes per pixel, plus DPX header size */
2004-11-27 19:46:30 +02:00
int size = codec - > width * codec - > height ;
2011-04-01 15:11:52 +03:00
bit_buffer_size = FFMAX ( bit_buffer_size , 6 * size + 1664 ) ;
2004-11-27 19:46:30 +02:00
}
2001-07-22 17:37:44 +03:00
}
2004-11-27 19:46:30 +02:00
if ( ! bit_buffer )
bit_buffer = av_malloc ( bit_buffer_size ) ;
2009-03-11 08:06:18 +02:00
if ( ! bit_buffer ) {
2009-06-15 02:14:54 +03:00
fprintf ( stderr , " Cannot allocate %d bytes output buffer \n " ,
bit_buffer_size ) ;
2009-03-11 08:06:18 +02:00
ret = AVERROR ( ENOMEM ) ;
2004-11-27 19:46:30 +02:00
goto fail ;
2002-10-11 12:19:34 +03:00
}
2001-07-22 17:37:44 +03:00
/* open each encoder */
for ( i = 0 ; i < nb_ostreams ; i + + ) {
ost = ost_table [ i ] ;
if ( ost - > encoding_needed ) {
2010-10-02 00:51:12 +03:00
AVCodec * codec = i < nb_output_codecs ? output_codecs [ i ] : NULL ;
2010-11-13 15:57:49 +02:00
AVCodecContext * dec = ist_table [ ost - > source_index ] - > st - > codec ;
2008-10-08 20:27:45 +03:00
if ( ! codec )
2008-10-08 20:28:49 +03:00
codec = avcodec_find_encoder ( ost - > st - > codec - > codec_id ) ;
2001-07-22 17:37:44 +03:00
if ( ! codec ) {
2009-06-21 04:59:05 +03:00
snprintf ( error , sizeof ( error ) , " Encoder (codec id %d) not found for output stream #%d.%d " ,
ost - > st - > codec - > codec_id , ost - > file_index , ost - > index ) ;
2009-03-11 08:06:18 +02:00
ret = AVERROR ( EINVAL ) ;
goto dump_format ;
2001-07-22 17:37:44 +03:00
}
2010-11-13 15:57:49 +02:00
if ( dec - > subtitle_header ) {
ost - > st - > codec - > subtitle_header = av_malloc ( dec - > subtitle_header_size ) ;
if ( ! ost - > st - > codec - > subtitle_header ) {
ret = AVERROR ( ENOMEM ) ;
goto dump_format ;
}
memcpy ( ost - > st - > codec - > subtitle_header , dec - > subtitle_header , dec - > subtitle_header_size ) ;
ost - > st - > codec - > subtitle_header_size = dec - > subtitle_header_size ;
}
2005-07-18 01:24:36 +03:00
if ( avcodec_open ( ost - > st - > codec , codec ) < 0 ) {
2009-06-21 04:59:05 +03:00
snprintf ( error , sizeof ( error ) , " Error while opening encoder for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height " ,
2001-07-22 17:37:44 +03:00
ost - > file_index , ost - > index ) ;
2009-03-11 08:06:18 +02:00
ret = AVERROR ( EINVAL ) ;
goto dump_format ;
2001-07-22 17:37:44 +03:00
}
2005-07-18 01:24:36 +03:00
extra_size + = ost - > st - > codec - > extradata_size ;
2001-07-22 17:37:44 +03:00
}
}
/* open each decoder */
for ( i = 0 ; i < nb_istreams ; i + + ) {
ist = ist_table [ i ] ;
if ( ist - > decoding_needed ) {
2010-10-02 00:41:27 +03:00
AVCodec * codec = i < nb_input_codecs ? input_codecs [ i ] : NULL ;
2008-10-08 20:27:45 +03:00
if ( ! codec )
2008-10-08 20:28:49 +03:00
codec = avcodec_find_decoder ( ist - > st - > codec - > codec_id ) ;
2001-07-22 17:37:44 +03:00
if ( ! codec ) {
2009-06-21 04:59:05 +03:00
snprintf ( error , sizeof ( error ) , " Decoder (codec id %d) not found for input stream #%d.%d " ,
2005-07-18 01:24:36 +03:00
ist - > st - > codec - > codec_id , ist - > file_index , ist - > index ) ;
2009-03-11 08:06:18 +02:00
ret = AVERROR ( EINVAL ) ;
goto dump_format ;
2001-07-22 17:37:44 +03:00
}
2005-07-18 01:24:36 +03:00
if ( avcodec_open ( ist - > st - > codec , codec ) < 0 ) {
2009-06-21 04:59:05 +03:00
snprintf ( error , sizeof ( error ) , " Error while opening decoder for input stream #%d.%d " ,
2001-07-22 17:37:44 +03:00
ist - > file_index , ist - > index ) ;
2009-03-11 08:06:18 +02:00
ret = AVERROR ( EINVAL ) ;
goto dump_format ;
2001-07-22 17:37:44 +03:00
}
2010-03-31 02:30:55 +03:00
//if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
2005-07-18 01:24:36 +03:00
// ist->st->codec->flags |= CODEC_FLAG_REPEAT_FIELD;
2001-07-22 17:37:44 +03:00
}
}
/* init pts */
for ( i = 0 ; i < nb_istreams ; i + + ) {
2010-02-24 00:06:36 +02:00
AVStream * st ;
2001-07-22 17:37:44 +03:00
ist = ist_table [ i ] ;
2010-02-24 00:06:36 +02:00
st = ist - > st ;
ist - > pts = st - > avg_frame_rate . num ? - st - > codec - > has_b_frames * AV_TIME_BASE / av_q2d ( st - > avg_frame_rate ) : 0 ;
2008-02-17 22:12:44 +02:00
ist - > next_pts = AV_NOPTS_VALUE ;
2004-06-30 20:53:05 +03:00
ist - > is_start = 1 ;
2001-07-22 17:37:44 +03:00
}
2010-02-03 00:23:09 +02:00
2004-07-21 04:35:32 +03:00
/* set meta data information from input file if required */
for ( i = 0 ; i < nb_meta_data_maps ; i + + ) {
2010-11-02 08:01:28 +02:00
AVFormatContext * files [ 2 ] ;
AVMetadata * * meta [ 2 ] ;
int j ;
2004-07-21 04:35:32 +03:00
2010-11-02 08:01:28 +02:00
# define METADATA_CHECK_INDEX(index, nb_elems, desc)\
if ( ( index ) < 0 | | ( index ) > = ( nb_elems ) ) { \
snprintf ( error , sizeof ( error ) , " Invalid %s index %d while processing metadata maps \n " , \
( desc ) , ( index ) ) ; \
ret = AVERROR ( EINVAL ) ; \
goto dump_format ; \
2005-12-17 20:14:38 +02:00
}
2010-11-02 08:01:28 +02:00
int out_file_index = meta_data_maps [ i ] [ 0 ] . file ;
int in_file_index = meta_data_maps [ i ] [ 1 ] . file ;
2010-11-08 08:47:41 +02:00
if ( in_file_index < 0 | | out_file_index < 0 )
continue ;
2010-11-02 08:01:28 +02:00
METADATA_CHECK_INDEX ( out_file_index , nb_output_files , " output file " )
METADATA_CHECK_INDEX ( in_file_index , nb_input_files , " input file " )
2004-07-21 04:35:32 +03:00
2010-11-02 08:01:28 +02:00
files [ 0 ] = output_files [ out_file_index ] ;
files [ 1 ] = input_files [ in_file_index ] ;
for ( j = 0 ; j < 2 ; j + + ) {
AVMetaDataMap * map = & meta_data_maps [ i ] [ j ] ;
switch ( map - > type ) {
case ' g ' :
meta [ j ] = & files [ j ] - > metadata ;
break ;
case ' s ' :
METADATA_CHECK_INDEX ( map - > index , files [ j ] - > nb_streams , " stream " )
meta [ j ] = & files [ j ] - > streams [ map - > index ] - > metadata ;
break ;
case ' c ' :
METADATA_CHECK_INDEX ( map - > index , files [ j ] - > nb_chapters , " chapter " )
meta [ j ] = & files [ j ] - > chapters [ map - > index ] - > metadata ;
break ;
case ' p ' :
METADATA_CHECK_INDEX ( map - > index , files [ j ] - > nb_programs , " program " )
meta [ j ] = & files [ j ] - > programs [ map - > index ] - > metadata ;
break ;
}
}
2009-03-01 16:54:22 +02:00
2011-01-14 21:30:55 +02:00
av_metadata_copy ( meta [ 0 ] , * meta [ 1 ] , AV_METADATA_DONT_OVERWRITE ) ;
2004-07-21 04:35:32 +03:00
}
2005-12-17 20:14:38 +02:00
2010-11-22 09:32:23 +02:00
/* copy global metadata by default */
if ( metadata_global_autocopy ) {
2011-01-14 21:31:20 +02:00
for ( i = 0 ; i < nb_output_files ; i + + )
2011-01-14 21:30:55 +02:00
av_metadata_copy ( & output_files [ i ] - > metadata , input_files [ 0 ] - > metadata ,
AV_METADATA_DONT_OVERWRITE ) ;
2010-11-22 09:32:23 +02:00
}
2010-11-12 08:56:19 +02:00
/* copy chapters according to chapter maps */
for ( i = 0 ; i < nb_chapter_maps ; i + + ) {
int infile = chapter_maps [ i ] . in_file ;
int outfile = chapter_maps [ i ] . out_file ;
if ( infile < 0 | | outfile < 0 )
continue ;
if ( infile > = nb_input_files ) {
snprintf ( error , sizeof ( error ) , " Invalid input file index %d in chapter mapping. \n " , infile ) ;
ret = AVERROR ( EINVAL ) ;
goto dump_format ;
}
if ( outfile > = nb_output_files ) {
snprintf ( error , sizeof ( error ) , " Invalid output file index %d in chapter mapping. \n " , outfile ) ;
ret = AVERROR ( EINVAL ) ;
goto dump_format ;
}
copy_chapters ( infile , outfile ) ;
}
2010-03-19 09:44:38 +02:00
/* copy chapters from the first input file that has them*/
2010-11-12 08:56:19 +02:00
if ( ! nb_chapter_maps )
2010-11-12 08:56:23 +02:00
for ( i = 0 ; i < nb_input_files ; i + + ) {
if ( ! input_files [ i ] - > nb_chapters )
continue ;
2010-03-19 09:44:38 +02:00
2010-11-12 08:56:23 +02:00
for ( j = 0 ; j < nb_output_files ; j + + )
if ( ( ret = copy_chapters ( i , j ) ) < 0 )
goto dump_format ;
2010-11-12 08:56:26 +02:00
break ;
2010-11-12 08:56:23 +02:00
}
2010-03-19 09:44:38 +02:00
2001-07-22 17:37:44 +03:00
/* open files and write file headers */
for ( i = 0 ; i < nb_output_files ; i + + ) {
os = output_files [ i ] ;
2002-05-20 19:32:49 +03:00
if ( av_write_header ( os ) < 0 ) {
2009-03-11 08:06:18 +02:00
snprintf ( error , sizeof ( error ) , " Could not write header for output file #%d (incorrect codec parameters ?) " , i ) ;
2007-02-13 20:26:14 +02:00
ret = AVERROR ( EINVAL ) ;
2009-03-11 08:06:18 +02:00
goto dump_format ;
2001-09-25 02:22:25 +03:00
}
2007-08-20 11:12:08 +03:00
if ( strcmp ( output_files [ i ] - > oformat - > name , " rtp " ) ) {
want_sdp = 0 ;
}
}
2009-03-11 08:06:18 +02:00
dump_format :
/* dump the file output parameters - cannot be done before in case
of stream copy */
for ( i = 0 ; i < nb_output_files ; i + + ) {
2011-02-16 10:52:35 +02:00
av_dump_format ( output_files [ i ] , i , output_files [ i ] - > filename , 1 ) ;
2009-03-11 08:06:18 +02:00
}
/* dump the stream mapping */
if ( verbose > = 0 ) {
fprintf ( stderr , " Stream mapping: \n " ) ;
for ( i = 0 ; i < nb_ostreams ; i + + ) {
ost = ost_table [ i ] ;
fprintf ( stderr , " Stream #%d.%d -> #%d.%d " ,
ist_table [ ost - > source_index ] - > file_index ,
ist_table [ ost - > source_index ] - > index ,
ost - > file_index ,
ost - > index ) ;
if ( ost - > sync_ist ! = ist_table [ ost - > source_index ] )
fprintf ( stderr , " [sync #%d.%d] " ,
ost - > sync_ist - > file_index ,
ost - > sync_ist - > index ) ;
fprintf ( stderr , " \n " ) ;
}
}
if ( ret ) {
fprintf ( stderr , " %s \n " , error ) ;
goto fail ;
}
2007-08-20 11:12:08 +03:00
if ( want_sdp ) {
print_sdp ( output_files , nb_output_files ) ;
2001-07-22 17:37:44 +03:00
}
2011-03-07 18:23:32 +02:00
if ( ! using_stdin ) {
if ( verbose > = 0 )
2011-05-14 16:51:47 +03:00
fprintf ( stderr , " Press [q] to stop, [?] for help \n " ) ;
2011-04-04 21:15:44 +03:00
avio_set_interrupt_cb ( decode_interrupt_cb ) ;
2004-03-14 21:40:43 +02:00
}
2001-09-25 02:22:25 +03:00
term_init ( ) ;
2007-03-16 18:13:54 +02:00
timer_start = av_gettime ( ) ;
2002-05-09 04:06:59 +03:00
2003-08-29 23:51:10 +03:00
for ( ; received_sigterm = = 0 ; ) {
2001-07-22 17:37:44 +03:00
int file_index , ist_index ;
AVPacket pkt ;
2004-07-25 03:22:20 +03:00
double ipts_min ;
double opts_min ;
2004-06-30 01:56:54 +03:00
2001-07-22 17:37:44 +03:00
redo :
2004-07-25 03:22:20 +03:00
ipts_min = 1e100 ;
opts_min = 1e100 ;
2001-09-25 02:22:25 +03:00
/* if 'q' pressed, exits */
2003-08-29 23:51:10 +03:00
if ( ! using_stdin ) {
2004-03-14 21:40:43 +02:00
if ( q_pressed )
break ;
2002-05-30 05:38:57 +03:00
/* read_key() returns 0 on EOF */
key = read_key ( ) ;
if ( key = = ' q ' )
break ;
2011-05-14 03:54:28 +03:00
if ( key = = ' + ' ) verbose + + ;
if ( key = = ' - ' ) verbose - - ;
if ( key = = ' s ' ) qp_hist ^ = 1 ;
if ( key = = ' h ' ) {
if ( do_hex_dump ) {
do_hex_dump = do_pkt_dump = 0 ;
} else if ( do_pkt_dump ) {
do_hex_dump = 1 ;
} else
do_pkt_dump = 1 ;
av_log_set_level ( AV_LOG_DEBUG ) ;
}
2011-05-15 02:39:04 +03:00
if ( key = = ' d ' | | key = = ' D ' ) {
int debug = 0 ;
if ( key = = ' D ' ) {
ist = ist_table [ 0 ] ;
debug = ist - > st - > codec - > debug < < 1 ;
if ( ! debug ) debug = 1 ;
while ( debug & ( FF_DEBUG_DCT_COEFF | FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE ) ) //unsupported, would just crash
debug + = debug ;
} else
scanf ( " %d " , & debug ) ;
for ( i = 0 ; i < nb_istreams ; i + + ) {
ist = ist_table [ i ] ;
ist - > st - > codec - > debug = debug ;
}
for ( i = 0 ; i < nb_ostreams ; i + + ) {
ost = ost_table [ i ] ;
ost - > st - > codec - > debug = debug ;
}
if ( debug ) av_log_set_level ( AV_LOG_DEBUG ) ;
fprintf ( stderr , " debug=%d \n " , debug ) ;
}
2011-05-14 16:51:47 +03:00
if ( key = = ' ? ' ) {
fprintf ( stderr , " key function \n "
" ? show this help \n "
" + increase verbosity \n "
" - decrease verbosity \n "
2011-05-15 02:39:04 +03:00
" D cycle through available debug modes \n "
2011-05-14 16:51:47 +03:00
" h dump packets/hex press to cycle through the 3 states \n "
" q quit \n "
" s Show QP histogram \n "
) ;
}
2002-05-30 05:38:57 +03:00
}
2001-09-25 02:22:25 +03:00
2002-10-21 20:42:47 +03:00
/* select the stream that we must read now by looking at the
smallest output pts */
2001-07-22 17:37:44 +03:00
file_index = - 1 ;
2002-10-21 20:42:47 +03:00
for ( i = 0 ; i < nb_ostreams ; i + + ) {
2004-06-30 01:56:54 +03:00
double ipts , opts ;
2002-10-21 20:42:47 +03:00
ost = ost_table [ i ] ;
os = output_files [ ost - > file_index ] ;
ist = ist_table [ ost - > source_index ] ;
2010-02-08 11:04:06 +02:00
if ( ist - > is_past_recording_time | | no_packet [ ist - > file_index ] )
2009-03-03 21:50:04 +02:00
continue ;
2005-05-01 00:43:59 +03:00
opts = ost - > st - > pts . val * av_q2d ( ost - > st - > time_base ) ;
2004-06-30 01:56:54 +03:00
ipts = ( double ) ist - > pts ;
if ( ! file_table [ ist - > file_index ] . eof_reached ) {
if ( ipts < ipts_min ) {
ipts_min = ipts ;
if ( input_sync ) file_index = ist - > file_index ;
}
if ( opts < opts_min ) {
opts_min = opts ;
if ( ! input_sync ) file_index = ist - > file_index ;
}
2001-07-22 17:37:44 +03:00
}
2005-07-18 01:24:36 +03:00
if ( ost - > frame_number > = max_frames [ ost - > st - > codec - > codec_type ] ) {
2004-11-30 18:03:29 +02:00
file_index = - 1 ;
break ;
}
2001-07-22 17:37:44 +03:00
}
/* if none, if is finished */
2002-05-09 04:06:59 +03:00
if ( file_index < 0 ) {
2009-03-03 21:50:04 +02:00
if ( no_packet_count ) {
no_packet_count = 0 ;
memset ( no_packet , 0 , sizeof ( no_packet ) ) ;
2009-03-03 22:24:58 +02:00
usleep ( 10000 ) ;
2009-03-03 21:50:04 +02:00
continue ;
}
2001-07-22 17:37:44 +03:00
break ;
2002-10-21 20:42:47 +03:00
}
2005-03-22 20:20:07 +02:00
/* finish if limit size exhausted */
2011-03-03 21:11:45 +02:00
if ( limit_filesize ! = 0 & & limit_filesize < = avio_tell ( output_files [ 0 ] - > pb ) )
2005-03-22 20:20:07 +02:00
break ;
2003-11-10 20:54:17 +02:00
/* read a frame from it and output it in the fifo */
2001-07-22 17:37:44 +03:00
is = input_files [ file_index ] ;
2009-01-22 14:04:01 +02:00
ret = av_read_frame ( is , & pkt ) ;
2009-03-20 03:23:33 +02:00
if ( ret = = AVERROR ( EAGAIN ) ) {
2009-03-03 21:50:04 +02:00
no_packet [ file_index ] = 1 ;
no_packet_count + + ;
2009-01-22 14:04:01 +02:00
continue ;
2009-03-03 21:50:04 +02:00
}
2009-01-22 14:04:01 +02:00
if ( ret < 0 ) {
2001-07-22 17:37:44 +03:00
file_table [ file_index ] . eof_reached = 1 ;
2007-07-19 03:44:47 +03:00
if ( opt_shortest )
break ;
else
continue ;
2001-07-22 17:37:44 +03:00
}
2004-01-22 21:48:28 +02:00
2009-03-03 21:50:04 +02:00
no_packet_count = 0 ;
memset ( no_packet , 0 , sizeof ( no_packet ) ) ;
2003-11-10 20:54:17 +02:00
if ( do_pkt_dump ) {
2011-02-24 10:08:07 +02:00
av_pkt_dump_log2 ( NULL , AV_LOG_DEBUG , & pkt , do_hex_dump ,
is - > streams [ pkt . stream_index ] ) ;
2003-01-11 07:05:47 +02:00
}
2002-05-20 19:32:49 +03:00
/* the following test is needed in case new streams appear
dynamically in stream : we ignore them */
if ( pkt . stream_index > = file_table [ file_index ] . nb_streams )
2002-05-26 01:25:13 +03:00
goto discard_packet ;
2001-07-22 17:37:44 +03:00
ist_index = file_table [ file_index ] . ist_index + pkt . stream_index ;
ist = ist_table [ ist_index ] ;
2002-05-26 01:25:13 +03:00
if ( ist - > discard )
goto discard_packet ;
2001-07-22 17:37:44 +03:00
2007-08-03 22:21:50 +03:00
if ( pkt . dts ! = AV_NOPTS_VALUE )
pkt . dts + = av_rescale_q ( input_files_ts_offset [ ist - > file_index ] , AV_TIME_BASE_Q , ist - > st - > time_base ) ;
if ( pkt . pts ! = AV_NOPTS_VALUE )
pkt . pts + = av_rescale_q ( input_files_ts_offset [ ist - > file_index ] , AV_TIME_BASE_Q , ist - > st - > time_base ) ;
2010-10-02 00:36:13 +03:00
if ( pkt . stream_index < nb_input_files_ts_scale [ file_index ]
& & input_files_ts_scale [ file_index ] [ pkt . stream_index ] ) {
2008-07-14 01:55:52 +03:00
if ( pkt . pts ! = AV_NOPTS_VALUE )
pkt . pts * = input_files_ts_scale [ file_index ] [ pkt . stream_index ] ;
if ( pkt . dts ! = AV_NOPTS_VALUE )
pkt . dts * = input_files_ts_scale [ file_index ] [ pkt . stream_index ] ;
}
2006-11-02 00:39:58 +02:00
// fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n", ist->next_pts, pkt.dts, input_files_ts_offset[ist->file_index], ist->st->codec->codec_type);
2008-10-09 21:28:43 +03:00
if ( pkt . dts ! = AV_NOPTS_VALUE & & ist - > next_pts ! = AV_NOPTS_VALUE
& & ( is - > iformat - > flags & AVFMT_TS_DISCONT ) ) {
2007-08-08 21:54:33 +03:00
int64_t pkt_dts = av_rescale_q ( pkt . dts , ist - > st - > time_base , AV_TIME_BASE_Q ) ;
int64_t delta = pkt_dts - ist - > next_pts ;
if ( ( FFABS ( delta ) > 1LL * dts_delta_threshold * AV_TIME_BASE | | pkt_dts + 1 < ist - > pts ) & & ! copy_ts ) {
2004-06-12 06:41:36 +03:00
input_files_ts_offset [ ist - > file_index ] - = delta ;
if ( verbose > 2 )
2005-12-12 03:56:46 +02:00
fprintf ( stderr , " timestamp discontinuity % " PRId64 " , new offset= % " PRId64 " \n " , delta , input_files_ts_offset [ ist - > file_index ] ) ;
2007-08-03 22:21:50 +03:00
pkt . dts - = av_rescale_q ( delta , AV_TIME_BASE_Q , ist - > st - > time_base ) ;
if ( pkt . pts ! = AV_NOPTS_VALUE )
pkt . pts - = av_rescale_q ( delta , AV_TIME_BASE_Q , ist - > st - > time_base ) ;
2004-06-12 06:41:36 +03:00
}
}
2010-02-02 00:08:45 +02:00
/* finish if recording time exhausted */
2010-02-26 16:46:20 +02:00
if ( recording_time ! = INT64_MAX & &
2011-05-10 18:31:32 +03:00
( pkt . pts ! = AV_NOPTS_VALUE | | pkt . dts ! = AV_NOPTS_VALUE ?
av_compare_ts ( pkt . pts , ist - > st - > time_base , recording_time + start_time , ( AVRational ) { 1 , 1000000 } )
:
av_compare_ts ( ist - > pts , AV_TIME_BASE_Q , recording_time + start_time , ( AVRational ) { 1 , 1000000 } )
) > = 0 ) {
2010-02-08 11:04:06 +02:00
ist - > is_past_recording_time = 1 ;
2010-02-02 00:08:45 +02:00
goto discard_packet ;
2010-02-08 11:04:06 +02:00
}
2010-02-02 00:08:45 +02:00
2003-10-21 13:55:24 +03:00
//fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->index, pkt.size);
2003-12-15 16:43:44 +02:00
if ( output_packet ( ist , ist_index , ost_table , nb_ostreams , & pkt ) < 0 ) {
2004-04-11 16:50:42 +03:00
if ( verbose > = 0 )
fprintf ( stderr , " Error while decoding stream #%d.%d \n " ,
ist - > file_index , ist - > index ) ;
2008-09-05 02:23:44 +03:00
if ( exit_on_error )
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2003-12-15 16:43:44 +02:00
av_free_packet ( & pkt ) ;
goto redo ;
2003-10-14 17:36:58 +03:00
}
2005-06-03 17:31:45 +03:00
2002-05-26 01:25:13 +03:00
discard_packet :
2001-07-22 17:37:44 +03:00
av_free_packet ( & pkt ) ;
2005-12-17 20:14:38 +02:00
2002-10-21 20:42:47 +03:00
/* dump report by using the output first video and audio streams */
print_report ( output_files , ost_table , nb_ostreams , 0 ) ;
2001-07-22 17:37:44 +03:00
}
2003-12-15 16:43:44 +02:00
/* at the end of stream, we must flush the decoder buffers */
for ( i = 0 ; i < nb_istreams ; i + + ) {
ist = ist_table [ i ] ;
if ( ist - > decoding_needed ) {
output_packet ( ist , i , ost_table , nb_ostreams , NULL ) ;
}
}
2001-09-25 02:22:25 +03:00
term_exit ( ) ;
2001-07-22 17:37:44 +03:00
2004-03-06 00:51:22 +02:00
/* write the trailer if needed and close file */
for ( i = 0 ; i < nb_output_files ; i + + ) {
os = output_files [ i ] ;
av_write_trailer ( os ) ;
}
2004-04-15 19:34:38 +03:00
/* dump report by using the first video and audio streams */
print_report ( output_files , ost_table , nb_ostreams , 1 ) ;
2001-07-22 17:37:44 +03:00
/* close each encoder */
for ( i = 0 ; i < nb_ostreams ; i + + ) {
ost = ost_table [ i ] ;
if ( ost - > encoding_needed ) {
2005-07-18 01:24:36 +03:00
av_freep ( & ost - > st - > codec - > stats_in ) ;
avcodec_close ( ost - > st - > codec ) ;
2001-07-22 17:37:44 +03:00
}
2011-02-15 00:02:10 +02:00
# if CONFIG_AVFILTER
avfilter_graph_free ( & ost - > graph ) ;
# endif
2001-07-22 17:37:44 +03:00
}
2005-12-17 20:14:38 +02:00
2001-07-22 17:37:44 +03:00
/* close each decoder */
for ( i = 0 ; i < nb_istreams ; i + + ) {
ist = ist_table [ i ] ;
if ( ist - > decoding_needed ) {
2005-07-18 01:24:36 +03:00
avcodec_close ( ist - > st - > codec ) ;
2001-07-22 17:37:44 +03:00
}
}
/* finished ! */
2009-03-11 08:13:14 +02:00
ret = 0 ;
2005-12-17 20:14:38 +02:00
2009-03-11 08:06:18 +02:00
fail :
2005-01-12 20:12:13 +02:00
av_freep ( & bit_buffer ) ;
2002-05-19 02:17:41 +03:00
av_free ( file_table ) ;
2001-08-14 00:43:02 +03:00
2001-07-22 17:37:44 +03:00
if ( ist_table ) {
for ( i = 0 ; i < nb_istreams ; i + + ) {
ist = ist_table [ i ] ;
2002-05-19 02:17:41 +03:00
av_free ( ist ) ;
2001-07-22 17:37:44 +03:00
}
2002-05-19 02:17:41 +03:00
av_free ( ist_table ) ;
2001-07-22 17:37:44 +03:00
}
if ( ost_table ) {
for ( i = 0 ; i < nb_ostreams ; i + + ) {
ost = ost_table [ i ] ;
if ( ost ) {
2010-06-08 22:27:29 +03:00
if ( ost - > st - > stream_copy )
av_freep ( & ost - > st - > codec - > extradata ) ;
2002-10-10 20:09:01 +03:00
if ( ost - > logfile ) {
fclose ( ost - > logfile ) ;
ost - > logfile = NULL ;
}
2009-03-08 16:16:55 +02:00
av_fifo_free ( ost - > fifo ) ; /* works even if fifo is not
2006-09-21 10:31:53 +03:00
initialized but set to zero */
2010-11-13 15:57:49 +02:00
av_freep ( & ost - > st - > codec - > subtitle_header ) ;
2011-05-06 12:30:27 +03:00
av_free ( ost - > resample_frame . data [ 0 ] ) ;
2010-10-19 00:47:15 +03:00
av_free ( ost - > forced_kf_pts ) ;
2001-07-22 17:37:44 +03:00
if ( ost - > video_resample )
2006-08-02 14:50:38 +03:00
sws_freeContext ( ost - > img_resample_ctx ) ;
2008-01-07 22:42:45 +02:00
if ( ost - > resample )
2001-07-22 17:37:44 +03:00
audio_resample_close ( ost - > resample ) ;
2008-08-03 03:37:07 +03:00
if ( ost - > reformat_ctx )
av_audio_convert_free ( ost - > reformat_ctx ) ;
2002-05-19 02:17:41 +03:00
av_free ( ost ) ;
2001-07-22 17:37:44 +03:00
}
}
2002-05-19 02:17:41 +03:00
av_free ( ost_table ) ;
2001-07-22 17:37:44 +03:00
}
return ret ;
}
2003-02-10 11:44:47 +02:00
static void opt_format ( const char * arg )
2001-07-22 17:37:44 +03:00
{
2009-10-30 11:57:34 +02:00
last_asked_format = arg ;
2001-07-22 17:37:44 +03:00
}
2008-01-02 12:22:36 +02:00
static void opt_video_rc_override_string ( const char * arg )
2002-10-15 18:07:38 +03:00
{
video_rc_override_string = arg ;
}
2008-04-22 23:17:30 +03:00
static int opt_me_threshold ( const char * opt , const char * arg )
2004-04-23 22:06:30 +03:00
{
2008-04-22 23:17:30 +03:00
me_threshold = parse_number_or_die ( opt , arg , OPT_INT64 , INT_MIN , INT_MAX ) ;
return 0 ;
2004-04-23 22:06:30 +03:00
}
2008-04-22 23:17:30 +03:00
static int opt_verbose ( const char * opt , const char * arg )
2003-09-03 15:13:43 +03:00
{
2008-05-25 23:34:50 +03:00
verbose = parse_number_or_die ( opt , arg , OPT_INT64 , - 10 , 10 ) ;
2008-04-22 23:17:30 +03:00
return 0 ;
2003-09-03 15:13:43 +03:00
}
2008-08-23 15:07:48 +03:00
static int opt_frame_rate ( const char * opt , const char * arg )
2001-07-22 17:37:44 +03:00
{
2010-07-27 02:12:28 +03:00
if ( av_parse_video_rate ( & frame_rate , arg ) < 0 ) {
2008-08-23 15:07:48 +03:00
fprintf ( stderr , " Incorrect value for %s: %s \n " , opt , arg ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2003-07-12 10:37:05 +03:00
}
2008-08-23 15:07:48 +03:00
return 0 ;
2001-07-22 17:37:44 +03:00
}
2008-01-02 12:24:36 +02:00
static int opt_bitrate ( const char * opt , const char * arg )
2007-11-04 04:03:36 +02:00
{
2010-03-31 02:30:55 +03:00
int codec_type = opt [ 0 ] = = ' a ' ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO ;
2007-11-04 04:03:36 +02:00
opt_default ( opt , arg ) ;
2009-03-04 01:32:10 +02:00
if ( av_get_int ( avcodec_opts [ codec_type ] , " b " , NULL ) < 1000 )
2007-11-04 04:03:36 +02:00
fprintf ( stderr , " WARNING: The bitrate parameter is set too low. It takes bits/s as argument, not kbits/s \n " ) ;
2008-01-02 12:24:36 +02:00
return 0 ;
2007-11-04 04:03:36 +02:00
}
2010-10-18 16:34:46 +03:00
static int opt_frame_crop ( const char * opt , const char * arg )
2002-09-01 10:19:38 +03:00
{
2010-10-18 16:34:46 +03:00
fprintf ( stderr , " Option '%s' has been removed, use the crop filter instead \n " , opt ) ;
return AVERROR ( EINVAL ) ;
2002-09-01 10:19:38 +03:00
}
2003-02-10 11:44:47 +02:00
static void opt_frame_size ( const char * arg )
2001-07-22 17:37:44 +03:00
{
2010-07-27 02:12:28 +03:00
if ( av_parse_video_size ( & frame_width , & frame_height , arg ) < 0 ) {
2001-07-22 17:37:44 +03:00
fprintf ( stderr , " Incorrect frame size \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2001-07-22 17:37:44 +03:00
}
}
2010-07-04 23:59:02 +03:00
static int opt_pad ( const char * opt , const char * arg ) {
fprintf ( stderr , " Option '%s' has been removed, use the pad filter instead \n " , opt ) ;
return - 1 ;
2004-04-08 21:54:40 +03:00
}
2003-05-07 22:01:45 +03:00
static void opt_frame_pix_fmt ( const char * arg )
{
2009-03-20 00:29:32 +02:00
if ( strcmp ( arg , " list " ) ) {
2010-01-30 21:10:26 +02:00
frame_pix_fmt = av_get_pix_fmt ( arg ) ;
2009-03-20 00:29:32 +02:00
if ( frame_pix_fmt = = PIX_FMT_NONE ) {
fprintf ( stderr , " Unknown pixel format requested: %s \n " , arg ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-03-20 00:29:32 +02:00
}
} else {
2010-02-03 21:55:45 +02:00
show_pix_fmts ( ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 0 ) ;
2007-05-30 17:20:55 +03:00
}
2003-05-07 22:01:45 +03:00
}
2003-04-29 22:46:08 +03:00
static void opt_frame_aspect_ratio ( const char * arg )
{
int x = 0 , y = 0 ;
double ar = 0 ;
const char * p ;
2008-02-02 02:54:37 +02:00
char * end ;
2005-12-17 20:14:38 +02:00
2003-04-29 22:46:08 +03:00
p = strchr ( arg , ' : ' ) ;
if ( p ) {
2008-02-02 02:54:37 +02:00
x = strtol ( arg , & end , 10 ) ;
if ( end = = p )
y = strtol ( end + 1 , & end , 10 ) ;
2005-12-22 03:10:11 +02:00
if ( x > 0 & & y > 0 )
ar = ( double ) x / ( double ) y ;
2003-04-29 22:46:08 +03:00
} else
2008-02-02 02:54:37 +02:00
ar = strtod ( arg , NULL ) ;
2003-04-29 22:46:08 +03:00
if ( ! ar ) {
fprintf ( stderr , " Incorrect aspect ratio specification. \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2003-04-29 22:46:08 +03:00
}
frame_aspect_ratio = ar ;
}
2009-03-01 16:54:22 +02:00
static int opt_metadata ( const char * opt , const char * arg )
{
char * mid = strchr ( arg , ' = ' ) ;
if ( ! mid ) {
fprintf ( stderr , " Missing = \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-03-01 16:54:22 +02:00
}
* mid + + = 0 ;
2010-10-16 18:25:02 +03:00
av_metadata_set2 ( & metadata , arg , mid , 0 ) ;
2009-03-01 16:54:22 +02:00
return 0 ;
}
2011-04-11 14:16:07 +03:00
static int opt_qscale ( const char * opt , const char * arg )
2001-07-22 17:37:44 +03:00
{
2011-04-11 14:16:07 +03:00
video_qscale = parse_number_or_die ( opt , arg , OPT_FLOAT , 0 , 255 ) ;
if ( video_qscale < = 0 | | video_qscale > 255 ) {
2006-05-28 15:38:10 +03:00
fprintf ( stderr , " qscale must be > 0.0 and <= 255 \n " ) ;
2011-04-11 14:16:07 +03:00
return AVERROR ( EINVAL ) ;
2001-07-22 17:37:44 +03:00
}
2011-04-11 14:16:07 +03:00
return 0 ;
2001-07-22 17:37:44 +03:00
}
2011-04-11 14:16:07 +03:00
static int opt_top_field_first ( const char * opt , const char * arg )
2003-12-30 18:07:57 +02:00
{
2011-04-11 14:16:07 +03:00
top_field_first = parse_number_or_die ( opt , arg , OPT_INT , 0 , 1 ) ;
2011-05-16 22:52:35 +03:00
opt_default ( opt , arg ) ;
2011-04-11 14:16:07 +03:00
return 0 ;
2003-12-30 18:07:57 +02:00
}
2008-06-13 00:21:28 +03:00
static int opt_thread_count ( const char * opt , const char * arg )
2004-02-13 19:54:10 +02:00
{
2008-06-13 00:21:28 +03:00
thread_count = parse_number_or_die ( opt , arg , OPT_INT64 , 0 , INT_MAX ) ;
2009-01-14 01:44:16 +02:00
# if !HAVE_THREADS
2004-04-11 16:50:42 +03:00
if ( verbose > = 0 )
fprintf ( stderr , " Warning: not compiled with thread support, using thread emulation \n " ) ;
2004-02-14 00:18:33 +02:00
# endif
2008-06-13 00:21:28 +03:00
return 0 ;
2004-02-13 19:54:10 +02:00
}
2008-07-31 16:11:07 +03:00
static void opt_audio_sample_fmt ( const char * arg )
{
2011-01-14 22:58:51 +02:00
if ( strcmp ( arg , " list " ) ) {
2010-11-03 22:19:34 +02:00
audio_sample_fmt = av_get_sample_fmt ( arg ) ;
2011-01-14 22:58:51 +02:00
if ( audio_sample_fmt = = AV_SAMPLE_FMT_NONE ) {
av_log ( NULL , AV_LOG_ERROR , " Invalid sample format '%s' \n " , arg ) ;
ffmpeg_exit ( 1 ) ;
}
} else {
2011-03-12 13:44:22 +02:00
int i ;
char fmt_str [ 128 ] ;
for ( i = - 1 ; i < AV_SAMPLE_FMT_NB ; i + + )
printf ( " %s \n " , av_get_sample_fmt_string ( fmt_str , sizeof ( fmt_str ) , i ) ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 0 ) ;
2008-07-31 16:11:07 +03:00
}
}
2008-04-22 23:17:30 +03:00
static int opt_audio_rate ( const char * opt , const char * arg )
2001-07-22 17:37:44 +03:00
{
2008-04-22 23:17:30 +03:00
audio_sample_rate = parse_number_or_die ( opt , arg , OPT_INT64 , 0 , INT_MAX ) ;
return 0 ;
2001-07-22 17:37:44 +03:00
}
2008-04-22 23:17:30 +03:00
static int opt_audio_channels ( const char * opt , const char * arg )
2001-07-22 17:37:44 +03:00
{
2008-04-22 23:17:30 +03:00
audio_channels = parse_number_or_die ( opt , arg , OPT_INT64 , 0 , INT_MAX ) ;
return 0 ;
2001-07-22 17:37:44 +03:00
}
2011-04-11 14:16:07 +03:00
static int opt_video_channel ( const char * opt , const char * arg )
2003-01-23 20:44:26 +02:00
{
2011-04-11 14:16:07 +03:00
video_channel = parse_number_or_die ( opt , arg , OPT_INT64 , 0 , INT_MAX ) ;
return 0 ;
2003-01-23 20:44:26 +02:00
}
2003-06-25 13:21:45 +03:00
static void opt_video_standard ( const char * arg )
{
video_standard = av_strdup ( arg ) ;
}
2007-08-08 17:34:51 +03:00
static void opt_codec ( int * pstream_copy , char * * pcodec_name ,
2005-06-03 17:31:45 +03:00
int codec_type , const char * arg )
2001-07-22 17:37:44 +03:00
{
2007-08-08 17:34:51 +03:00
av_freep ( pcodec_name ) ;
2002-10-11 12:19:34 +03:00
if ( ! strcmp ( arg , " copy " ) ) {
2005-06-03 17:31:45 +03:00
* pstream_copy = 1 ;
2001-07-22 17:37:44 +03:00
} else {
2007-08-08 17:34:51 +03:00
* pcodec_name = av_strdup ( arg ) ;
2001-07-22 17:37:44 +03:00
}
}
2005-06-03 17:31:45 +03:00
static void opt_audio_codec ( const char * arg )
{
2010-03-31 02:30:55 +03:00
opt_codec ( & audio_stream_copy , & audio_codec_name , AVMEDIA_TYPE_AUDIO , arg ) ;
2005-06-03 17:31:45 +03:00
}
2003-02-10 11:44:47 +02:00
static void opt_video_codec ( const char * arg )
2001-07-22 17:37:44 +03:00
{
2010-03-31 02:30:55 +03:00
opt_codec ( & video_stream_copy , & video_codec_name , AVMEDIA_TYPE_VIDEO , arg ) ;
2005-06-03 17:31:45 +03:00
}
2001-07-22 17:37:44 +03:00
2005-06-03 17:31:45 +03:00
static void opt_subtitle_codec ( const char * arg )
{
2010-03-31 02:30:55 +03:00
opt_codec ( & subtitle_stream_copy , & subtitle_codec_name , AVMEDIA_TYPE_SUBTITLE , arg ) ;
2001-07-22 17:37:44 +03:00
}
2011-04-14 14:32:36 +03:00
static void opt_data_codec ( const char * arg )
{
opt_codec ( & data_stream_copy , & data_codec_name , AVMEDIA_TYPE_DATA , arg ) ;
}
2010-10-31 21:55:13 +02:00
static int opt_codec_tag ( const char * opt , const char * arg )
2009-03-11 10:14:19 +02:00
{
char * tail ;
2010-10-28 16:20:26 +03:00
uint32_t * codec_tag ;
codec_tag = ! strcmp ( opt , " atag " ) ? & audio_codec_tag :
! strcmp ( opt , " vtag " ) ? & video_codec_tag :
! strcmp ( opt , " stag " ) ? & subtitle_codec_tag : NULL ;
2010-10-31 21:55:13 +02:00
if ( ! codec_tag )
return - 1 ;
2009-03-11 10:14:19 +02:00
2010-10-28 16:20:26 +03:00
* codec_tag = strtol ( arg , & tail , 0 ) ;
if ( ! tail | | * tail )
2010-11-01 00:48:44 +02:00
* codec_tag = AV_RL32 ( arg ) ;
2010-10-31 21:55:13 +02:00
return 0 ;
2009-03-11 10:14:19 +02:00
}
2003-02-10 11:44:47 +02:00
static void opt_map ( const char * arg )
2001-07-22 17:37:44 +03:00
{
AVStreamMap * m ;
2008-02-02 02:54:37 +02:00
char * p ;
2001-07-22 17:37:44 +03:00
2010-10-02 00:52:09 +03:00
stream_maps = grow_array ( stream_maps , sizeof ( * stream_maps ) , & nb_stream_maps , nb_stream_maps + 1 ) ;
m = & stream_maps [ nb_stream_maps - 1 ] ;
2001-07-22 17:37:44 +03:00
2008-02-02 02:54:37 +02:00
m - > file_index = strtol ( arg , & p , 0 ) ;
2001-07-22 17:37:44 +03:00
if ( * p )
p + + ;
2002-05-12 02:27:14 +03:00
2008-02-02 02:54:37 +02:00
m - > stream_index = strtol ( p , & p , 0 ) ;
2005-05-26 11:59:05 +03:00
if ( * p ) {
p + + ;
2008-02-02 02:54:37 +02:00
m - > sync_file_index = strtol ( p , & p , 0 ) ;
2005-05-26 11:59:05 +03:00
if ( * p )
p + + ;
2008-02-02 02:54:37 +02:00
m - > sync_stream_index = strtol ( p , & p , 0 ) ;
2005-05-26 11:59:05 +03:00
} else {
m - > sync_file_index = m - > file_index ;
m - > sync_stream_index = m - > stream_index ;
}
2001-07-22 17:37:44 +03:00
}
2011-01-11 23:14:11 +02:00
static void parse_meta_type ( char * arg , char * type , int * index , char * * endptr )
2010-11-02 08:01:28 +02:00
{
* endptr = arg ;
if ( * arg = = ' , ' ) {
* type = * ( + + arg ) ;
switch ( * arg ) {
case ' g ' :
break ;
case ' s ' :
case ' c ' :
case ' p ' :
* index = strtol ( + + arg , endptr , 0 ) ;
break ;
default :
fprintf ( stderr , " Invalid metadata type %c. \n " , * arg ) ;
ffmpeg_exit ( 1 ) ;
}
} else
* type = ' g ' ;
}
2011-02-02 22:45:16 +02:00
static void opt_map_metadata ( const char * arg )
2004-07-21 04:35:32 +03:00
{
2010-11-02 08:01:28 +02:00
AVMetaDataMap * m , * m1 ;
2008-02-02 02:54:37 +02:00
char * p ;
2005-12-17 20:14:38 +02:00
2010-10-28 23:28:22 +03:00
meta_data_maps = grow_array ( meta_data_maps , sizeof ( * meta_data_maps ) ,
& nb_meta_data_maps , nb_meta_data_maps + 1 ) ;
2004-07-21 04:35:32 +03:00
2010-11-02 08:01:28 +02:00
m = & meta_data_maps [ nb_meta_data_maps - 1 ] [ 0 ] ;
m - > file = strtol ( arg , & p , 0 ) ;
parse_meta_type ( p , & m - > type , & m - > index , & p ) ;
2004-07-21 04:35:32 +03:00
if ( * p )
p + + ;
2010-11-02 08:01:28 +02:00
m1 = & meta_data_maps [ nb_meta_data_maps - 1 ] [ 1 ] ;
m1 - > file = strtol ( p , & p , 0 ) ;
parse_meta_type ( p , & m1 - > type , & m1 - > index , & p ) ;
2010-11-02 08:12:54 +02:00
2010-11-22 09:32:23 +02:00
if ( m - > type = = ' g ' | | m1 - > type = = ' g ' )
metadata_global_autocopy = 0 ;
2010-11-02 08:12:54 +02:00
if ( m - > type = = ' s ' | | m1 - > type = = ' s ' )
metadata_streams_autocopy = 0 ;
if ( m - > type = = ' c ' | | m1 - > type = = ' c ' )
metadata_chapters_autocopy = 0 ;
2004-07-21 04:35:32 +03:00
}
2011-02-02 22:45:16 +02:00
static void opt_map_meta_data ( const char * arg )
{
fprintf ( stderr , " -map_meta_data is deprecated and will be removed soon. "
" Use -map_metadata instead. \n " ) ;
opt_map_metadata ( arg ) ;
}
2010-11-12 08:56:19 +02:00
static void opt_map_chapters ( const char * arg )
{
AVChapterMap * c ;
char * p ;
chapter_maps = grow_array ( chapter_maps , sizeof ( * chapter_maps ) , & nb_chapter_maps ,
nb_chapter_maps + 1 ) ;
c = & chapter_maps [ nb_chapter_maps - 1 ] ;
c - > out_file = strtol ( arg , & p , 0 ) ;
if ( * p )
p + + ;
c - > in_file = strtol ( p , & p , 0 ) ;
}
2008-07-14 01:55:52 +03:00
static void opt_input_ts_scale ( const char * arg )
{
unsigned int stream ;
double scale ;
char * p ;
stream = strtol ( arg , & p , 0 ) ;
if ( * p )
p + + ;
scale = strtod ( p , & p ) ;
if ( stream > = MAX_STREAMS )
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2008-07-14 01:55:52 +03:00
2010-10-02 00:36:13 +03:00
input_files_ts_scale [ nb_input_files ] = grow_array ( input_files_ts_scale [ nb_input_files ] , sizeof ( * input_files_ts_scale [ nb_input_files ] ) , & nb_input_files_ts_scale [ nb_input_files ] , stream + 1 ) ;
2008-07-14 01:55:52 +03:00
input_files_ts_scale [ nb_input_files ] [ stream ] = scale ;
}
2008-03-22 17:12:04 +02:00
static int opt_recording_time ( const char * opt , const char * arg )
2001-07-22 17:37:44 +03:00
{
2008-03-22 17:12:04 +02:00
recording_time = parse_time_or_die ( opt , arg , 1 ) ;
return 0 ;
2001-07-22 17:37:44 +03:00
}
2008-03-22 17:12:04 +02:00
static int opt_start_time ( const char * opt , const char * arg )
2003-10-21 13:55:24 +03:00
{
2008-03-22 17:12:04 +02:00
start_time = parse_time_or_die ( opt , arg , 1 ) ;
return 0 ;
2003-10-21 13:55:24 +03:00
}
2010-06-23 01:54:39 +03:00
static int opt_recording_timestamp ( const char * opt , const char * arg )
2004-04-06 09:31:12 +03:00
{
2010-06-23 01:54:39 +03:00
recording_timestamp = parse_time_or_die ( opt , arg , 0 ) / 1000000 ;
2008-03-22 17:12:04 +02:00
return 0 ;
2004-04-06 09:31:12 +03:00
}
2008-03-22 17:12:04 +02:00
static int opt_input_ts_offset ( const char * opt , const char * arg )
2004-06-12 01:03:16 +03:00
{
2008-03-22 17:12:04 +02:00
input_ts_offset = parse_time_or_die ( opt , arg , 1 ) ;
return 0 ;
2004-06-12 01:03:16 +03:00
}
2010-06-01 01:31:51 +03:00
static enum CodecID find_codec_or_die ( const char * name , int type , int encoder , int strict )
2007-08-08 17:34:51 +03:00
{
2008-02-04 02:37:36 +02:00
const char * codec_string = encoder ? " encoder " : " decoder " ;
2007-08-08 17:34:51 +03:00
AVCodec * codec ;
if ( ! name )
return CODEC_ID_NONE ;
codec = encoder ?
avcodec_find_encoder_by_name ( name ) :
avcodec_find_decoder_by_name ( name ) ;
if ( ! codec ) {
2009-02-16 18:14:34 +02:00
fprintf ( stderr , " Unknown %s '%s' \n " , codec_string , name ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2007-08-08 17:34:51 +03:00
}
if ( codec - > type ! = type ) {
2009-02-16 18:14:34 +02:00
fprintf ( stderr , " Invalid %s type '%s' \n " , codec_string , name ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2007-08-08 17:34:51 +03:00
}
2010-06-01 01:31:51 +03:00
if ( codec - > capabilities & CODEC_CAP_EXPERIMENTAL & &
strict > FF_COMPLIANCE_EXPERIMENTAL ) {
fprintf ( stderr , " %s '%s' is experimental and might produce bad "
" results. \n Add '-strict experimental' if you want to use it. \n " ,
codec_string , codec - > name ) ;
2010-06-01 01:35:14 +03:00
codec = encoder ?
avcodec_find_encoder ( codec - > id ) :
avcodec_find_decoder ( codec - > id ) ;
if ( ! ( codec - > capabilities & CODEC_CAP_EXPERIMENTAL ) )
fprintf ( stderr , " Or use the non experimental %s '%s'. \n " ,
codec_string , codec - > name ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2010-06-01 01:31:51 +03:00
}
2007-08-08 17:34:51 +03:00
return codec - > id ;
}
2003-02-10 11:44:47 +02:00
static void opt_input_file ( const char * filename )
2001-07-22 17:37:44 +03:00
{
AVFormatContext * ic ;
AVFormatParameters params , * ap = & params ;
2009-10-30 11:57:34 +02:00
AVInputFormat * file_iformat = NULL ;
2003-03-12 17:16:19 +02:00
int err , i , ret , rfps , rfps_base ;
2004-09-20 18:49:24 +03:00
int64_t timestamp ;
2001-07-22 17:37:44 +03:00
2009-10-30 11:57:34 +02:00
if ( last_asked_format ) {
2010-03-02 02:01:16 +02:00
if ( ! ( file_iformat = av_find_input_format ( last_asked_format ) ) ) {
fprintf ( stderr , " Unknown input format: '%s' \n " , last_asked_format ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2010-03-02 02:01:16 +02:00
}
2009-10-30 11:57:34 +02:00
last_asked_format = NULL ;
}
2002-11-19 21:08:56 +02:00
if ( ! strcmp ( filename , " - " ) )
filename = " pipe: " ;
2005-12-17 20:14:38 +02:00
using_stdin | = ! strncmp ( filename , " pipe: " , 5 ) | |
2008-05-30 00:26:30 +03:00
! strcmp ( filename , " /dev/stdin " ) ;
2003-08-29 23:51:10 +03:00
2001-07-22 17:37:44 +03:00
/* get default parameters from command line */
2009-02-08 10:27:26 +02:00
ic = avformat_alloc_context ( ) ;
2009-09-12 20:22:56 +03:00
if ( ! ic ) {
print_error ( filename , AVERROR ( ENOMEM ) ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-09-12 20:22:56 +03:00
}
2006-08-27 15:14:13 +03:00
2002-05-20 19:32:49 +03:00
memset ( ap , 0 , sizeof ( * ap ) ) ;
2006-08-27 15:14:13 +03:00
ap - > prealloced_context = 1 ;
2002-05-20 19:32:49 +03:00
ap - > sample_rate = audio_sample_rate ;
ap - > channels = audio_channels ;
2007-06-18 11:08:43 +03:00
ap - > time_base . den = frame_rate . num ;
ap - > time_base . num = frame_rate . den ;
2010-05-07 15:16:23 +03:00
ap - > width = frame_width ;
ap - > height = frame_height ;
2003-05-07 22:01:45 +03:00
ap - > pix_fmt = frame_pix_fmt ;
2008-08-03 03:37:07 +03:00
// ap->sample_fmt = audio_sample_fmt; //FIXME:not implemented in libavformat
2004-10-20 07:57:09 +03:00
ap - > channel = video_channel ;
ap - > standard = video_standard ;
2002-05-20 19:32:49 +03:00
2010-09-30 02:06:51 +03:00
set_context_opts ( ic , avformat_opts , AV_OPT_FLAG_DECODING_PARAM , NULL ) ;
2007-12-19 12:56:17 +02:00
2010-06-01 01:31:51 +03:00
ic - > video_codec_id =
find_codec_or_die ( video_codec_name , AVMEDIA_TYPE_VIDEO , 0 ,
avcodec_opts [ AVMEDIA_TYPE_VIDEO ] - > strict_std_compliance ) ;
ic - > audio_codec_id =
find_codec_or_die ( audio_codec_name , AVMEDIA_TYPE_AUDIO , 0 ,
avcodec_opts [ AVMEDIA_TYPE_AUDIO ] - > strict_std_compliance ) ;
ic - > subtitle_codec_id =
find_codec_or_die ( subtitle_codec_name , AVMEDIA_TYPE_SUBTITLE , 0 ,
avcodec_opts [ AVMEDIA_TYPE_SUBTITLE ] - > strict_std_compliance ) ;
2011-04-30 22:38:40 +03:00
ic - > flags | = AVFMT_FLAG_NONBLOCK | AVFMT_FLAG_PRIV_OPT ;
2007-12-19 12:56:17 +02:00
2002-05-20 19:32:49 +03:00
/* open the input file with generic libav function */
err = av_open_input_file ( & ic , filename , file_iformat , 0 , ap ) ;
2011-04-30 22:38:40 +03:00
if ( err > = 0 ) {
set_context_opts ( ic , avformat_opts , AV_OPT_FLAG_DECODING_PARAM , NULL ) ;
err = av_demuxer_open ( ic , ap ) ;
if ( err < 0 )
avformat_free_context ( ic ) ;
}
2001-07-22 17:37:44 +03:00
if ( err < 0 ) {
2002-05-20 19:32:49 +03:00
print_error ( filename , err ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2001-07-22 17:37:44 +03:00
}
2007-10-27 21:46:25 +03:00
if ( opt_programid ) {
2010-02-23 17:08:41 +02:00
int i , j ;
int found = 0 ;
for ( i = 0 ; i < ic - > nb_streams ; i + + ) {
ic - > streams [ i ] - > discard = AVDISCARD_ALL ;
}
for ( i = 0 ; i < ic - > nb_programs ; i + + ) {
AVProgram * p = ic - > programs [ i ] ;
if ( p - > id ! = opt_programid ) {
p - > discard = AVDISCARD_ALL ;
} else {
found = 1 ;
for ( j = 0 ; j < p - > nb_stream_indexes ; j + + ) {
2010-04-03 02:08:23 +03:00
ic - > streams [ p - > stream_index [ j ] ] - > discard = AVDISCARD_DEFAULT ;
2010-02-23 17:08:41 +02:00
}
}
}
if ( ! found ) {
fprintf ( stderr , " Specified program id not found \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2010-02-23 17:08:41 +02:00
}
opt_programid = 0 ;
2007-10-27 21:46:25 +03:00
}
2005-08-15 17:22:43 +03:00
2006-07-14 00:13:49 +03:00
ic - > loop_input = loop_input ;
2002-05-20 19:32:49 +03:00
/* If not enough info to get the stream parameters, we decode the
first frames to get it . ( used in mpeg case for example ) */
ret = av_find_stream_info ( ic ) ;
2004-04-11 16:50:42 +03:00
if ( ret < 0 & & verbose > = 0 ) {
2001-07-22 17:37:44 +03:00
fprintf ( stderr , " %s: could not find codec parameters \n " , filename ) ;
2010-07-15 14:53:34 +03:00
av_close_input_file ( ic ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2001-07-22 17:37:44 +03:00
}
2004-09-20 18:49:24 +03:00
timestamp = start_time ;
/* add the stream start time */
if ( ic - > start_time ! = AV_NOPTS_VALUE )
timestamp + = ic - > start_time ;
2003-11-10 20:54:17 +02:00
/* if seeking requested, we execute it */
if ( start_time ! = 0 ) {
2004-10-11 01:05:43 +03:00
ret = av_seek_frame ( ic , - 1 , timestamp , AVSEEK_FLAG_BACKWARD ) ;
2003-11-10 20:54:17 +02:00
if ( ret < 0 ) {
2005-12-17 20:14:38 +02:00
fprintf ( stderr , " %s: could not seek to position %0.3f \n " ,
2003-11-10 20:54:17 +02:00
filename , ( double ) timestamp / AV_TIME_BASE ) ;
}
/* reset seek info */
start_time = 0 ;
}
2001-07-22 17:37:44 +03:00
/* update the current parameters so that they match the one of the input stream */
for ( i = 0 ; i < ic - > nb_streams ; i + + ) {
2009-12-14 05:23:45 +02:00
AVStream * st = ic - > streams [ i ] ;
2010-07-25 13:42:00 +03:00
AVCodecContext * dec = st - > codec ;
2011-02-08 04:15:45 +02:00
dec - > thread_count = thread_count ;
2010-10-02 00:41:27 +03:00
input_codecs = grow_array ( input_codecs , sizeof ( * input_codecs ) , & nb_input_codecs , nb_input_codecs + 1 ) ;
2010-07-25 13:42:00 +03:00
switch ( dec - > codec_type ) {
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_AUDIO :
2010-10-02 00:41:27 +03:00
input_codecs [ nb_input_codecs - 1 ] = avcodec_find_decoder_by_name ( audio_codec_name ) ;
2011-05-16 22:20:35 +03:00
if ( ! input_codecs [ nb_input_codecs - 1 ] )
input_codecs [ nb_input_codecs - 1 ] = avcodec_find_decoder ( dec - > codec_id ) ;
2010-10-02 00:41:27 +03:00
set_context_opts ( dec , avcodec_opts [ AVMEDIA_TYPE_AUDIO ] , AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM , input_codecs [ nb_input_codecs - 1 ] ) ;
2010-07-25 13:42:00 +03:00
channel_layout = dec - > channel_layout ;
audio_channels = dec - > channels ;
audio_sample_rate = dec - > sample_rate ;
audio_sample_fmt = dec - > sample_fmt ;
2005-01-22 03:48:11 +02:00
if ( audio_disable )
2009-12-14 05:23:45 +02:00
st - > discard = AVDISCARD_ALL ;
2010-09-09 23:58:13 +03:00
/* Note that av_find_stream_info can add more streams, and we
* currently have no chance of setting up lowres decoding
* early enough for them . */
if ( dec - > lowres )
audio_sample_rate > > = dec - > lowres ;
2001-07-22 17:37:44 +03:00
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_VIDEO :
2010-10-02 00:41:27 +03:00
input_codecs [ nb_input_codecs - 1 ] = avcodec_find_decoder_by_name ( video_codec_name ) ;
2011-05-16 22:20:35 +03:00
if ( ! input_codecs [ nb_input_codecs - 1 ] )
input_codecs [ nb_input_codecs - 1 ] = avcodec_find_decoder ( dec - > codec_id ) ;
2010-10-02 00:41:27 +03:00
set_context_opts ( dec , avcodec_opts [ AVMEDIA_TYPE_VIDEO ] , AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM , input_codecs [ nb_input_codecs - 1 ] ) ;
2010-07-25 13:42:00 +03:00
frame_height = dec - > height ;
frame_width = dec - > width ;
frame_pix_fmt = dec - > pix_fmt ;
2005-05-01 00:43:59 +03:00
rfps = ic - > streams [ i ] - > r_frame_rate . num ;
rfps_base = ic - > streams [ i ] - > r_frame_rate . den ;
2010-07-25 13:42:00 +03:00
if ( dec - > lowres ) {
dec - > flags | = CODEC_FLAG_EMU_EDGE ;
frame_height > > = dec - > lowres ;
frame_width > > = dec - > lowres ;
2011-01-07 12:16:00 +02:00
dec - > height = frame_height ;
dec - > width = frame_width ;
2009-12-05 19:51:00 +02:00
}
2004-04-23 22:06:30 +03:00
if ( me_threshold )
2010-07-25 13:42:00 +03:00
dec - > debug | = FF_DEBUG_MV ;
2002-11-08 20:35:39 +02:00
2010-07-25 13:42:00 +03:00
if ( dec - > time_base . den ! = rfps * dec - > ticks_per_frame | | dec - > time_base . num ! = rfps_base ) {
2004-04-11 16:50:42 +03:00
if ( verbose > = 0 )
2006-12-09 15:12:02 +02:00
fprintf ( stderr , " \n Seems stream %d codec frame rate differs from container frame rate: %2.2f (%d/%d) -> %2.2f (%d/%d) \n " ,
2010-07-25 13:42:00 +03:00
i , ( float ) dec - > time_base . den / dec - > time_base . num , dec - > time_base . den , dec - > time_base . num ,
2004-04-11 16:50:42 +03:00
2004-12-19 03:23:22 +02:00
( float ) rfps / rfps_base , rfps , rfps_base ) ;
2002-05-20 19:32:49 +03:00
}
2002-05-26 01:25:13 +03:00
/* update the current frame rate to match the stream frame rate */
2007-06-18 11:08:43 +03:00
frame_rate . num = rfps ;
frame_rate . den = rfps_base ;
2003-03-07 14:37:49 +02:00
2005-01-22 03:48:11 +02:00
if ( video_disable )
2009-12-14 05:23:45 +02:00
st - > discard = AVDISCARD_ALL ;
2005-03-17 03:25:01 +02:00
else if ( video_discard )
2009-12-14 05:23:45 +02:00
st - > discard = video_discard ;
2001-07-22 17:37:44 +03:00
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_DATA :
2003-11-10 20:54:17 +02:00
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_SUBTITLE :
2010-10-02 00:41:27 +03:00
input_codecs [ nb_input_codecs - 1 ] = avcodec_find_decoder_by_name ( subtitle_codec_name ) ;
2011-05-16 22:20:35 +03:00
if ( ! input_codecs [ nb_input_codecs - 1 ] )
input_codecs [ nb_input_codecs - 1 ] = avcodec_find_decoder ( dec - > codec_id ) ;
2007-07-25 22:47:44 +03:00
if ( subtitle_disable )
2009-12-14 05:23:45 +02:00
st - > discard = AVDISCARD_ALL ;
2005-06-03 17:31:45 +03:00
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_ATTACHMENT :
case AVMEDIA_TYPE_UNKNOWN :
2005-08-11 02:41:20 +03:00
break ;
2002-05-09 04:06:59 +03:00
default :
2007-07-02 10:43:23 +03:00
abort ( ) ;
2001-07-22 17:37:44 +03:00
}
}
2005-12-17 20:14:38 +02:00
2001-07-22 17:37:44 +03:00
input_files [ nb_input_files ] = ic ;
2004-09-20 18:49:24 +03:00
input_files_ts_offset [ nb_input_files ] = input_ts_offset - ( copy_ts ? 0 : timestamp ) ;
2001-07-22 17:37:44 +03:00
/* dump the file content */
2004-04-11 16:50:42 +03:00
if ( verbose > = 0 )
2011-02-16 10:52:35 +02:00
av_dump_format ( ic , nb_input_files , filename , 0 ) ;
2004-04-11 16:50:42 +03:00
2001-07-22 17:37:44 +03:00
nb_input_files + + ;
2003-03-07 14:37:49 +02:00
2004-10-20 07:57:09 +03:00
video_channel = 0 ;
2011-05-17 17:48:39 +03:00
top_field_first = - 1 ;
2005-12-17 20:14:38 +02:00
2007-12-21 12:08:43 +02:00
av_freep ( & video_codec_name ) ;
av_freep ( & audio_codec_name ) ;
av_freep ( & subtitle_codec_name ) ;
2011-05-07 09:55:25 +03:00
uninit_opts ( ) ;
init_opts ( ) ;
2001-07-22 17:37:44 +03:00
}
2011-04-14 14:32:36 +03:00
static void check_inputs ( int * has_video_ptr ,
int * has_audio_ptr ,
int * has_subtitle_ptr ,
int * has_data_ptr )
2001-09-17 00:47:13 +03:00
{
2011-04-14 14:32:36 +03:00
int has_video , has_audio , has_subtitle , has_data , i , j ;
2001-09-17 00:47:13 +03:00
AVFormatContext * ic ;
has_video = 0 ;
has_audio = 0 ;
2007-07-25 22:47:44 +03:00
has_subtitle = 0 ;
2011-04-14 14:32:36 +03:00
has_data = 0 ;
2001-09-17 00:47:13 +03:00
for ( j = 0 ; j < nb_input_files ; j + + ) {
ic = input_files [ j ] ;
for ( i = 0 ; i < ic - > nb_streams ; i + + ) {
2005-07-18 01:24:36 +03:00
AVCodecContext * enc = ic - > streams [ i ] - > codec ;
2001-09-17 00:47:13 +03:00
switch ( enc - > codec_type ) {
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_AUDIO :
2001-09-17 00:47:13 +03:00
has_audio = 1 ;
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_VIDEO :
2001-09-17 00:47:13 +03:00
has_video = 1 ;
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_SUBTITLE :
2007-07-25 22:47:44 +03:00
has_subtitle = 1 ;
break ;
2010-03-31 02:30:55 +03:00
case AVMEDIA_TYPE_DATA :
case AVMEDIA_TYPE_ATTACHMENT :
case AVMEDIA_TYPE_UNKNOWN :
2011-04-14 14:32:36 +03:00
has_data = 1 ;
2004-03-26 19:40:40 +02:00
break ;
2002-05-09 04:06:59 +03:00
default :
2007-07-02 10:43:23 +03:00
abort ( ) ;
2001-09-17 00:47:13 +03:00
}
}
}
* has_video_ptr = has_video ;
* has_audio_ptr = has_audio ;
2007-07-25 22:47:44 +03:00
* has_subtitle_ptr = has_subtitle ;
2011-04-14 14:32:36 +03:00
* has_data_ptr = has_data ;
2001-09-17 00:47:13 +03:00
}
2010-10-07 22:25:48 +03:00
static void new_video_stream ( AVFormatContext * oc , int file_idx )
2001-07-22 17:37:44 +03:00
{
AVStream * st ;
2010-10-16 13:06:10 +03:00
AVOutputStream * ost ;
2005-06-03 17:31:45 +03:00
AVCodecContext * video_enc ;
2011-01-11 23:16:00 +02:00
enum CodecID codec_id = CODEC_ID_NONE ;
2010-09-30 02:06:51 +03:00
AVCodec * codec = NULL ;
2005-12-17 20:14:38 +02:00
2010-10-02 00:34:59 +03:00
st = av_new_stream ( oc , oc - > nb_streams < nb_streamid_map ? streamid_map [ oc - > nb_streams ] : 0 ) ;
2005-06-03 17:31:45 +03:00
if ( ! st ) {
fprintf ( stderr , " Could not alloc stream \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2005-06-03 17:31:45 +03:00
}
2010-10-16 13:06:10 +03:00
ost = new_output_stream ( oc , file_idx ) ;
2010-09-30 02:06:51 +03:00
2010-10-02 00:51:12 +03:00
output_codecs = grow_array ( output_codecs , sizeof ( * output_codecs ) , & nb_output_codecs , nb_output_codecs + 1 ) ;
2010-09-30 02:06:51 +03:00
if ( ! video_stream_copy ) {
if ( video_codec_name ) {
codec_id = find_codec_or_die ( video_codec_name , AVMEDIA_TYPE_VIDEO , 1 ,
avcodec_opts [ AVMEDIA_TYPE_VIDEO ] - > strict_std_compliance ) ;
codec = avcodec_find_encoder_by_name ( video_codec_name ) ;
2010-10-02 00:51:12 +03:00
output_codecs [ nb_output_codecs - 1 ] = codec ;
2010-09-30 02:06:51 +03:00
} else {
codec_id = av_guess_codec ( oc - > oformat , NULL , oc - > filename , NULL , AVMEDIA_TYPE_VIDEO ) ;
codec = avcodec_find_encoder ( codec_id ) ;
}
2011-04-17 02:47:24 +03:00
ost - > frame_aspect_ratio = frame_aspect_ratio ;
frame_aspect_ratio = 0 ;
2011-03-16 22:37:41 +02:00
# if CONFIG_AVFILTER
2011-05-17 05:47:05 +03:00
ost - > avfilter = vfilters ;
2011-02-15 00:02:10 +02:00
vfilters = NULL ;
2011-03-16 22:37:41 +02:00
# endif
2010-09-30 02:06:51 +03:00
}
avcodec_get_context_defaults3 ( st - > codec , codec ) ;
2010-10-16 13:06:13 +03:00
ost - > bitstream_filters = video_bitstream_filters ;
2006-07-06 18:04:46 +03:00
video_bitstream_filters = NULL ;
2011-02-08 04:15:45 +02:00
st - > codec - > thread_count = thread_count ;
2005-12-17 20:14:38 +02:00
2005-07-18 01:24:36 +03:00
video_enc = st - > codec ;
2005-12-17 20:14:38 +02:00
2005-06-03 17:31:45 +03:00
if ( video_codec_tag )
video_enc - > codec_tag = video_codec_tag ;
2005-12-17 20:14:38 +02:00
2005-06-27 03:04:03 +03:00
if ( ( video_global_header & 1 )
2005-09-12 13:23:52 +03:00
| | ( video_global_header = = 0 & & ( oc - > oformat - > flags & AVFMT_GLOBALHEADER ) ) ) {
2005-06-03 17:31:45 +03:00
video_enc - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
2010-03-31 02:30:55 +03:00
avcodec_opts [ AVMEDIA_TYPE_VIDEO ] - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
2005-09-12 13:23:52 +03:00
}
if ( video_global_header & 2 ) {
2005-06-27 03:04:03 +03:00
video_enc - > flags2 | = CODEC_FLAG2_LOCAL_HEADER ;
2010-03-31 02:30:55 +03:00
avcodec_opts [ AVMEDIA_TYPE_VIDEO ] - > flags2 | = CODEC_FLAG2_LOCAL_HEADER ;
2005-09-12 13:23:52 +03:00
}
2005-06-27 03:04:03 +03:00
2005-06-03 17:31:45 +03:00
if ( video_stream_copy ) {
st - > stream_copy = 1 ;
2010-03-31 02:30:55 +03:00
video_enc - > codec_type = AVMEDIA_TYPE_VIDEO ;
2008-09-29 02:24:32 +03:00
video_enc - > sample_aspect_ratio =
2008-08-24 02:13:58 +03:00
st - > sample_aspect_ratio = av_d2q ( frame_aspect_ratio * frame_height / frame_width , 255 ) ;
2005-06-03 17:31:45 +03:00
} else {
2008-01-02 12:22:36 +02:00
const char * p ;
2005-06-03 17:31:45 +03:00
int i ;
2007-12-27 00:28:22 +02:00
AVRational fps = frame_rate . num ? frame_rate : ( AVRational ) { 25 , 1 } ;
2005-12-17 20:14:38 +02:00
2005-06-03 17:31:45 +03:00
video_enc - > codec_id = codec_id ;
2010-09-30 02:06:51 +03:00
set_context_opts ( video_enc , avcodec_opts [ AVMEDIA_TYPE_VIDEO ] , AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM , codec ) ;
2005-12-17 20:14:38 +02:00
2008-09-28 20:34:03 +03:00
if ( codec & & codec - > supported_framerates & & ! force_fps )
fps = codec - > supported_framerates [ av_find_nearest_q_idx ( fps , codec - > supported_framerates ) ] ;
2007-12-27 00:28:22 +02:00
video_enc - > time_base . den = fps . num ;
video_enc - > time_base . num = fps . den ;
2005-12-17 20:14:38 +02:00
2010-05-07 15:16:23 +03:00
video_enc - > width = frame_width ;
video_enc - > height = frame_height ;
2005-06-03 17:31:45 +03:00
video_enc - > pix_fmt = frame_pix_fmt ;
2011-04-03 03:14:00 +03:00
video_enc - > bits_per_raw_sample = frame_bits_per_raw_sample ;
2008-08-24 02:13:58 +03:00
st - > sample_aspect_ratio = video_enc - > sample_aspect_ratio ;
2005-06-03 17:31:45 +03:00
2010-03-30 22:37:07 +03:00
choose_pixel_fmt ( st , codec ) ;
2005-06-03 17:31:45 +03:00
2006-09-15 20:40:46 +03:00
if ( intra_only )
2005-06-03 17:31:45 +03:00
video_enc - > gop_size = 0 ;
if ( video_qscale | | same_quality ) {
video_enc - > flags | = CODEC_FLAG_QSCALE ;
2005-12-17 20:14:38 +02:00
video_enc - > global_quality =
2005-06-03 17:31:45 +03:00
st - > quality = FF_QP2LAMBDA * video_qscale ;
}
if ( intra_matrix )
video_enc - > intra_matrix = intra_matrix ;
if ( inter_matrix )
video_enc - > inter_matrix = inter_matrix ;
p = video_rc_override_string ;
for ( i = 0 ; p ; i + + ) {
int start , end , q ;
int e = sscanf ( p , " %d,%d,%d " , & start , & end , & q ) ;
if ( e ! = 3 ) {
fprintf ( stderr , " error parsing rc_override \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2005-06-03 17:31:45 +03:00
}
2005-12-17 20:14:38 +02:00
video_enc - > rc_override =
av_realloc ( video_enc - > rc_override ,
2005-06-03 17:31:45 +03:00
sizeof ( RcOverride ) * ( i + 1 ) ) ;
video_enc - > rc_override [ i ] . start_frame = start ;
video_enc - > rc_override [ i ] . end_frame = end ;
if ( q > 0 ) {
video_enc - > rc_override [ i ] . qscale = q ;
video_enc - > rc_override [ i ] . quality_factor = 1.0 ;
}
else {
video_enc - > rc_override [ i ] . qscale = 0 ;
video_enc - > rc_override [ i ] . quality_factor = - q / 100.0 ;
}
p = strchr ( p , ' / ' ) ;
if ( p ) p + + ;
}
video_enc - > rc_override_count = i ;
2007-01-22 12:01:14 +02:00
if ( ! video_enc - > rc_initial_buffer_occupancy )
video_enc - > rc_initial_buffer_occupancy = video_enc - > rc_buffer_size * 3 / 4 ;
2005-06-03 17:31:45 +03:00
video_enc - > me_threshold = me_threshold ;
video_enc - > intra_dc_precision = intra_dc_precision - 8 ;
if ( do_psnr )
video_enc - > flags | = CODEC_FLAG_PSNR ;
2005-12-17 20:14:38 +02:00
2005-06-03 17:31:45 +03:00
/* two pass mode */
if ( do_pass ) {
if ( do_pass = = 1 ) {
video_enc - > flags | = CODEC_FLAG_PASS1 ;
} else {
video_enc - > flags | = CODEC_FLAG_PASS2 ;
}
}
2010-10-19 00:47:15 +03:00
if ( forced_key_frames )
parse_forced_key_frames ( forced_key_frames , ost , video_enc ) ;
2005-06-03 17:31:45 +03:00
}
2009-12-16 14:08:01 +02:00
if ( video_language ) {
2010-04-25 17:27:42 +03:00
av_metadata_set2 ( & st - > metadata , " language " , video_language , 0 ) ;
2009-12-16 14:08:01 +02:00
av_freep ( & video_language ) ;
}
2005-06-03 17:31:45 +03:00
/* reset some key parameters */
video_disable = 0 ;
2007-08-08 17:34:51 +03:00
av_freep ( & video_codec_name ) ;
2010-10-19 00:47:15 +03:00
av_freep ( & forced_key_frames ) ;
2005-06-03 17:31:45 +03:00
video_stream_copy = 0 ;
2010-03-01 18:47:44 +02:00
frame_pix_fmt = PIX_FMT_NONE ;
2005-06-03 17:31:45 +03:00
}
2010-10-07 22:25:48 +03:00
static void new_audio_stream ( AVFormatContext * oc , int file_idx )
2005-06-03 17:31:45 +03:00
{
AVStream * st ;
2010-10-16 13:06:10 +03:00
AVOutputStream * ost ;
2010-09-30 02:06:51 +03:00
AVCodec * codec = NULL ;
2005-06-03 17:31:45 +03:00
AVCodecContext * audio_enc ;
2011-01-11 23:16:00 +02:00
enum CodecID codec_id = CODEC_ID_NONE ;
2005-12-17 20:14:38 +02:00
2010-10-02 00:34:59 +03:00
st = av_new_stream ( oc , oc - > nb_streams < nb_streamid_map ? streamid_map [ oc - > nb_streams ] : 0 ) ;
2005-06-03 17:31:45 +03:00
if ( ! st ) {
fprintf ( stderr , " Could not alloc stream \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2005-06-03 17:31:45 +03:00
}
2010-10-16 13:06:10 +03:00
ost = new_output_stream ( oc , file_idx ) ;
2010-09-30 02:06:51 +03:00
2010-10-02 00:51:12 +03:00
output_codecs = grow_array ( output_codecs , sizeof ( * output_codecs ) , & nb_output_codecs , nb_output_codecs + 1 ) ;
2010-09-30 02:06:51 +03:00
if ( ! audio_stream_copy ) {
if ( audio_codec_name ) {
codec_id = find_codec_or_die ( audio_codec_name , AVMEDIA_TYPE_AUDIO , 1 ,
avcodec_opts [ AVMEDIA_TYPE_AUDIO ] - > strict_std_compliance ) ;
codec = avcodec_find_encoder_by_name ( audio_codec_name ) ;
2010-10-02 00:51:12 +03:00
output_codecs [ nb_output_codecs - 1 ] = codec ;
2010-09-30 02:06:51 +03:00
} else {
codec_id = av_guess_codec ( oc - > oformat , NULL , oc - > filename , NULL , AVMEDIA_TYPE_AUDIO ) ;
codec = avcodec_find_encoder ( codec_id ) ;
}
}
avcodec_get_context_defaults3 ( st - > codec , codec ) ;
2006-07-06 18:04:46 +03:00
2010-10-16 13:06:13 +03:00
ost - > bitstream_filters = audio_bitstream_filters ;
2006-07-06 18:04:46 +03:00
audio_bitstream_filters = NULL ;
2011-02-08 04:15:45 +02:00
st - > codec - > thread_count = thread_count ;
2005-12-17 20:14:38 +02:00
2005-07-18 01:24:36 +03:00
audio_enc = st - > codec ;
2010-03-31 02:30:55 +03:00
audio_enc - > codec_type = AVMEDIA_TYPE_AUDIO ;
2005-12-17 20:14:38 +02:00
2005-06-03 17:31:45 +03:00
if ( audio_codec_tag )
audio_enc - > codec_tag = audio_codec_tag ;
2005-12-17 20:14:38 +02:00
2005-09-12 13:23:52 +03:00
if ( oc - > oformat - > flags & AVFMT_GLOBALHEADER ) {
2005-06-03 17:31:45 +03:00
audio_enc - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
2010-03-31 02:30:55 +03:00
avcodec_opts [ AVMEDIA_TYPE_AUDIO ] - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
2005-09-12 13:23:52 +03:00
}
2005-06-03 17:31:45 +03:00
if ( audio_stream_copy ) {
st - > stream_copy = 1 ;
audio_enc - > channels = audio_channels ;
2010-04-22 12:40:51 +03:00
audio_enc - > sample_rate = audio_sample_rate ;
2005-06-03 17:31:45 +03:00
} else {
audio_enc - > codec_id = codec_id ;
2010-09-30 02:06:51 +03:00
set_context_opts ( audio_enc , avcodec_opts [ AVMEDIA_TYPE_AUDIO ] , AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM , codec ) ;
2005-12-17 20:14:38 +02:00
2005-08-21 23:27:00 +03:00
if ( audio_qscale > QSCALE_NONE ) {
audio_enc - > flags | = CODEC_FLAG_QSCALE ;
audio_enc - > global_quality = st - > quality = FF_QP2LAMBDA * audio_qscale ;
}
2007-01-25 11:46:59 +02:00
audio_enc - > channels = audio_channels ;
2008-08-03 03:37:07 +03:00
audio_enc - > sample_fmt = audio_sample_fmt ;
2010-04-22 12:40:51 +03:00
audio_enc - > sample_rate = audio_sample_rate ;
2008-11-29 21:32:42 +02:00
audio_enc - > channel_layout = channel_layout ;
2010-11-21 22:06:22 +02:00
if ( av_get_channel_layout_nb_channels ( channel_layout ) ! = audio_channels )
2009-04-19 17:05:55 +03:00
audio_enc - > channel_layout = 0 ;
2010-03-30 22:37:07 +03:00
choose_sample_fmt ( st , codec ) ;
2010-04-22 12:40:51 +03:00
choose_sample_rate ( st , codec ) ;
2005-06-03 17:31:45 +03:00
}
2005-09-04 12:00:47 +03:00
audio_enc - > time_base = ( AVRational ) { 1 , audio_sample_rate } ;
2005-06-03 17:31:45 +03:00
if ( audio_language ) {
2010-04-25 17:27:42 +03:00
av_metadata_set2 ( & st - > metadata , " language " , audio_language , 0 ) ;
2009-12-15 22:36:14 +02:00
av_freep ( & audio_language ) ;
2005-06-03 17:31:45 +03:00
}
/* reset some key parameters */
audio_disable = 0 ;
2007-08-08 17:34:51 +03:00
av_freep ( & audio_codec_name ) ;
2005-06-03 17:31:45 +03:00
audio_stream_copy = 0 ;
}
2011-04-14 14:32:36 +03:00
static void new_data_stream ( AVFormatContext * oc , int file_idx )
{
AVStream * st ;
AVOutputStream * ost ;
AVCodec * codec = NULL ;
AVCodecContext * data_enc ;
st = av_new_stream ( oc , oc - > nb_streams < nb_streamid_map ? streamid_map [ oc - > nb_streams ] : 0 ) ;
if ( ! st ) {
fprintf ( stderr , " Could not alloc stream \n " ) ;
ffmpeg_exit ( 1 ) ;
}
ost = new_output_stream ( oc , file_idx ) ;
data_enc = st - > codec ;
output_codecs = grow_array ( output_codecs , sizeof ( * output_codecs ) , & nb_output_codecs , nb_output_codecs + 1 ) ;
if ( ! data_stream_copy ) {
fprintf ( stderr , " Data stream encoding not supported yet (only streamcopy) \n " ) ;
ffmpeg_exit ( 1 ) ;
}
avcodec_get_context_defaults3 ( st - > codec , codec ) ;
data_enc - > codec_type = AVMEDIA_TYPE_DATA ;
if ( data_codec_tag )
data_enc - > codec_tag = data_codec_tag ;
if ( oc - > oformat - > flags & AVFMT_GLOBALHEADER ) {
data_enc - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
avcodec_opts [ AVMEDIA_TYPE_DATA ] - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
}
if ( data_stream_copy ) {
st - > stream_copy = 1 ;
}
data_disable = 0 ;
av_freep ( & data_codec_name ) ;
data_stream_copy = 0 ;
}
2010-10-07 22:25:48 +03:00
static void new_subtitle_stream ( AVFormatContext * oc , int file_idx )
2005-06-03 17:31:45 +03:00
{
AVStream * st ;
2010-10-16 13:06:10 +03:00
AVOutputStream * ost ;
2010-09-30 02:06:51 +03:00
AVCodec * codec = NULL ;
2005-06-03 17:31:45 +03:00
AVCodecContext * subtitle_enc ;
2011-01-11 23:16:00 +02:00
enum CodecID codec_id = CODEC_ID_NONE ;
2005-12-17 20:14:38 +02:00
2010-10-02 00:34:59 +03:00
st = av_new_stream ( oc , oc - > nb_streams < nb_streamid_map ? streamid_map [ oc - > nb_streams ] : 0 ) ;
2005-06-03 17:31:45 +03:00
if ( ! st ) {
fprintf ( stderr , " Could not alloc stream \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2005-06-03 17:31:45 +03:00
}
2010-10-16 13:06:10 +03:00
ost = new_output_stream ( oc , file_idx ) ;
2010-09-30 02:06:51 +03:00
subtitle_enc = st - > codec ;
2010-10-02 00:51:12 +03:00
output_codecs = grow_array ( output_codecs , sizeof ( * output_codecs ) , & nb_output_codecs , nb_output_codecs + 1 ) ;
2010-09-30 02:06:51 +03:00
if ( ! subtitle_stream_copy ) {
2010-12-04 16:46:13 +02:00
if ( subtitle_codec_name ) {
codec_id = find_codec_or_die ( subtitle_codec_name , AVMEDIA_TYPE_SUBTITLE , 1 ,
2010-12-04 16:47:13 +02:00
avcodec_opts [ AVMEDIA_TYPE_SUBTITLE ] - > strict_std_compliance ) ;
codec = output_codecs [ nb_output_codecs - 1 ] = avcodec_find_encoder_by_name ( subtitle_codec_name ) ;
2010-12-04 16:46:13 +02:00
} else {
codec_id = av_guess_codec ( oc - > oformat , NULL , oc - > filename , NULL , AVMEDIA_TYPE_SUBTITLE ) ;
codec = avcodec_find_encoder ( codec_id ) ;
}
2010-09-30 02:06:51 +03:00
}
avcodec_get_context_defaults3 ( st - > codec , codec ) ;
2005-06-03 17:31:45 +03:00
2010-10-16 13:06:13 +03:00
ost - > bitstream_filters = subtitle_bitstream_filters ;
2008-01-28 23:13:40 +02:00
subtitle_bitstream_filters = NULL ;
2010-03-31 02:30:55 +03:00
subtitle_enc - > codec_type = AVMEDIA_TYPE_SUBTITLE ;
2009-03-11 10:14:19 +02:00
if ( subtitle_codec_tag )
subtitle_enc - > codec_tag = subtitle_codec_tag ;
2010-11-13 15:46:36 +02:00
if ( oc - > oformat - > flags & AVFMT_GLOBALHEADER ) {
subtitle_enc - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
avcodec_opts [ AVMEDIA_TYPE_SUBTITLE ] - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
}
2005-06-03 17:31:45 +03:00
if ( subtitle_stream_copy ) {
st - > stream_copy = 1 ;
} else {
2010-12-04 16:46:13 +02:00
subtitle_enc - > codec_id = codec_id ;
2010-09-30 02:06:51 +03:00
set_context_opts ( avcodec_opts [ AVMEDIA_TYPE_SUBTITLE ] , subtitle_enc , AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM , codec ) ;
2005-06-03 17:31:45 +03:00
}
if ( subtitle_language ) {
2010-04-25 17:27:42 +03:00
av_metadata_set2 ( & st - > metadata , " language " , subtitle_language , 0 ) ;
2009-12-15 22:36:14 +02:00
av_freep ( & subtitle_language ) ;
2005-06-03 17:31:45 +03:00
}
2007-07-25 22:47:44 +03:00
subtitle_disable = 0 ;
2007-08-08 17:34:51 +03:00
av_freep ( & subtitle_codec_name ) ;
2005-06-03 17:31:45 +03:00
subtitle_stream_copy = 0 ;
}
2010-10-06 00:05:07 +03:00
static int opt_new_stream ( const char * opt , const char * arg )
2005-06-03 17:31:45 +03:00
{
AVFormatContext * oc ;
2010-10-07 22:25:48 +03:00
int file_idx = nb_output_files - 1 ;
2005-06-03 17:31:45 +03:00
if ( nb_output_files < = 0 ) {
fprintf ( stderr , " At least one output file must be specified \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2005-06-03 17:31:45 +03:00
}
2010-10-07 22:25:48 +03:00
oc = output_files [ file_idx ] ;
2005-06-03 17:31:45 +03:00
2010-10-07 22:25:48 +03:00
if ( ! strcmp ( opt , " newvideo " ) ) new_video_stream ( oc , file_idx ) ;
else if ( ! strcmp ( opt , " newaudio " ) ) new_audio_stream ( oc , file_idx ) ;
else if ( ! strcmp ( opt , " newsubtitle " ) ) new_subtitle_stream ( oc , file_idx ) ;
2011-04-14 14:32:36 +03:00
else if ( ! strcmp ( opt , " newdata " ) ) new_data_stream ( oc , file_idx ) ;
2010-10-01 00:57:31 +03:00
else av_assert0 ( 0 ) ;
2010-10-06 00:05:07 +03:00
return 0 ;
2007-07-25 22:47:44 +03:00
}
2010-07-01 01:35:57 +03:00
/* arg format is "output-stream-index:streamid-value". */
2010-10-06 00:05:07 +03:00
static int opt_streamid ( const char * opt , const char * arg )
2010-07-01 01:35:57 +03:00
{
int idx ;
char * p ;
char idx_str [ 16 ] ;
2011-05-03 21:19:31 +03:00
av_strlcpy ( idx_str , arg , sizeof ( idx_str ) ) ;
2010-07-01 01:35:57 +03:00
p = strchr ( idx_str , ' : ' ) ;
if ( ! p ) {
fprintf ( stderr ,
" Invalid value '%s' for option '%s', required syntax is 'index:value' \n " ,
arg , opt ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2010-07-01 01:35:57 +03:00
}
* p + + = ' \0 ' ;
idx = parse_number_or_die ( opt , idx_str , OPT_INT , 0 , MAX_STREAMS - 1 ) ;
2010-10-02 00:34:59 +03:00
streamid_map = grow_array ( streamid_map , sizeof ( * streamid_map ) , & nb_streamid_map , idx + 1 ) ;
2010-07-01 01:35:57 +03:00
streamid_map [ idx ] = parse_number_or_die ( opt , p , OPT_INT , 0 , INT_MAX ) ;
2010-10-06 00:05:07 +03:00
return 0 ;
2010-07-01 01:35:57 +03:00
}
2005-06-03 17:31:45 +03:00
static void opt_output_file ( const char * filename )
{
AVFormatContext * oc ;
2011-04-14 14:32:36 +03:00
int err , use_video , use_audio , use_subtitle , use_data ;
int input_has_video , input_has_audio , input_has_subtitle , input_has_data ;
2003-01-11 07:05:47 +02:00
AVFormatParameters params , * ap = & params ;
2009-10-30 11:57:34 +02:00
AVOutputFormat * file_oformat ;
2001-07-22 17:37:44 +03:00
if ( ! strcmp ( filename , " - " ) )
filename = " pipe: " ;
2011-04-30 21:43:16 +03:00
oc = avformat_alloc_output_context ( last_asked_format , NULL , filename ) ;
last_asked_format = NULL ;
2009-09-12 20:22:56 +03:00
if ( ! oc ) {
print_error ( filename , AVERROR ( ENOMEM ) ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-09-12 20:22:56 +03:00
}
2011-04-30 21:43:16 +03:00
file_oformat = oc - > oformat ;
2001-07-22 17:37:44 +03:00
2005-12-17 20:14:38 +02:00
if ( ! strcmp ( file_oformat - > name , " ffm " ) & &
2007-06-24 14:27:12 +03:00
av_strstart ( filename , " http: " , NULL ) ) {
2001-07-22 17:37:44 +03:00
/* special case for files sent to ffserver: we get the stream
parameters from ffserver */
2008-06-13 01:30:01 +03:00
int err = read_ffserver_streams ( oc , filename ) ;
if ( err < 0 ) {
print_error ( filename , err ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2001-07-22 17:37:44 +03:00
}
} else {
2007-08-08 17:34:51 +03:00
use_video = file_oformat - > video_codec ! = CODEC_ID_NONE | | video_stream_copy | | video_codec_name ;
use_audio = file_oformat - > audio_codec ! = CODEC_ID_NONE | | audio_stream_copy | | audio_codec_name ;
use_subtitle = file_oformat - > subtitle_codec ! = CODEC_ID_NONE | | subtitle_stream_copy | | subtitle_codec_name ;
2011-04-14 14:32:36 +03:00
use_data = data_stream_copy | | data_codec_name ; /* XXX once generic data codec will be available add a ->data_codec reference and use it here */
2001-09-17 00:47:13 +03:00
2001-09-20 00:39:25 +03:00
/* disable if no corresponding type found and at least one
input file */
if ( nb_input_files > 0 ) {
2011-04-14 14:32:36 +03:00
check_inputs ( & input_has_video ,
& input_has_audio ,
& input_has_subtitle ,
& input_has_data ) ;
2001-09-20 00:39:25 +03:00
if ( ! input_has_video )
use_video = 0 ;
if ( ! input_has_audio )
use_audio = 0 ;
2007-07-25 22:47:44 +03:00
if ( ! input_has_subtitle )
use_subtitle = 0 ;
2011-04-14 14:32:36 +03:00
if ( ! input_has_data )
use_data = 0 ;
2001-09-20 00:39:25 +03:00
}
2001-09-17 00:47:13 +03:00
/* manual disable */
2010-10-16 23:57:55 +03:00
if ( audio_disable ) use_audio = 0 ;
if ( video_disable ) use_video = 0 ;
if ( subtitle_disable ) use_subtitle = 0 ;
2011-04-14 14:32:36 +03:00
if ( data_disable ) use_data = 0 ;
2001-07-22 17:37:44 +03:00
2010-10-16 23:57:55 +03:00
if ( use_video ) new_video_stream ( oc , nb_output_files ) ;
if ( use_audio ) new_audio_stream ( oc , nb_output_files ) ;
if ( use_subtitle ) new_subtitle_stream ( oc , nb_output_files ) ;
2011-04-14 14:32:36 +03:00
if ( use_data ) new_data_stream ( oc , nb_output_files ) ;
2007-07-25 22:47:44 +03:00
2010-06-23 01:54:39 +03:00
oc - > timestamp = recording_timestamp ;
2005-12-17 20:14:38 +02:00
2011-01-14 21:30:55 +02:00
av_metadata_copy ( & oc - > metadata , metadata , 0 ) ;
2010-10-16 19:16:01 +03:00
av_metadata_free ( & metadata ) ;
2001-07-22 17:37:44 +03:00
}
2002-10-11 12:19:34 +03:00
output_files [ nb_output_files + + ] = oc ;
2001-07-22 17:37:44 +03:00
2001-09-17 00:47:13 +03:00
/* check filename in case of an image number is expected */
2002-05-20 19:32:49 +03:00
if ( oc - > oformat - > flags & AVFMT_NEEDNUMBER ) {
2006-09-04 12:57:47 +03:00
if ( ! av_filename_number_test ( oc - > filename ) ) {
2011-04-11 01:29:30 +03:00
print_error ( oc - > filename , AVERROR ( EINVAL ) ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2002-05-20 19:32:49 +03:00
}
2001-09-17 00:47:13 +03:00
}
2002-05-20 19:32:49 +03:00
if ( ! ( oc - > oformat - > flags & AVFMT_NOFILE ) ) {
2001-07-22 17:37:44 +03:00
/* test if it already exists to avoid loosing precious files */
2005-12-17 20:14:38 +02:00
if ( ! file_overwrite & &
2001-07-22 17:37:44 +03:00
( strchr ( filename , ' : ' ) = = NULL | |
2007-12-25 12:06:22 +02:00
filename [ 1 ] = = ' : ' | |
2007-06-24 14:27:12 +03:00
av_strstart ( filename , " file: " , NULL ) ) ) {
2011-04-09 02:32:37 +03:00
if ( avio_check ( filename , 0 ) = = 0 ) {
2008-05-30 00:26:30 +03:00
if ( ! using_stdin ) {
2003-08-29 23:51:10 +03:00
fprintf ( stderr , " File '%s' already exists. Overwrite ? [y/N] " , filename ) ;
fflush ( stderr ) ;
2009-03-18 23:38:41 +02:00
if ( ! read_yesno ( ) ) {
2003-08-29 23:51:10 +03:00
fprintf ( stderr , " Not overwriting - exiting \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2003-08-29 23:51:10 +03:00
}
2008-05-30 00:26:30 +03:00
}
else {
2003-08-29 23:51:10 +03:00
fprintf ( stderr , " File '%s' already exists. Exiting. \n " , filename ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2008-05-30 00:26:30 +03:00
}
2001-07-22 17:37:44 +03:00
}
}
2005-12-17 20:14:38 +02:00
2001-07-22 17:37:44 +03:00
/* open the file */
2011-04-15 17:42:09 +03:00
if ( ( err = avio_open ( & oc - > pb , filename , AVIO_FLAG_WRITE ) ) < 0 ) {
2010-04-27 01:36:55 +03:00
print_error ( filename , err ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2001-07-22 17:37:44 +03:00
}
}
2003-01-11 07:05:47 +02:00
memset ( ap , 0 , sizeof ( * ap ) ) ;
if ( av_set_parameters ( oc , ap ) < 0 ) {
fprintf ( stderr , " %s: Invalid encoding parameters \n " ,
oc - > filename ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2003-01-11 07:05:47 +02:00
}
2004-10-17 00:27:42 +03:00
oc - > preload = ( int ) ( mux_preload * AV_TIME_BASE ) ;
oc - > max_delay = ( int ) ( mux_max_delay * AV_TIME_BASE ) ;
2005-06-18 04:52:24 +03:00
oc - > loop_output = loop_output ;
2004-10-07 01:29:30 +03:00
2010-09-30 02:06:51 +03:00
set_context_opts ( oc , avformat_opts , AV_OPT_FLAG_ENCODING_PARAM , NULL ) ;
2010-07-01 01:35:57 +03:00
2010-10-19 00:47:15 +03:00
av_freep ( & forced_key_frames ) ;
2011-05-07 09:55:25 +03:00
uninit_opts ( ) ;
init_opts ( ) ;
2001-07-22 17:37:44 +03:00
}
2002-10-10 20:09:01 +03:00
/* same option as mencoder */
2011-04-11 14:16:07 +03:00
static int opt_pass ( const char * opt , const char * arg )
2002-10-10 20:09:01 +03:00
{
2011-04-11 14:16:07 +03:00
do_pass = parse_number_or_die ( opt , arg , OPT_INT , 1 , 2 ) ;
return 0 ;
2002-10-10 20:09:01 +03:00
}
2001-09-25 02:22:25 +03:00
2003-02-11 18:35:48 +02:00
static int64_t getutime ( void )
2001-08-14 00:43:02 +03:00
{
2009-01-14 01:44:16 +02:00
# if HAVE_GETRUSAGE
2003-01-11 22:34:38 +02:00
struct rusage rusage ;
getrusage ( RUSAGE_SELF , & rusage ) ;
return ( rusage . ru_utime . tv_sec * 1000000LL ) + rusage . ru_utime . tv_usec ;
2009-01-14 01:44:16 +02:00
# elif HAVE_GETPROCESSTIMES
2007-07-13 19:11:36 +03:00
HANDLE proc ;
FILETIME c , e , k , u ;
proc = GetCurrentProcess ( ) ;
GetProcessTimes ( proc , & c , & e , & k , & u ) ;
return ( ( int64_t ) u . dwHighDateTime < < 32 | u . dwLowDateTime ) / 10 ;
# else
2007-08-07 03:46:36 +03:00
return av_gettime ( ) ;
2007-07-13 19:04:00 +03:00
# endif
2001-08-14 00:43:02 +03:00
}
2001-07-31 02:19:22 +03:00
2010-02-23 00:21:58 +02:00
static int64_t getmaxrss ( void )
{
# if HAVE_GETRUSAGE && HAVE_STRUCT_RUSAGE_RU_MAXRSS
struct rusage rusage ;
getrusage ( RUSAGE_SELF , & rusage ) ;
return ( int64_t ) rusage . ru_maxrss * 1024 ;
# elif HAVE_GETPROCESSMEMORYINFO
HANDLE proc ;
PROCESS_MEMORY_COUNTERS memcounters ;
proc = GetCurrentProcess ( ) ;
memcounters . cb = sizeof ( memcounters ) ;
GetProcessMemoryInfo ( proc , & memcounters , sizeof ( memcounters ) ) ;
return memcounters . PeakPagefileUsage ;
# else
return 0 ;
# endif
}
2006-01-31 01:33:19 +02:00
static void parse_matrix_coeffs ( uint16_t * dest , const char * str )
2003-10-31 12:25:21 +02:00
{
int i ;
const char * p = str ;
for ( i = 0 ; ; i + + ) {
dest [ i ] = atoi ( p ) ;
if ( i = = 63 )
break ;
p = strchr ( p , ' , ' ) ;
if ( ! p ) {
fprintf ( stderr , " Syntax error in matrix \" %s \" at coeff %d \n " , str , i ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2003-10-31 12:25:21 +02:00
}
p + + ;
}
}
2006-01-31 01:33:19 +02:00
static void opt_inter_matrix ( const char * arg )
2003-10-31 12:25:21 +02:00
{
inter_matrix = av_mallocz ( sizeof ( uint16_t ) * 64 ) ;
parse_matrix_coeffs ( inter_matrix , arg ) ;
}
2006-01-31 01:33:19 +02:00
static void opt_intra_matrix ( const char * arg )
2003-10-31 12:25:21 +02:00
{
intra_matrix = av_mallocz ( sizeof ( uint16_t ) * 64 ) ;
parse_matrix_coeffs ( intra_matrix , arg ) ;
}
2009-12-21 04:12:34 +02:00
static void show_usage ( void )
2007-11-15 14:31:58 +02:00
{
2009-12-21 04:09:17 +02:00
printf ( " Hyper fast Audio and Video encoder \n " ) ;
2009-12-21 04:10:14 +02:00
printf ( " usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}... \n " ) ;
2007-11-15 14:31:58 +02:00
printf ( " \n " ) ;
2009-12-21 04:12:34 +02:00
}
static void show_help ( void )
{
2010-12-10 20:25:02 +02:00
AVCodec * c ;
2011-01-02 18:00:47 +02:00
AVOutputFormat * oformat = NULL ;
2010-12-10 20:25:02 +02:00
2009-12-21 04:12:34 +02:00
av_log_set_callback ( log_callback_help ) ;
show_usage ( ) ;
2007-11-15 14:31:58 +02:00
show_help_options ( options , " Main options: \n " ,
2008-06-16 13:00:32 +03:00
OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE | OPT_GRAB , 0 ) ;
2008-06-17 13:11:46 +03:00
show_help_options ( options , " \n Advanced options: \n " ,
OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE | OPT_GRAB ,
OPT_EXPERT ) ;
2007-11-15 14:31:58 +02:00
show_help_options ( options , " \n Video options: \n " ,
OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB ,
OPT_VIDEO ) ;
show_help_options ( options , " \n Advanced Video options: \n " ,
OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB ,
OPT_VIDEO | OPT_EXPERT ) ;
show_help_options ( options , " \n Audio options: \n " ,
OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB ,
OPT_AUDIO ) ;
show_help_options ( options , " \n Advanced Audio options: \n " ,
OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB ,
OPT_AUDIO | OPT_EXPERT ) ;
show_help_options ( options , " \n Subtitle options: \n " ,
OPT_SUBTITLE | OPT_GRAB ,
OPT_SUBTITLE ) ;
show_help_options ( options , " \n Audio/Video grab options: \n " ,
OPT_GRAB ,
OPT_GRAB ) ;
2008-05-31 21:36:44 +03:00
printf ( " \n " ) ;
2010-09-24 03:51:40 +03:00
av_opt_show2 ( avcodec_opts [ 0 ] , NULL , AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_DECODING_PARAM , 0 ) ;
2008-05-31 21:36:44 +03:00
printf ( " \n " ) ;
2010-12-10 20:25:02 +02:00
/* individual codec options */
c = NULL ;
while ( ( c = av_codec_next ( c ) ) ) {
if ( c - > priv_class ) {
av_opt_show2 ( & c - > priv_class , NULL , AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_DECODING_PARAM , 0 ) ;
printf ( " \n " ) ;
}
}
2010-09-24 03:51:40 +03:00
av_opt_show2 ( avformat_opts , NULL , AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_DECODING_PARAM , 0 ) ;
2008-05-31 21:36:44 +03:00
printf ( " \n " ) ;
2011-01-02 18:00:47 +02:00
/* individual muxer options */
while ( ( oformat = av_oformat_next ( oformat ) ) ) {
if ( oformat - > priv_class ) {
av_opt_show2 ( & oformat - > priv_class , NULL , AV_OPT_FLAG_ENCODING_PARAM , 0 ) ;
printf ( " \n " ) ;
}
}
2010-09-24 03:51:40 +03:00
av_opt_show2 ( sws_opts , NULL , AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_DECODING_PARAM , 0 ) ;
2007-11-15 14:31:58 +02:00
}
2003-11-03 19:28:44 +02:00
static void opt_target ( const char * arg )
{
2009-12-15 01:18:49 +02:00
enum { PAL , NTSC , FILM , UNKNOWN } norm = UNKNOWN ;
2005-02-24 21:08:50 +02:00
static const char * const frame_rates [ ] = { " 25 " , " 30000/1001 " , " 24000/1001 " } ;
2003-11-03 19:28:44 +02:00
if ( ! strncmp ( arg , " pal- " , 4 ) ) {
2009-12-15 01:18:49 +02:00
norm = PAL ;
2003-11-03 19:28:44 +02:00
arg + = 4 ;
} else if ( ! strncmp ( arg , " ntsc- " , 5 ) ) {
2009-12-15 01:18:49 +02:00
norm = NTSC ;
2003-11-03 19:28:44 +02:00
arg + = 5 ;
2004-12-19 17:31:55 +02:00
} else if ( ! strncmp ( arg , " film- " , 5 ) ) {
2009-12-15 01:18:49 +02:00
norm = FILM ;
2004-12-19 17:31:55 +02:00
arg + = 5 ;
2003-11-03 19:28:44 +02:00
} else {
int fr ;
/* Calculate FR via float to avoid int overflow */
2007-06-18 11:08:43 +03:00
fr = ( int ) ( frame_rate . num * 1000.0 / frame_rate . den ) ;
2003-11-03 19:28:44 +02:00
if ( fr = = 25000 ) {
2009-12-15 01:18:49 +02:00
norm = PAL ;
2003-11-03 19:28:44 +02:00
} else if ( ( fr = = 29970 ) | | ( fr = = 23976 ) ) {
2009-12-15 01:18:49 +02:00
norm = NTSC ;
2003-11-03 19:28:44 +02:00
} else {
/* Try to determine PAL/NTSC by peeking in the input files */
if ( nb_input_files ) {
int i , j ;
for ( j = 0 ; j < nb_input_files ; j + + ) {
for ( i = 0 ; i < input_files [ j ] - > nb_streams ; i + + ) {
2005-07-18 01:24:36 +03:00
AVCodecContext * c = input_files [ j ] - > streams [ i ] - > codec ;
2010-03-31 02:30:55 +03:00
if ( c - > codec_type ! = AVMEDIA_TYPE_VIDEO )
2003-11-03 19:28:44 +02:00
continue ;
2005-05-01 00:43:59 +03:00
fr = c - > time_base . den * 1000 / c - > time_base . num ;
2003-11-03 19:28:44 +02:00
if ( fr = = 25000 ) {
2009-12-15 01:18:49 +02:00
norm = PAL ;
2003-11-03 19:28:44 +02:00
break ;
} else if ( ( fr = = 29970 ) | | ( fr = = 23976 ) ) {
2009-12-15 01:18:49 +02:00
norm = NTSC ;
2003-11-03 19:28:44 +02:00
break ;
}
}
2009-12-15 01:18:49 +02:00
if ( norm ! = UNKNOWN )
2003-11-03 19:28:44 +02:00
break ;
}
}
}
2011-04-18 14:04:33 +03:00
if ( verbose > 0 & & norm ! = UNKNOWN )
2009-12-16 01:25:16 +02:00
fprintf ( stderr , " Assuming %s for target. \n " , norm = = PAL ? " PAL " : " NTSC " ) ;
2003-11-03 19:28:44 +02:00
}
2009-12-15 01:18:49 +02:00
if ( norm = = UNKNOWN ) {
2004-12-19 17:31:55 +02:00
fprintf ( stderr , " Could not determine norm (PAL/NTSC/NTSC-Film) for target. \n " ) ;
fprintf ( stderr , " Please prefix target with \" pal- \" , \" ntsc- \" or \" film- \" , \n " ) ;
2003-11-03 19:28:44 +02:00
fprintf ( stderr , " or set a framerate with \" -r xxx \" . \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2003-11-03 19:28:44 +02:00
}
if ( ! strcmp ( arg , " vcd " ) ) {
opt_video_codec ( " mpeg1video " ) ;
opt_audio_codec ( " mp2 " ) ;
opt_format ( " vcd " ) ;
2009-12-16 01:25:16 +02:00
opt_frame_size ( norm = = PAL ? " 352x288 " : " 352x240 " ) ;
2008-08-23 15:07:48 +03:00
opt_frame_rate ( NULL , frame_rates [ norm ] ) ;
2009-12-16 01:25:16 +02:00
opt_default ( " g " , norm = = PAL ? " 15 " : " 18 " ) ;
2003-11-03 19:28:44 +02:00
2006-09-15 14:15:55 +03:00
opt_default ( " b " , " 1150000 " ) ;
2006-09-15 20:38:43 +03:00
opt_default ( " maxrate " , " 1150000 " ) ;
opt_default ( " minrate " , " 1150000 " ) ;
2006-09-18 22:27:12 +03:00
opt_default ( " bufsize " , " 327680 " ) ; // 40*1024*8;
2003-11-03 19:28:44 +02:00
2007-03-05 12:04:53 +02:00
opt_default ( " ab " , " 224000 " ) ;
2003-11-03 19:28:44 +02:00
audio_sample_rate = 44100 ;
2007-02-05 18:07:26 +02:00
audio_channels = 2 ;
2005-12-17 20:14:38 +02:00
2006-09-20 11:24:17 +03:00
opt_default ( " packetsize " , " 2324 " ) ;
2006-09-20 11:23:01 +03:00
opt_default ( " muxrate " , " 1411200 " ) ; // 2352 * 75 * 8;
2003-11-03 19:28:44 +02:00
2004-10-17 00:27:42 +03:00
/* We have to offset the PTS, so that it is consistent with the SCR.
SCR starts at 36000 , but the first two packs contain only padding
and the first pack from the other stream , respectively , may also have
been written before .
So the real data starts at SCR 36000 + 3 * 1200. */
mux_preload = ( 36000 + 3 * 1200 ) / 90000.0 ; //0.44
2003-11-03 19:28:44 +02:00
} else if ( ! strcmp ( arg , " svcd " ) ) {
opt_video_codec ( " mpeg2video " ) ;
opt_audio_codec ( " mp2 " ) ;
2004-02-20 00:34:13 +02:00
opt_format ( " svcd " ) ;
2003-11-03 19:28:44 +02:00
2009-12-16 01:25:16 +02:00
opt_frame_size ( norm = = PAL ? " 480x576 " : " 480x480 " ) ;
2008-08-23 15:07:48 +03:00
opt_frame_rate ( NULL , frame_rates [ norm ] ) ;
2009-12-16 01:25:16 +02:00
opt_default ( " g " , norm = = PAL ? " 15 " : " 18 " ) ;
2003-11-03 19:28:44 +02:00
2006-09-15 14:15:55 +03:00
opt_default ( " b " , " 2040000 " ) ;
2006-09-15 20:38:43 +03:00
opt_default ( " maxrate " , " 2516000 " ) ;
opt_default ( " minrate " , " 0 " ) ; //1145000;
2006-09-18 22:27:12 +03:00
opt_default ( " bufsize " , " 1835008 " ) ; //224*1024*8;
2008-09-13 20:25:38 +03:00
opt_default ( " flags " , " +scan_offset " ) ;
2005-09-12 13:23:52 +03:00
2003-11-03 19:28:44 +02:00
2007-03-05 12:04:53 +02:00
opt_default ( " ab " , " 224000 " ) ;
2003-11-03 19:28:44 +02:00
audio_sample_rate = 44100 ;
2006-09-20 11:24:17 +03:00
opt_default ( " packetsize " , " 2324 " ) ;
2004-10-07 01:29:30 +03:00
2003-11-03 19:28:44 +02:00
} else if ( ! strcmp ( arg , " dvd " ) ) {
opt_video_codec ( " mpeg2video " ) ;
opt_audio_codec ( " ac3 " ) ;
2004-10-03 21:21:45 +03:00
opt_format ( " dvd " ) ;
2003-11-03 19:28:44 +02:00
2009-12-16 01:25:16 +02:00
opt_frame_size ( norm = = PAL ? " 720x576 " : " 720x480 " ) ;
2008-08-23 15:07:48 +03:00
opt_frame_rate ( NULL , frame_rates [ norm ] ) ;
2009-12-16 01:25:16 +02:00
opt_default ( " g " , norm = = PAL ? " 15 " : " 18 " ) ;
2003-11-03 19:28:44 +02:00
2006-09-15 14:15:55 +03:00
opt_default ( " b " , " 6000000 " ) ;
2006-09-15 20:38:43 +03:00
opt_default ( " maxrate " , " 9000000 " ) ;
opt_default ( " minrate " , " 0 " ) ; //1500000;
2006-09-18 22:27:12 +03:00
opt_default ( " bufsize " , " 1835008 " ) ; //224*1024*8;
2003-11-03 19:28:44 +02:00
2006-09-20 11:24:17 +03:00
opt_default ( " packetsize " , " 2048 " ) ; // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
2006-09-20 11:23:01 +03:00
opt_default ( " muxrate " , " 10080000 " ) ; // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
2004-11-21 05:37:33 +02:00
2007-03-05 12:04:53 +02:00
opt_default ( " ab " , " 448000 " ) ;
2003-11-03 19:28:44 +02:00
audio_sample_rate = 48000 ;
2006-03-30 05:36:02 +03:00
} else if ( ! strncmp ( arg , " dv " , 2 ) ) {
2004-12-29 20:50:47 +02:00
opt_format ( " dv " ) ;
2009-12-25 20:32:16 +02:00
opt_frame_size ( norm = = PAL ? " 720x576 " : " 720x480 " ) ;
2006-03-30 05:36:02 +03:00
opt_frame_pix_fmt ( ! strncmp ( arg , " dv50 " , 4 ) ? " yuv422p " :
2009-12-16 01:25:16 +02:00
( norm = = PAL ? " yuv420p " : " yuv411p " ) ) ;
2008-08-23 15:07:48 +03:00
opt_frame_rate ( NULL , frame_rates [ norm ] ) ;
2004-12-29 20:50:47 +02:00
audio_sample_rate = 48000 ;
audio_channels = 2 ;
2003-11-03 19:28:44 +02:00
} else {
fprintf ( stderr , " Unknown target: %s \n " , arg ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2003-11-03 19:28:44 +02:00
}
}
2007-04-25 16:55:11 +03:00
static void opt_vstats_file ( const char * arg )
{
av_free ( vstats_filename ) ;
vstats_filename = av_strdup ( arg ) ;
}
static void opt_vstats ( void )
{
char filename [ 40 ] ;
time_t today2 = time ( NULL ) ;
struct tm * today = localtime ( & today2 ) ;
snprintf ( filename , sizeof ( filename ) , " vstats_%02d%02d%02d.log " , today - > tm_hour , today - > tm_min ,
today - > tm_sec ) ;
opt_vstats_file ( filename ) ;
}
2008-01-02 12:24:36 +02:00
static int opt_bsf ( const char * opt , const char * arg )
2006-07-06 18:04:46 +03:00
{
AVBitStreamFilterContext * bsfc = av_bitstream_filter_init ( arg ) ; //FIXME split name and args for filter at '='
AVBitStreamFilterContext * * bsfp ;
if ( ! bsfc ) {
2007-03-07 02:27:23 +02:00
fprintf ( stderr , " Unknown bitstream filter %s \n " , arg ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2006-07-06 18:04:46 +03:00
}
2008-01-28 23:13:40 +02:00
bsfp = * opt = = ' v ' ? & video_bitstream_filters :
* opt = = ' a ' ? & audio_bitstream_filters :
& subtitle_bitstream_filters ;
2006-07-06 18:04:46 +03:00
while ( * bsfp )
bsfp = & ( * bsfp ) - > next ;
* bsfp = bsfc ;
2008-01-02 12:24:36 +02:00
return 0 ;
2006-07-06 18:04:46 +03:00
}
2008-06-07 12:12:42 +03:00
static int opt_preset ( const char * opt , const char * arg )
{
2008-06-08 13:48:23 +03:00
FILE * f = NULL ;
2008-10-18 21:42:20 +03:00
char filename [ 1000 ] , tmp [ 1000 ] , tmp2 [ 1000 ] , line [ 1000 ] ;
2010-11-05 01:07:04 +02:00
char * codec_name = * opt = = ' v ' ? video_codec_name :
* opt = = ' a ' ? audio_codec_name :
subtitle_codec_name ;
2008-06-07 12:12:42 +03:00
2010-11-05 01:07:04 +02:00
if ( ! ( f = get_preset_file ( filename , sizeof ( filename ) , arg , * opt = = ' f ' , codec_name ) ) ) {
2008-10-18 21:18:52 +03:00
fprintf ( stderr , " File for preset '%s' not found \n " , arg ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2008-06-07 12:12:42 +03:00
}
while ( ! feof ( f ) ) {
2008-09-19 00:07:11 +03:00
int e = fscanf ( f , " %999[^ \n ] \n " , line ) - 1 ;
if ( line [ 0 ] = = ' # ' & & ! e )
continue ;
e | = sscanf ( line , " %999[^=]=%999[^ \n ] \n " , tmp , tmp2 ) - 2 ;
if ( e ) {
2008-11-22 00:51:17 +02:00
fprintf ( stderr , " %s: Invalid syntax: '%s' \n " , filename , line ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2008-06-07 12:12:42 +03:00
}
2008-07-09 09:56:26 +03:00
if ( ! strcmp ( tmp , " acodec " ) ) {
opt_audio_codec ( tmp2 ) ;
} else if ( ! strcmp ( tmp , " vcodec " ) ) {
opt_video_codec ( tmp2 ) ;
} else if ( ! strcmp ( tmp , " scodec " ) ) {
opt_subtitle_codec ( tmp2 ) ;
2011-04-14 14:32:36 +03:00
} else if ( ! strcmp ( tmp , " dcodec " ) ) {
opt_data_codec ( tmp2 ) ;
2008-10-18 21:27:32 +03:00
} else if ( opt_default ( tmp , tmp2 ) < 0 ) {
2008-11-22 00:56:08 +02:00
fprintf ( stderr , " %s: Invalid option or argument: '%s', parsed as '%s' = '%s' \n " , filename , line , tmp , tmp2 ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2008-10-18 21:27:32 +03:00
}
2008-06-07 12:12:42 +03:00
}
fclose ( f ) ;
return 0 ;
}
2011-04-18 14:10:52 +03:00
static void log_callback_null ( void * ptr , int level , const char * fmt , va_list vl )
{
}
2011-04-21 01:46:20 +03:00
static void opt_passlogfile ( const char * arg )
{
pass_logfilename_prefix = arg ;
opt_default ( " passlogfile " , arg ) ;
}
2008-05-01 18:12:00 +03:00
static const OptionDef options [ ] = {
2003-08-24 18:29:48 +03:00
/* main options */
2009-11-30 01:12:19 +02:00
# include "cmdutils_common_opts.h"
2001-08-14 00:43:02 +03:00
{ " f " , HAS_ARG , { ( void * ) opt_format } , " force format " , " fmt " } ,
{ " i " , HAS_ARG , { ( void * ) opt_input_file } , " input file name " , " filename " } ,
{ " y " , OPT_BOOL , { ( void * ) & file_overwrite } , " overwrite output files " } ,
2011-03-20 09:01:40 +02:00
{ " map " , HAS_ARG | OPT_EXPERT , { ( void * ) opt_map } , " set input stream mapping " , " file.stream[:syncfile.syncstream] " } ,
2011-02-02 22:45:16 +02:00
{ " map_meta_data " , HAS_ARG | OPT_EXPERT , { ( void * ) opt_map_meta_data } , " DEPRECATED set meta data information of outfile from infile " ,
" outfile[,metadata]:infile[,metadata] " } ,
{ " map_metadata " , HAS_ARG | OPT_EXPERT , { ( void * ) opt_map_metadata } , " set metadata information of outfile from infile " ,
" outfile[,metadata]:infile[,metadata] " } ,
2010-11-12 08:56:19 +02:00
{ " map_chapters " , HAS_ARG | OPT_EXPERT , { ( void * ) opt_map_chapters } , " set chapters mapping " , " outfile:infile " } ,
2008-03-22 17:12:04 +02:00
{ " t " , OPT_FUNC2 | HAS_ARG , { ( void * ) opt_recording_time } , " record or transcode \" duration \" seconds of audio/video " , " duration " } ,
2007-03-30 14:31:29 +03:00
{ " fs " , HAS_ARG | OPT_INT64 , { ( void * ) & limit_filesize } , " set the limit file size in bytes " , " limit_size " } , //
2008-03-22 17:12:04 +02:00
{ " ss " , OPT_FUNC2 | HAS_ARG , { ( void * ) opt_start_time } , " set the start time offset " , " time_off " } ,
{ " itsoffset " , OPT_FUNC2 | HAS_ARG , { ( void * ) opt_input_ts_offset } , " set the input ts offset " , " time_off " } ,
2008-07-14 01:55:52 +03:00
{ " itsscale " , HAS_ARG , { ( void * ) opt_input_ts_scale } , " set the input ts scale " , " stream:scale " } ,
2010-06-23 01:54:39 +03:00
{ " timestamp " , OPT_FUNC2 | HAS_ARG , { ( void * ) opt_recording_timestamp } , " set the recording timestamp ('now' to set the current time) " , " time " } ,
2009-04-27 10:13:50 +03:00
{ " metadata " , OPT_FUNC2 | HAS_ARG , { ( void * ) opt_metadata } , " add metadata " , " string=string " } ,
2010-03-31 02:30:55 +03:00
{ " dframes " , OPT_INT | HAS_ARG , { ( void * ) & max_frames [ AVMEDIA_TYPE_DATA ] } , " set the number of data frames to record " , " number " } ,
2005-12-17 20:14:38 +02:00
{ " benchmark " , OPT_BOOL | OPT_EXPERT , { ( void * ) & do_benchmark } ,
2001-07-31 02:19:22 +03:00
" add timings for benchmarking " } ,
2010-01-20 08:42:39 +02:00
{ " timelimit " , OPT_FUNC2 | HAS_ARG , { ( void * ) opt_timelimit } , " set max runtime in seconds " , " limit " } ,
2005-12-17 20:14:38 +02:00
{ " dump " , OPT_BOOL | OPT_EXPERT , { ( void * ) & do_pkt_dump } ,
2001-09-23 20:14:51 +03:00
" dump each input packet " } ,
2005-12-17 20:14:38 +02:00
{ " hex " , OPT_BOOL | OPT_EXPERT , { ( void * ) & do_hex_dump } ,
2003-11-10 20:54:17 +02:00
" when dumping packets, also dump the payload " } ,
2003-08-25 00:19:13 +03:00
{ " re " , OPT_BOOL | OPT_EXPERT , { ( void * ) & rate_emu } , " read input at native frame rate " , " " } ,
2006-02-28 13:32:31 +02:00
{ " loop_input " , OPT_BOOL | OPT_EXPERT , { ( void * ) & loop_input } , " loop (current only works with images) " } ,
2005-06-18 04:52:24 +03:00
{ " loop_output " , HAS_ARG | OPT_INT | OPT_EXPERT , { ( void * ) & loop_output } , " number of times to loop output in formats that support looping (0 loops forever) " , " " } ,
2009-03-15 09:23:18 +02:00
{ " v " , HAS_ARG | OPT_FUNC2 , { ( void * ) opt_verbose } , " set ffmpeg verbosity level " , " number " } ,
2006-03-30 05:36:02 +03:00
{ " target " , HAS_ARG , { ( void * ) opt_target } , " specify target file type ( \" vcd \" , \" svcd \" , \" dvd \" , \" dv \" , \" dv50 \" , \" pal-vcd \" , \" ntsc-svcd \" , ...) " , " type " } ,
2008-06-13 00:21:28 +03:00
{ " threads " , OPT_FUNC2 | HAS_ARG | OPT_EXPERT , { ( void * ) opt_thread_count } , " thread count " , " count " } ,
2004-06-30 17:47:29 +03:00
{ " vsync " , HAS_ARG | OPT_INT | OPT_EXPERT , { ( void * ) & video_sync_method } , " video sync method " , " " } ,
{ " async " , HAS_ARG | OPT_INT | OPT_EXPERT , { ( void * ) & audio_sync_method } , " audio sync method " , " " } ,
2008-04-08 04:01:00 +03:00
{ " adrift_threshold " , HAS_ARG | OPT_FLOAT | OPT_EXPERT , { ( void * ) & audio_drift_threshold } , " audio drift threshold " , " threshold " } ,
2005-06-27 03:04:03 +03:00
{ " vglobal " , HAS_ARG | OPT_INT | OPT_EXPERT , { ( void * ) & video_global_header } , " video global header storage type " , " " } ,
2004-06-12 06:41:36 +03:00
{ " copyts " , OPT_BOOL | OPT_EXPERT , { ( void * ) & copy_ts } , " copy timestamps " } ,
2011-01-15 00:01:49 +02:00
{ " copytb " , OPT_BOOL | OPT_EXPERT , { ( void * ) & copy_tb } , " copy input stream time base when stream copying " } ,
2005-03-23 02:52:31 +02:00
{ " shortest " , OPT_BOOL | OPT_EXPERT , { ( void * ) & opt_shortest } , " finish encoding within shortest input " } , //
2008-04-08 04:01:00 +03:00
{ " dts_delta_threshold " , HAS_ARG | OPT_FLOAT | OPT_EXPERT , { ( void * ) & dts_delta_threshold } , " timestamp discontinuity delta threshold " , " threshold " } ,
2007-10-27 21:46:25 +03:00
{ " programid " , HAS_ARG | OPT_INT | OPT_EXPERT , { ( void * ) & opt_programid } , " desired program number " , " " } ,
2008-09-05 02:23:44 +03:00
{ " xerror " , OPT_BOOL , { ( void * ) & exit_on_error } , " exit on error " , " error " } ,
2008-12-22 10:22:22 +02:00
{ " copyinkf " , OPT_BOOL | OPT_EXPERT , { ( void * ) & copy_initial_nonkeyframes } , " copy initial non-keyframes " } ,
2003-08-24 18:29:48 +03:00
/* video options */
2008-04-08 04:01:00 +03:00
{ " b " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO , { ( void * ) opt_bitrate } , " set bitrate (in bits/s) " , " bitrate " } ,
{ " vb " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO , { ( void * ) opt_bitrate } , " set bitrate (in bits/s) " , " bitrate " } ,
2010-03-31 02:30:55 +03:00
{ " vframes " , OPT_INT | HAS_ARG | OPT_VIDEO , { ( void * ) & max_frames [ AVMEDIA_TYPE_VIDEO ] } , " set the number of video frames to record " , " number " } ,
2008-08-23 15:07:48 +03:00
{ " r " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO , { ( void * ) opt_frame_rate } , " set frame rate (Hz value, fraction or abbreviation) " , " rate " } ,
2003-08-24 18:29:48 +03:00
{ " s " , HAS_ARG | OPT_VIDEO , { ( void * ) opt_frame_size } , " set frame size (WxH or abbreviation) " , " size " } ,
{ " aspect " , HAS_ARG | OPT_VIDEO , { ( void * ) opt_frame_aspect_ratio } , " set aspect ratio (4:3, 16:9 or 1.3333, 1.7777) " , " aspect " } ,
2007-05-30 17:20:55 +03:00
{ " pix_fmt " , HAS_ARG | OPT_EXPERT | OPT_VIDEO , { ( void * ) opt_frame_pix_fmt } , " set pixel format, 'list' as argument shows all the pixel formats supported " , " format " } ,
2011-04-03 03:14:00 +03:00
{ " bits_per_raw_sample " , OPT_INT | HAS_ARG | OPT_VIDEO , { ( void * ) & frame_bits_per_raw_sample } , " set the number of bits per raw sample " , " number " } ,
2010-10-18 16:43:07 +03:00
{ " croptop " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO , { ( void * ) opt_frame_crop } , " Removed, use the crop filter instead " , " size " } ,
{ " cropbottom " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO , { ( void * ) opt_frame_crop } , " Removed, use the crop filter instead " , " size " } ,
{ " cropleft " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO , { ( void * ) opt_frame_crop } , " Removed, use the crop filter instead " , " size " } ,
{ " cropright " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO , { ( void * ) opt_frame_crop } , " Removed, use the crop filter instead " , " size " } ,
2010-07-04 23:59:02 +03:00
{ " padtop " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO , { ( void * ) opt_pad } , " Removed, use the pad filter instead " , " size " } ,
{ " padbottom " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO , { ( void * ) opt_pad } , " Removed, use the pad filter instead " , " size " } ,
{ " padleft " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO , { ( void * ) opt_pad } , " Removed, use the pad filter instead " , " size " } ,
{ " padright " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO , { ( void * ) opt_pad } , " Removed, use the pad filter instead " , " size " } ,
{ " padcolor " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO , { ( void * ) opt_pad } , " Removed, use the pad filter instead " , " color " } ,
2003-08-24 18:29:48 +03:00
{ " intra " , OPT_BOOL | OPT_EXPERT | OPT_VIDEO , { ( void * ) & intra_only } , " use only intra frames " } ,
{ " vn " , OPT_BOOL | OPT_VIDEO , { ( void * ) & video_disable } , " disable video " } ,
2005-03-17 07:07:54 +02:00
{ " vdt " , OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO , { ( void * ) & video_discard } , " discard threshold " , " n " } ,
2011-04-11 14:16:07 +03:00
{ " qscale " , HAS_ARG | OPT_FUNC2 | OPT_EXPERT | OPT_VIDEO , { ( void * ) opt_qscale } , " use fixed video quantizer scale (VBR) " , " q " } ,
2003-08-24 19:14:24 +03:00
{ " rc_override " , HAS_ARG | OPT_EXPERT | OPT_VIDEO , { ( void * ) opt_video_rc_override_string } , " rate control override for specific intervals " , " override " } ,
2003-08-24 18:29:48 +03:00
{ " vcodec " , HAS_ARG | OPT_VIDEO , { ( void * ) opt_video_codec } , " force video codec ('copy' to copy stream) " , " codec " } ,
2008-04-22 23:17:30 +03:00
{ " me_threshold " , HAS_ARG | OPT_FUNC2 | OPT_EXPERT | OPT_VIDEO , { ( void * ) opt_me_threshold } , " motion estimaton threshold " , " threshold " } ,
2005-12-17 20:14:38 +02:00
{ " sameq " , OPT_BOOL | OPT_VIDEO , { ( void * ) & same_quality } ,
2011-03-28 23:13:44 +03:00
" use same quantizer as source (implies VBR) " } ,
2011-04-11 14:16:07 +03:00
{ " pass " , HAS_ARG | OPT_FUNC2 | OPT_VIDEO , { ( void * ) opt_pass } , " select the pass number (1 or 2) " , " n " } ,
2011-04-21 01:46:20 +03:00
{ " passlogfile " , HAS_ARG | OPT_VIDEO , { ( void * ) & opt_passlogfile } , " select two pass log file name prefix " , " prefix " } ,
2005-12-17 20:14:38 +02:00
{ " deinterlace " , OPT_BOOL | OPT_EXPERT | OPT_VIDEO , { ( void * ) & do_deinterlace } ,
2003-08-24 18:29:48 +03:00
" deinterlace pictures " } ,
{ " psnr " , OPT_BOOL | OPT_EXPERT | OPT_VIDEO , { ( void * ) & do_psnr } , " calculate PSNR of compressed frames " } ,
2007-04-25 16:55:11 +03:00
{ " vstats " , OPT_EXPERT | OPT_VIDEO , { ( void * ) & opt_vstats } , " dump video coding statistics to file " } ,
{ " vstats_file " , HAS_ARG | OPT_EXPERT | OPT_VIDEO , { ( void * ) opt_vstats_file } , " dump video coding statistics to file " , " file " } ,
2010-05-07 12:43:21 +03:00
# if CONFIG_AVFILTER
2010-05-12 04:47:14 +03:00
{ " vf " , OPT_STRING | HAS_ARG , { ( void * ) & vfilters } , " video filters " , " filter list " } ,
2010-05-07 12:43:21 +03:00
# endif
2003-10-31 12:25:21 +02:00
{ " intra_matrix " , HAS_ARG | OPT_EXPERT | OPT_VIDEO , { ( void * ) opt_intra_matrix } , " specify intra matrix coeffs " , " matrix " } ,
{ " inter_matrix " , HAS_ARG | OPT_EXPERT | OPT_VIDEO , { ( void * ) opt_inter_matrix } , " specify inter matrix coeffs " , " matrix " } ,
2011-04-11 14:16:07 +03:00
{ " top " , HAS_ARG | OPT_FUNC2 | OPT_EXPERT | OPT_VIDEO , { ( void * ) opt_top_field_first } , " top=1/bottom=0/auto=-1 field first " , " " } ,
2004-04-30 16:44:29 +03:00
{ " dc " , OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO , { ( void * ) & intra_dc_precision } , " intra_dc_precision " , " precision " } ,
2010-10-28 16:20:26 +03:00
{ " vtag " , OPT_FUNC2 | HAS_ARG | OPT_EXPERT | OPT_VIDEO , { ( void * ) opt_codec_tag } , " force video tag/fourcc " , " fourcc/tag " } ,
2010-08-24 18:48:20 +03:00
{ " newvideo " , OPT_VIDEO | OPT_FUNC2 , { ( void * ) opt_new_stream } , " add a new video stream to the current output stream " } ,
2009-12-16 14:08:01 +02:00
{ " vlang " , HAS_ARG | OPT_STRING | OPT_VIDEO , { ( void * ) & video_language } , " set the ISO 639 language code (3 letters) of the current video stream " , " code " } ,
2005-12-18 22:01:02 +02:00
{ " qphist " , OPT_BOOL | OPT_EXPERT | OPT_VIDEO , { ( void * ) & qp_hist } , " show QP histogram " } ,
2008-09-28 20:34:03 +03:00
{ " force_fps " , OPT_BOOL | OPT_EXPERT | OPT_VIDEO , { ( void * ) & force_fps } , " force the selected framerate, disable the best supported framerate selection " } ,
2010-07-01 01:35:57 +03:00
{ " streamid " , OPT_FUNC2 | HAS_ARG | OPT_EXPERT , { ( void * ) opt_streamid } , " set the value of an outfile streamid " , " streamIndex:value " } ,
2010-10-19 00:47:15 +03:00
{ " force_key_frames " , OPT_STRING | HAS_ARG | OPT_EXPERT | OPT_VIDEO , { ( void * ) & forced_key_frames } , " force key frames at specified timestamps " , " timestamps " } ,
2003-08-24 18:29:48 +03:00
/* audio options */
2008-04-08 04:01:00 +03:00
{ " ab " , OPT_FUNC2 | HAS_ARG | OPT_AUDIO , { ( void * ) opt_bitrate } , " set bitrate (in bits/s) " , " bitrate " } ,
2010-03-31 02:30:55 +03:00
{ " aframes " , OPT_INT | HAS_ARG | OPT_AUDIO , { ( void * ) & max_frames [ AVMEDIA_TYPE_AUDIO ] } , " set the number of audio frames to record " , " number " } ,
2005-08-21 23:27:00 +03:00
{ " aq " , OPT_FLOAT | HAS_ARG | OPT_AUDIO , { ( void * ) & audio_qscale } , " set audio quality (codec-specific) " , " quality " , } ,
2008-04-22 23:17:30 +03:00
{ " ar " , HAS_ARG | OPT_FUNC2 | OPT_AUDIO , { ( void * ) opt_audio_rate } , " set audio sampling rate (in Hz) " , " rate " } ,
{ " ac " , HAS_ARG | OPT_FUNC2 | OPT_AUDIO , { ( void * ) opt_audio_channels } , " set number of audio channels " , " channels " } ,
2003-08-24 18:29:48 +03:00
{ " an " , OPT_BOOL | OPT_AUDIO , { ( void * ) & audio_disable } , " disable audio " } ,
{ " acodec " , HAS_ARG | OPT_AUDIO , { ( void * ) opt_audio_codec } , " force audio codec ('copy' to copy stream) " , " codec " } ,
2010-10-28 16:20:26 +03:00
{ " atag " , OPT_FUNC2 | HAS_ARG | OPT_EXPERT | OPT_AUDIO , { ( void * ) opt_codec_tag } , " force audio tag/fourcc " , " fourcc/tag " } ,
2005-03-23 04:10:23 +02:00
{ " vol " , OPT_INT | HAS_ARG | OPT_AUDIO , { ( void * ) & audio_volume } , " change audio volume (256=normal) " , " volume " } , //
2010-08-24 18:48:20 +03:00
{ " newaudio " , OPT_AUDIO | OPT_FUNC2 , { ( void * ) opt_new_stream } , " add a new audio stream to the current output stream " } ,
2005-06-03 17:31:45 +03:00
{ " alang " , HAS_ARG | OPT_STRING | OPT_AUDIO , { ( void * ) & audio_language } , " set the ISO 639 language code (3 letters) of the current audio stream " , " code " } ,
2008-08-03 03:37:07 +03:00
{ " sample_fmt " , HAS_ARG | OPT_EXPERT | OPT_AUDIO , { ( void * ) opt_audio_sample_fmt } , " set sample format, 'list' as argument shows all the sample formats supported " , " format " } ,
2003-08-24 18:29:48 +03:00
2005-06-03 17:31:45 +03:00
/* subtitle options */
2007-07-25 22:47:44 +03:00
{ " sn " , OPT_BOOL | OPT_SUBTITLE , { ( void * ) & subtitle_disable } , " disable subtitle " } ,
2005-06-03 17:31:45 +03:00
{ " scodec " , HAS_ARG | OPT_SUBTITLE , { ( void * ) opt_subtitle_codec } , " force subtitle codec ('copy' to copy stream) " , " codec " } ,
2010-08-24 18:48:20 +03:00
{ " newsubtitle " , OPT_SUBTITLE | OPT_FUNC2 , { ( void * ) opt_new_stream } , " add a new subtitle stream to the current output stream " } ,
2005-06-03 17:31:45 +03:00
{ " slang " , HAS_ARG | OPT_STRING | OPT_SUBTITLE , { ( void * ) & subtitle_language } , " set the ISO 639 language code (3 letters) of the current subtitle stream " , " code " } ,
2010-10-28 16:20:26 +03:00
{ " stag " , OPT_FUNC2 | HAS_ARG | OPT_EXPERT | OPT_SUBTITLE , { ( void * ) opt_codec_tag } , " force subtitle tag/fourcc " , " fourcc/tag " } ,
2005-12-17 20:14:38 +02:00
2003-08-24 18:29:48 +03:00
/* grab options */
2011-04-11 14:16:07 +03:00
{ " vc " , HAS_ARG | OPT_FUNC2 | OPT_EXPERT | OPT_VIDEO | OPT_GRAB , { ( void * ) opt_video_channel } , " set video grab channel (DV1394 only) " , " channel " } ,
2003-08-24 18:29:48 +03:00
{ " tvstd " , HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB , { ( void * ) opt_video_standard } , " set television standard (NTSC, PAL (SECAM)) " , " standard " } ,
2007-02-14 19:01:32 +02:00
{ " isync " , OPT_BOOL | OPT_EXPERT | OPT_GRAB , { ( void * ) & input_sync } , " sync read on input " , " " } ,
2005-12-17 20:14:38 +02:00
/* muxer options */
2004-10-17 00:27:42 +03:00
{ " muxdelay " , OPT_FLOAT | HAS_ARG | OPT_EXPERT , { ( void * ) & mux_max_delay } , " set the maximum demux-decode delay " , " seconds " } ,
{ " muxpreload " , OPT_FLOAT | HAS_ARG | OPT_EXPERT , { ( void * ) & mux_preload } , " set the initial demux-decode delay " , " seconds " } ,
2006-07-06 18:04:46 +03:00
2008-05-28 14:55:59 +03:00
{ " absf " , OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_EXPERT , { ( void * ) opt_bsf } , " " , " bitstream_filter " } ,
{ " vbsf " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO | OPT_EXPERT , { ( void * ) opt_bsf } , " " , " bitstream_filter " } ,
{ " sbsf " , OPT_FUNC2 | HAS_ARG | OPT_SUBTITLE | OPT_EXPERT , { ( void * ) opt_bsf } , " " , " bitstream_filter " } ,
2006-07-06 18:04:46 +03:00
2008-10-12 23:46:30 +03:00
{ " apre " , OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_EXPERT , { ( void * ) opt_preset } , " set the audio options to the indicated preset " , " preset " } ,
{ " vpre " , OPT_FUNC2 | HAS_ARG | OPT_VIDEO | OPT_EXPERT , { ( void * ) opt_preset } , " set the video options to the indicated preset " , " preset " } ,
{ " spre " , OPT_FUNC2 | HAS_ARG | OPT_SUBTITLE | OPT_EXPERT , { ( void * ) opt_preset } , " set the subtitle options to the indicated preset " , " preset " } ,
2009-12-03 02:55:52 +02:00
{ " fpre " , OPT_FUNC2 | HAS_ARG | OPT_EXPERT , { ( void * ) opt_preset } , " set options from indicated preset file " , " filename " } ,
2011-04-14 14:32:36 +03:00
/* data codec support */
{ " dcodec " , HAS_ARG | OPT_DATA , { ( void * ) opt_data_codec } , " force data codec ('copy' to copy stream) " , " codec " } ,
2008-06-07 12:12:42 +03:00
2005-09-11 14:10:25 +03:00
{ " default " , OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT , { ( void * ) opt_default } , " generic catch all option " , " " } ,
2001-07-22 17:37:44 +03:00
{ NULL , } ,
} ;
2007-09-16 21:08:51 +03:00
int main ( int argc , char * * argv )
{
int64_t ti ;
2010-09-24 18:39:10 +03:00
av_log_set_flags ( AV_LOG_SKIP_REPEATED ) ;
2011-04-18 14:10:52 +03:00
if ( argc > 1 & & ! strcmp ( argv [ 1 ] , " -d " ) ) {
2011-04-22 19:49:44 +03:00
run_as_daemon = 1 ;
2011-04-18 14:10:52 +03:00
verbose = - 1 ;
av_log_set_callback ( log_callback_null ) ;
argc - - ;
argv + + ;
}
2007-11-22 18:10:02 +02:00
avcodec_register_all ( ) ;
2010-04-22 11:55:23 +03:00
# if CONFIG_AVDEVICE
2007-11-22 18:10:02 +02:00
avdevice_register_all ( ) ;
2010-05-07 12:43:21 +03:00
# endif
# if CONFIG_AVFILTER
avfilter_register_all ( ) ;
2010-04-22 11:55:23 +03:00
# endif
2007-09-16 21:08:51 +03:00
av_register_all ( ) ;
2009-07-24 03:13:59 +03:00
# if HAVE_ISATTY
2008-06-26 23:50:15 +03:00
if ( isatty ( STDIN_FILENO ) )
2011-04-04 21:15:44 +03:00
avio_set_interrupt_cb ( decode_interrupt_cb ) ;
2009-07-24 03:13:59 +03:00
# endif
2008-06-26 23:50:15 +03:00
2010-10-02 11:44:33 +03:00
init_opts ( ) ;
2007-09-16 21:08:51 +03:00
2011-05-18 14:58:13 +03:00
if ( verbose > = 0 )
show_banner ( ) ;
2007-09-16 21:08:51 +03:00
/* parse options */
parse_options ( argc , argv , options , opt_output_file ) ;
2009-12-21 04:15:46 +02:00
if ( nb_output_files < = 0 & & nb_input_files = = 0 ) {
show_usage ( ) ;
fprintf ( stderr , " Use -h to get full help or, even better, run 'man ffmpeg' \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2009-12-21 04:15:46 +02:00
}
2009-12-13 15:49:14 +02:00
2007-09-16 21:08:51 +03:00
/* file converter / grab */
if ( nb_output_files < = 0 ) {
2008-11-18 01:18:44 +02:00
fprintf ( stderr , " At least one output file must be specified \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2007-09-16 21:08:51 +03:00
}
if ( nb_input_files = = 0 ) {
2008-11-18 01:18:44 +02:00
fprintf ( stderr , " At least one input file must be specified \n " ) ;
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2007-09-16 21:08:51 +03:00
}
ti = getutime ( ) ;
2010-07-26 16:39:41 +03:00
if ( transcode ( output_files , nb_output_files , input_files , nb_input_files ,
2010-07-26 16:39:49 +03:00
stream_maps , nb_stream_maps ) < 0 )
2010-07-25 17:42:32 +03:00
ffmpeg_exit ( 1 ) ;
2007-09-16 21:08:51 +03:00
ti = getutime ( ) - ti ;
if ( do_benchmark ) {
2010-02-23 00:21:58 +02:00
int maxrss = getmaxrss ( ) / 1024 ;
printf ( " bench: utime=%0.3fs maxrss=%ikB \n " , ti / 1000000.0 , maxrss ) ;
2007-09-16 21:08:51 +03:00
}
2010-07-25 17:42:32 +03:00
return ffmpeg_exit ( 0 ) ;
2007-09-16 21:08:51 +03:00
}