X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ffmpeg.c;h=d601dc5d6af4a30a69ef911d9b3c026bd2ef94c7;hb=b0e8ce55aec5efcb3cd83e511e88f7957574ece7;hp=3c683dced3b3d7d1739b70cba59e0d89305d7449;hpb=de427ff48b060815ca047399069280c9db0a2773;p=ffmpeg diff --git a/ffmpeg.c b/ffmpeg.c index 3c683dced3b..d601dc5d6af 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -20,7 +20,7 @@ */ /* needed for usleep() */ -#define _XOPEN_SOURCE 500 +#define _XOPEN_SOURCE 600 #include "config.h" #include @@ -48,7 +48,11 @@ #include #endif -#if defined(HAVE_TERMIOS_H) +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#ifdef HAVE_TERMIOS_H #include #include #include @@ -90,10 +94,14 @@ static const OptionDef options[]; static AVFormatContext *input_files[MAX_FILES]; static int64_t input_files_ts_offset[MAX_FILES]; static double input_files_ts_scale[MAX_FILES][MAX_STREAMS]; +static AVCodec *input_codecs[MAX_FILES*MAX_STREAMS]; static int nb_input_files = 0; +static int nb_icodecs; static AVFormatContext *output_files[MAX_FILES]; +static AVCodec *output_codecs[MAX_FILES*MAX_STREAMS]; static int nb_output_files = 0; +static int nb_ocodecs; static AVStreamMap stream_maps[MAX_FILES*MAX_STREAMS]; static int nb_stream_maps; @@ -143,6 +151,7 @@ static int qp_hist = 0; static int intra_only = 0; static int audio_sample_rate = 44100; +static int64_t channel_layout = 0; #define QSCALE_NONE -99999 static float audio_qscale = QSCALE_NONE; static int audio_disable = 0; @@ -195,6 +204,7 @@ static char *video_standard; static int audio_volume = 256; +static int exit_on_error = 0; static int using_stdin = 0; static int using_vhook = 0; static int verbose = 1; @@ -207,17 +217,13 @@ static int nb_frames_dup = 0; static int nb_frames_drop = 0; static int input_sync; static uint64_t limit_filesize = 0; // +static int force_fps = 0; static int pgmyuv_compatibility_hack=0; static float dts_delta_threshold = 10; static unsigned int sws_flags = SWS_BICUBIC; -static const char **opt_names; -static int opt_name_count; -static AVCodecContext *avctx_opts[CODEC_TYPE_NB]; -static AVFormatContext *avformat_opts; -static struct SwsContext *sws_opts; static int64_t timer_start; static AVBitStreamFilterContext *video_bitstream_filters=NULL; @@ -275,7 +281,6 @@ typedef struct AVInputStream { int64_t sample_index; /* current sample */ int64_t start; /* time when read started */ - unsigned long frame; /* current frame */ int64_t next_pts; /* synthetic pts for cases where pkt.pts is not defined */ int64_t pts; /* current pts */ @@ -414,7 +419,7 @@ static int av_exit(int ret) av_free(video_standard); #ifdef CONFIG_POWERPC_PERF - extern void powerpc_display_perf_report(void); + void powerpc_display_perf_report(void); powerpc_display_perf_report(); #endif /* CONFIG_POWERPC_PERF */ @@ -495,6 +500,8 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx bsfc->filter->name, pkt->stream_index, avctx->codec ? avctx->codec->name : "copy"); print_error("", a); + if (exit_on_error) + av_exit(1); } *pkt= new_pkt; @@ -524,6 +531,8 @@ static void do_audio_out(AVFormatContext *s, int size_out, frame_bytes, ret; AVCodecContext *enc= ost->st->codec; AVCodecContext *dec= ist->st->codec; + int osize= av_get_bits_per_sample_format(enc->sample_fmt)/8; + int isize= av_get_bits_per_sample_format(dec->sample_fmt)/8; /* SC: dynamic allocation of buffers */ if (!audio_buf) @@ -537,6 +546,10 @@ static void do_audio_out(AVFormatContext *s, ost->audio_resample = 1; if (ost->audio_resample && !ost->resample) { + if (dec->sample_fmt != SAMPLE_FMT_S16) { + fprintf(stderr, "Audio resampler only works with 16 bits per sample, patch welcome.\n"); + av_exit(1); + } ost->resample = audio_resample_init(enc->channels, dec->channels, enc->sample_rate, dec->sample_rate); if (!ost->resample) { @@ -618,8 +631,8 @@ static void do_audio_out(AVFormatContext *s, buftmp = audio_buf; size_out = audio_resample(ost->resample, (short *)buftmp, (short *)buf, - size / (ist->st->codec->channels * 2)); - size_out = size_out * enc->channels * 2; + size / (ist->st->codec->channels * isize)); + size_out = size_out * enc->channels * osize; } else { buftmp = buf; size_out = size; @@ -628,17 +641,17 @@ static void do_audio_out(AVFormatContext *s, if (dec->sample_fmt!=enc->sample_fmt) { const void *ibuf[6]= {buftmp}; void *obuf[6]= {audio_out2}; - int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8}; - int ostride[6]= {av_get_bits_per_sample_format(enc->sample_fmt)/8}; + int istride[6]= {isize}; + int ostride[6]= {osize}; 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"); + if (exit_on_error) + av_exit(1); return; } buftmp = audio_out2; - /* FIXME: existing code assume that size_out equals framesize*channels*2 - remove this legacy cruft */ - size_out = len*2; + size_out = len*osize; } /* now encode as many frames as possible */ @@ -650,7 +663,7 @@ static void do_audio_out(AVFormatContext *s, } av_fifo_generic_write(&ost->fifo, buftmp, size_out, NULL); - frame_bytes = enc->frame_size * 2 * enc->channels; + frame_bytes = enc->frame_size * osize * enc->channels; while (av_fifo_size(&ost->fifo) >= frame_bytes) { AVPacket pkt; @@ -675,36 +688,17 @@ static void do_audio_out(AVFormatContext *s, } } else { AVPacket pkt; + int coded_bps = av_get_bits_per_sample(enc->codec->id)/8; av_init_packet(&pkt); - ost->sync_opts += size_out / (2 * enc->channels); + ost->sync_opts += size_out / (osize * enc->channels); /* output a pcm frame */ - /* XXX: change encoding codec API to avoid this ? */ - switch(enc->codec->id) { - case CODEC_ID_PCM_S32LE: - case CODEC_ID_PCM_S32BE: - case CODEC_ID_PCM_U32LE: - case CODEC_ID_PCM_U32BE: - case CODEC_ID_PCM_F32BE: - size_out = size_out << 1; - break; - case CODEC_ID_PCM_S24LE: - case CODEC_ID_PCM_S24BE: - case CODEC_ID_PCM_U24LE: - case CODEC_ID_PCM_U24BE: - case CODEC_ID_PCM_S24DAUD: - size_out = size_out / 2 * 3; - break; - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_U16LE: - case CODEC_ID_PCM_U16BE: - break; - default: - size_out = size_out >> 1; - break; - } + /* determine the size of the coded buffer */ + size_out /= osize; + if (coded_bps) + size_out *= coded_bps; + //FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio() ret = avcodec_encode_audio(enc, audio_out, size_out, (short *)buftmp); @@ -745,6 +739,7 @@ static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void 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; @@ -782,6 +777,8 @@ static void do_subtitle_out(AVFormatContext *s, if (pts == AV_NOPTS_VALUE) { fprintf(stderr, "Subtitle packets must have a pts\n"); + if (exit_on_error) + av_exit(1); return; } @@ -875,6 +872,8 @@ static void do_video_out(AVFormatContext *s, if (ost->video_crop) { if (av_picture_crop((AVPicture *)&picture_crop_temp, (AVPicture *)in_picture, dec->pix_fmt, ost->topBand, ost->leftBand) < 0) { av_log(NULL, AV_LOG_ERROR, "error cropping picture\n"); + if (exit_on_error) + av_exit(1); return; } formatted_picture = &picture_crop_temp; @@ -890,6 +889,8 @@ static void do_video_out(AVFormatContext *s, if (ost->video_resample) { if (av_picture_crop((AVPicture *)&picture_pad_temp, (AVPicture *)final_picture, enc->pix_fmt, ost->padtop, ost->padleft) < 0) { av_log(NULL, AV_LOG_ERROR, "error padding picture\n"); + if (exit_on_error) + av_exit(1); return; } resampling_dst = &picture_pad_temp; @@ -1090,7 +1091,7 @@ static void print_report(AVFormatContext **output_files, if(qp_hist){ int j; int qp= lrintf(enc->coded_frame->quality/(float)FF_QP2LAMBDA); - if(qp>=0 && qp=0 && qpst->codec->rate_emu) { - int64_t pts = av_rescale((int64_t) ist->frame * ist->st->codec->time_base.num, 1000000, ist->st->codec->time_base.den); + if (rate_emu) { + int64_t pts = av_rescale(ist->pts, 1000000, AV_TIME_BASE); int64_t now = av_gettime() - ist->start; if (pts > now) usleep(pts - now); - - ist->frame++; } -#if 0 - /* mpeg PTS deordering : if it is a P or I frame, the PTS - is the one of the next displayed one */ - /* XXX: add mpeg4 too ? */ - if (ist->st->codec->codec_id == CODEC_ID_MPEG1VIDEO) { - if (ist->st->codec->pict_type != B_TYPE) { - int64_t tmp; - tmp = ist->last_ip_pts; - ist->last_ip_pts = ist->frac_pts.val; - ist->frac_pts.val = tmp; - } - } -#endif /* if output time reached then transcode raw format, encode packets and output them */ if (start_time == 0 || ist->pts >= start_time) @@ -1500,6 +1486,7 @@ static void print_sdp(AVFormatContext **avc, int n) avf_sdp_create(avc, n, sdp, sizeof(sdp)); printf("SDP:\n%s\n", sdp); + fflush(stdout); } static int stream_index_from_inputs(AVFormatContext **input_files, @@ -1581,9 +1568,8 @@ static int av_encode(AVFormatContext **output_files, ist->discard = 1; /* the stream is discarded by default (changed later) */ - if (ist->st->codec->rate_emu) { + if (rate_emu) { ist->start = av_gettime(); - ist->frame = 0; } } } @@ -1593,7 +1579,8 @@ static int av_encode(AVFormatContext **output_files, for(i=0;inb_streams) { - fprintf(stderr, "Output file does not contain any stream\n"); + dump_format(output_files[i], i, output_files[i]->filename, 1); + fprintf(stderr, "Output file #%d does not contain any stream\n", i); av_exit(1); } nb_ostreams += os->nb_streams; @@ -1745,6 +1732,7 @@ static int av_encode(AVFormatContext **output_files, fprintf(stderr,"-acodec copy and -vol are incompatible (frames are not decoded)\n"); av_exit(1); } + codec->channel_layout = icodec->channel_layout; codec->sample_rate = icodec->sample_rate; codec->channels = icodec->channels; codec->frame_size = icodec->frame_size; @@ -1853,7 +1841,7 @@ static int av_encode(AVFormatContext **output_files, if (codec->flags & CODEC_FLAG_PASS1) { f = fopen(logfilename, "w"); if (!f) { - perror(logfilename); + fprintf(stderr, "Cannot write log file '%s' for pass-1 encoding: %s\n", logfilename, strerror(errno)); av_exit(1); } ost->logfile = f; @@ -1861,7 +1849,7 @@ static int av_encode(AVFormatContext **output_files, /* read the log file */ f = fopen(logfilename, "r"); if (!f) { - perror(logfilename); + fprintf(stderr, "Cannot read log file '%s' for pass-2 encoding: %s\n", logfilename, strerror(errno)); av_exit(1); } fseek(f, 0, SEEK_END); @@ -1918,8 +1906,9 @@ static int av_encode(AVFormatContext **output_files, for(i=0;iencoding_needed) { - AVCodec *codec; - codec = avcodec_find_encoder(ost->st->codec->codec_id); + AVCodec *codec = output_codecs[i]; + if (!codec) + codec = avcodec_find_encoder(ost->st->codec->codec_id); if (!codec) { fprintf(stderr, "Unsupported codec for output stream #%d.%d\n", ost->file_index, ost->index); @@ -1938,8 +1927,9 @@ static int av_encode(AVFormatContext **output_files, for(i=0;idecoding_needed) { - AVCodec *codec; - codec = avcodec_find_decoder(ist->st->codec->codec_id); + AVCodec *codec = input_codecs[i]; + if (!codec) + codec = avcodec_find_decoder(ist->st->codec->codec_id); if (!codec) { fprintf(stderr, "Unsupported codec (id=%d) for input stream #%d.%d\n", ist->st->codec->codec_id, ist->file_index, ist->index); @@ -2115,7 +2105,8 @@ static int av_encode(AVFormatContext **output_files, } // 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); - if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE) { + if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE + && (is->iformat->flags & AVFMT_TS_DISCONT)) { 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+1pts)&& !copy_ts){ @@ -2134,7 +2125,8 @@ static int av_encode(AVFormatContext **output_files, if (verbose >= 0) fprintf(stderr, "Error while decoding stream #%d.%d\n", ist->file_index, ist->index); - + if (exit_on_error) + av_exit(1); av_free_packet(&pkt); goto redo; } @@ -2264,42 +2256,6 @@ static void opt_format(const char *arg) } } -static int opt_default(const char *opt, const char *arg){ - int type; - const AVOption *o= NULL; - int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0}; - - for(type=0; typename; - - if(avctx_opts[0]->debug || avformat_opts->debug) - av_log_set_level(AV_LOG_DEBUG); - return 0; -} - static void opt_video_rc_override_string(const char *arg) { video_rc_override_string = arg; @@ -2777,19 +2733,6 @@ static enum CodecID find_codec_or_die(const char *name, int type, int encoder) return codec->id; } -static void set_context_opts(void *ctx, void *opts_ctx, int flags) -{ - int i; - for(i=0; iflags & flags) == flags)) - av_set_string2(ctx, opt_names[i], str, 1); - } -} - static void opt_input_file(const char *filename) { AVFormatContext *ic; @@ -2878,9 +2821,11 @@ static void opt_input_file(const char *filename) case CODEC_TYPE_AUDIO: set_context_opts(enc, avctx_opts[CODEC_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM); //fprintf(stderr, "\nInput Audio channels: %d", enc->channels); + channel_layout = enc->channel_layout; audio_channels = enc->channels; audio_sample_rate = enc->sample_rate; audio_sample_fmt = enc->sample_fmt; + input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(audio_codec_name); if(audio_disable) ic->streams[i]->discard= AVDISCARD_ALL; break; @@ -2912,7 +2857,7 @@ static void opt_input_file(const char *filename) frame_rate.num = rfps; frame_rate.den = rfps_base; - enc->rate_emu = rate_emu; + input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(video_codec_name); if(video_disable) ic->streams[i]->discard= AVDISCARD_ALL; else if(video_discard) @@ -2921,11 +2866,13 @@ static void opt_input_file(const char *filename) case CODEC_TYPE_DATA: break; case CODEC_TYPE_SUBTITLE: + input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(subtitle_codec_name); if(subtitle_disable) ic->streams[i]->discard = AVDISCARD_ALL; break; case CODEC_TYPE_ATTACHMENT: case CODEC_TYPE_UNKNOWN: + nb_icodecs++; break; default: abort(); @@ -2944,7 +2891,6 @@ static void opt_input_file(const char *filename) video_channel = 0; - rate_emu = 0; av_freep(&video_codec_name); av_freep(&audio_codec_name); av_freep(&subtitle_codec_name); @@ -3023,6 +2969,7 @@ static void new_video_stream(AVFormatContext *oc) if (video_stream_copy) { st->stream_copy = 1; video_enc->codec_type = CODEC_TYPE_VIDEO; + video_enc->sample_aspect_ratio = st->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255); } else { const char *p; @@ -3030,32 +2977,23 @@ static void new_video_stream(AVFormatContext *oc) AVCodec *codec; AVRational fps= frame_rate.num ? frame_rate : (AVRational){25,1}; - codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_VIDEO); - if (video_codec_name) + if (video_codec_name) { codec_id = find_codec_or_die(video_codec_name, CODEC_TYPE_VIDEO, 1); + codec = avcodec_find_encoder_by_name(video_codec_name); + output_codecs[nb_ocodecs] = codec; + } else { + codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_VIDEO); + codec = avcodec_find_encoder(codec_id); + } video_enc->codec_id = codec_id; - codec = avcodec_find_encoder(codec_id); set_context_opts(video_enc, avctx_opts[CODEC_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM); + if (codec && codec->supported_framerates && !force_fps) + fps = codec->supported_framerates[av_find_nearest_q_idx(fps, codec->supported_framerates)]; video_enc->time_base.den = fps.num; video_enc->time_base.num = fps.den; - if(codec && codec->supported_framerates){ - const AVRational *p= codec->supported_framerates; - const AVRational *best=NULL; - AVRational best_error= (AVRational){INT_MAX, 1}; - for(; p->den!=0; p++){ - AVRational error= av_sub_q(fps, *p); - if(error.num <0) error.num *= -1; - if(av_cmp_q(error, best_error) < 0){ - best_error= error; - best= p; - } - } - video_enc->time_base.den= best->num; - video_enc->time_base.num= best->den; - } video_enc->width = frame_width + frame_padright + frame_padleft; video_enc->height = frame_height + frame_padtop + frame_padbottom; @@ -3129,6 +3067,7 @@ static void new_video_stream(AVFormatContext *oc) } } } + nb_ocodecs++; /* reset some key parameters */ video_disable = 0; @@ -3170,14 +3109,18 @@ static void new_audio_stream(AVFormatContext *oc) audio_enc->channels = audio_channels; } else { AVCodec *codec; - codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_AUDIO); set_context_opts(audio_enc, avctx_opts[CODEC_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM); - if (audio_codec_name) + if (audio_codec_name) { codec_id = find_codec_or_die(audio_codec_name, CODEC_TYPE_AUDIO, 1); + codec = avcodec_find_encoder_by_name(audio_codec_name); + output_codecs[nb_ocodecs] = codec; + } else { + codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_AUDIO); + codec = avcodec_find_encoder(codec_id); + } audio_enc->codec_id = codec_id; - codec = avcodec_find_encoder(codec_id); if (audio_qscale > QSCALE_NONE) { audio_enc->flags |= CODEC_FLAG_QSCALE; @@ -3186,6 +3129,7 @@ static void new_audio_stream(AVFormatContext *oc) audio_enc->thread_count = thread_count; audio_enc->channels = audio_channels; audio_enc->sample_fmt = audio_sample_fmt; + audio_enc->channel_layout = channel_layout; if(codec && codec->sample_fmts){ const enum SampleFormat *p= codec->sample_fmts; @@ -3197,6 +3141,7 @@ static void new_audio_stream(AVFormatContext *oc) audio_enc->sample_fmt = codec->sample_fmts[0]; } } + nb_ocodecs++; audio_enc->sample_rate = audio_sample_rate; audio_enc->time_base= (AVRational){1, audio_sample_rate}; if (audio_language) { @@ -3233,7 +3178,9 @@ static void new_subtitle_stream(AVFormatContext *oc) } else { set_context_opts(avctx_opts[CODEC_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM); subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, CODEC_TYPE_SUBTITLE, 1); + output_codecs[nb_ocodecs] = avcodec_find_encoder_by_name(subtitle_codec_name); } + nb_ocodecs++; if (subtitle_language) { av_strlcpy(st->language, subtitle_language, sizeof(st->language)); @@ -3632,7 +3579,7 @@ static void opt_target(const char *arg) opt_default("maxrate", "2516000"); opt_default("minrate", "0"); //1145000; opt_default("bufsize", "1835008"); //224*1024*8; - opt_default("flags", "+SCAN_OFFSET"); + opt_default("flags", "+scan_offset"); opt_default("ab", "224000"); @@ -3720,7 +3667,7 @@ static int opt_bsf(const char *opt, const char *arg) static int opt_preset(const char *opt, const char *arg) { FILE *f=NULL; - char tmp[1000], tmp2[1000]; + char filename[1000], tmp[1000], tmp2[1000], line[1000]; int i; const char *base[3]= { getenv("HOME"), "/usr/local/share", @@ -3728,26 +3675,34 @@ static int opt_preset(const char *opt, const char *arg) }; for(i=!base[0]; i<3 && !f; i++){ - snprintf(tmp, sizeof(tmp), "%s/%sffmpeg/%s.ffpreset", base[i], i ? "" : ".", arg); - f= fopen(tmp, "r"); + snprintf(filename, sizeof(filename), "%s/%sffmpeg/%s.ffpreset", base[i], i ? "" : ".", arg); + f= fopen(filename, "r"); if(!f){ char *codec_name= *opt == 'v' ? video_codec_name : *opt == 'a' ? audio_codec_name : subtitle_codec_name; - snprintf(tmp, sizeof(tmp), "%s/%sffmpeg/%s-%s.ffpreset", base[i], i ? "" : ".", codec_name, arg); - f= fopen(tmp, "r"); + snprintf(filename, sizeof(filename), "%s/%sffmpeg/%s-%s.ffpreset", base[i], i ? "" : ".", codec_name, arg); + f= fopen(filename, "r"); } } + if(!f && ((arg[0]=='.' && arg[1]=='/') || arg[0]=='/' || + is_dos_path(arg))){ + snprintf(filename, sizeof(filename), arg); + f= fopen(filename, "r"); + } if(!f){ - fprintf(stderr, "Preset file not found\n"); + fprintf(stderr, "File for preset '%s' not found\n", arg); av_exit(1); } while(!feof(f)){ - int e= fscanf(f, "%999[^=]=%999[^\n]\n", tmp, tmp2); - if(e!=2){ - fprintf(stderr, "Preset file invalid\n"); + 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){ + fprintf(stderr, "%s: Invalid syntax: '%s'\n", filename, line); av_exit(1); } if(!strcmp(tmp, "acodec")){ @@ -3756,8 +3711,10 @@ static int opt_preset(const char *opt, const char *arg) opt_video_codec(tmp2); }else if(!strcmp(tmp, "scodec")){ opt_subtitle_codec(tmp2); - }else - opt_default(tmp, tmp2); + }else if(opt_default(tmp, tmp2) < 0){ + fprintf(stderr, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", filename, line, tmp, tmp2); + av_exit(1); + } } fclose(f); @@ -3809,6 +3766,7 @@ static const OptionDef options[] = { { "shortest", OPT_BOOL | OPT_EXPERT, {(void*)&opt_shortest}, "finish encoding within shortest input" }, // { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&dts_delta_threshold}, "timestamp discontinuity delta threshold", "threshold" }, { "programid", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&opt_programid}, "desired program number", "" }, + { "xerror", OPT_BOOL, {(void*)&exit_on_error}, "exit on error", "error" }, /* video options */ { "b", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" }, @@ -3853,6 +3811,7 @@ static const OptionDef options[] = { { "vtag", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_tag}, "force video tag/fourcc", "fourcc/tag" }, { "newvideo", OPT_VIDEO, {(void*)opt_new_video_stream}, "add a new video stream to the current output stream" }, { "qphist", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&qp_hist }, "show QP histogram" }, + { "force_fps", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&force_fps}, "force the selected framerate, disable the best supported framerate selection" }, /* audio options */ { "ab", OPT_FUNC2 | HAS_ARG | OPT_AUDIO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" }, @@ -3887,9 +3846,9 @@ static const OptionDef options[] = { { "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" }, - { "apre", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_EXPERT, {(void*)opt_preset}, "", "preset" }, - { "vpre", OPT_FUNC2 | HAS_ARG | OPT_VIDEO | OPT_EXPERT, {(void*)opt_preset}, "", "preset" }, - { "spre", OPT_FUNC2 | HAS_ARG | OPT_SUBTITLE | OPT_EXPERT, {(void*)opt_preset}, "", "preset" }, + { "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" }, { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" }, { NULL, }, @@ -3914,22 +3873,18 @@ int main(int argc, char **argv) sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL); show_banner(); - if (argc <= 1) { - show_help(); - av_exit(1); - } /* parse options */ parse_options(argc, argv, options, opt_output_file); /* file converter / grab */ if (nb_output_files <= 0) { - fprintf(stderr, "Must supply at least one output file\n"); + fprintf(stderr, "At least one output file must be specified\n"); av_exit(1); } if (nb_input_files == 0) { - fprintf(stderr, "Must supply at least one input file\n"); + fprintf(stderr, "At least one input file must be specified\n"); av_exit(1); }