X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=avconv.c;h=dd998ab40cfca5f7bb5d99b689ddd0769af786e2;hb=e034cc6c60c77dce390b1ac31141b1862bdf8999;hp=2566a92c14112c40380da915a21885308452afe9;hpb=a5fd7c607f7aa6dad7dc2ca9b579c26ddef359d9;p=ffmpeg diff --git a/avconv.c b/avconv.c index 2566a92c141..dd998ab40cf 100644 --- a/avconv.c +++ b/avconv.c @@ -32,7 +32,7 @@ #include "libswscale/swscale.h" #include "libavresample/avresample.h" #include "libavutil/opt.h" -#include "libavutil/audioconvert.h" +#include "libavutil/channel_layout.h" #include "libavutil/parseutils.h" #include "libavutil/samplefmt.h" #include "libavutil/colorspace.h" @@ -53,6 +53,7 @@ # include "libavfilter/buffersink.h" #if HAVE_SYS_RESOURCE_H +#include #include #include #elif HAVE_GETPROCESSTIMES @@ -143,7 +144,7 @@ static int decode_interrupt_cb(void *ctx) const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL }; -void exit_program(int ret) +static void exit_program(void) { int i, j; @@ -180,10 +181,11 @@ void exit_program(int ret) bsfc = next; } output_streams[i]->bitstream_filters = NULL; + avcodec_free_frame(&output_streams[i]->filtered_frame); av_freep(&output_streams[i]->forced_keyframes); av_freep(&output_streams[i]->avfilter); - av_freep(&output_streams[i]->filtered_frame); + av_freep(&output_streams[i]->logfile_prefix); av_freep(&output_streams[i]); } for (i = 0; i < nb_input_files; i++) { @@ -191,7 +193,7 @@ void exit_program(int ret) av_freep(&input_files[i]); } for (i = 0; i < nb_input_streams; i++) { - av_freep(&input_streams[i]->decoded_frame); + avcodec_free_frame(&input_streams[i]->decoded_frame); av_dict_free(&input_streams[i]->opts); free_buffer_pool(&input_streams[i]->buffer_pool); av_freep(&input_streams[i]->filters); @@ -217,8 +219,6 @@ void exit_program(int ret) (int) received_sigterm); exit (255); } - - exit(ret); } void assert_avoptions(AVDictionary *m) @@ -226,28 +226,25 @@ void assert_avoptions(AVDictionary *m) AVDictionaryEntry *t; if ((t = av_dict_get(m, "", NULL, AV_DICT_IGNORE_SUFFIX))) { av_log(NULL, AV_LOG_FATAL, "Option %s not found.\n", t->key); - exit_program(1); + exit(1); } } -static void assert_codec_experimental(AVCodecContext *c, int encoder) +static void abort_codec_experimental(AVCodec *c, int encoder) { const char *codec_string = encoder ? "encoder" : "decoder"; AVCodec *codec; - if (c->codec->capabilities & CODEC_CAP_EXPERIMENTAL && - c->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { - av_log(NULL, AV_LOG_FATAL, "%s '%s' is experimental and might produce bad " - "results.\nAdd '-strict experimental' if you want to use it.\n", - codec_string, c->codec->name); - codec = encoder ? avcodec_find_encoder(c->codec->id) : avcodec_find_decoder(c->codec->id); - if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL)) - av_log(NULL, AV_LOG_FATAL, "Or use the non experimental %s '%s'.\n", - codec_string, codec->name); - exit_program(1); - } + av_log(NULL, AV_LOG_FATAL, "%s '%s' is experimental and might produce bad " + "results.\nAdd '-strict experimental' if you want to use it.\n", + codec_string, c->name); + codec = encoder ? avcodec_find_encoder(c->id) : avcodec_find_decoder(c->id); + if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL)) + av_log(NULL, AV_LOG_FATAL, "Or use the non experimental %s '%s'.\n", + codec_string, codec->name); + exit(1); } -/** +/* * Update the requested input sample format based on the output sample format. * This is currently only used to request float output from decoders which * support multiple sample formats, one of which is AV_SAMPLE_FMT_FLT. @@ -268,22 +265,41 @@ static void update_sample_fmt(AVCodecContext *dec, AVCodec *dec_codec, dec_codec->sample_fmts[0] != AV_SAMPLE_FMT_NONE && dec_codec->sample_fmts[1] != AV_SAMPLE_FMT_NONE) { const enum AVSampleFormat *p; - int min_dec = -1, min_inc = -1; + int min_dec = INT_MAX, min_inc = INT_MAX; + enum AVSampleFormat dec_fmt = AV_SAMPLE_FMT_NONE; + enum AVSampleFormat inc_fmt = AV_SAMPLE_FMT_NONE; /* find a matching sample format in the encoder */ for (p = dec_codec->sample_fmts; *p != AV_SAMPLE_FMT_NONE; p++) { if (*p == enc->sample_fmt) { dec->request_sample_fmt = *p; return; - } else if (*p > enc->sample_fmt) { - min_inc = FFMIN(min_inc, *p - enc->sample_fmt); - } else - min_dec = FFMIN(min_dec, enc->sample_fmt - *p); + } else { + enum AVSampleFormat dfmt = av_get_packed_sample_fmt(*p); + enum AVSampleFormat efmt = av_get_packed_sample_fmt(enc->sample_fmt); + int fmt_diff = 32 * abs(dfmt - efmt); + if (av_sample_fmt_is_planar(*p) != + av_sample_fmt_is_planar(enc->sample_fmt)) + fmt_diff++; + if (dfmt == efmt) { + min_inc = fmt_diff; + inc_fmt = *p; + } else if (dfmt > efmt) { + if (fmt_diff < min_inc) { + min_inc = fmt_diff; + inc_fmt = *p; + } + } else { + if (fmt_diff < min_dec) { + min_dec = fmt_diff; + dec_fmt = *p; + } + } + } } /* if none match, provide the one that matches quality closest */ - dec->request_sample_fmt = min_inc > 0 ? enc->sample_fmt + min_inc : - enc->sample_fmt - min_dec; + dec->request_sample_fmt = min_inc != INT_MAX ? inc_fmt : dec_fmt; } } @@ -323,7 +339,7 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) avctx->codec ? avctx->codec->name : "copy"); print_error("", a); if (exit_on_error) - exit_program(1); + exit(1); } *pkt = new_pkt; @@ -334,7 +350,7 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) ret = av_interleaved_write_frame(s, pkt); if (ret < 0) { print_error("av_interleaved_write_frame()", ret); - exit_program(1); + exit(1); } } @@ -371,7 +387,7 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost, if (avcodec_encode_audio2(enc, &pkt, frame, &got_packet) < 0) { av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n"); - exit_program(1); + exit(1); } if (got_packet) { @@ -442,7 +458,7 @@ static void do_subtitle_out(AVFormatContext *s, if (pts == AV_NOPTS_VALUE) { av_log(NULL, AV_LOG_ERROR, "Subtitle packets must have a pts\n"); if (exit_on_error) - exit_program(1); + exit(1); return; } @@ -474,7 +490,7 @@ static void do_subtitle_out(AVFormatContext *s, subtitle_out_max_size, sub); if (subtitle_out_size < 0) { av_log(NULL, AV_LOG_FATAL, "Subtitle encoding failed\n"); - exit_program(1); + exit(1); } av_init_packet(&pkt); @@ -496,7 +512,7 @@ static void do_subtitle_out(AVFormatContext *s, static void do_video_out(AVFormatContext *s, OutputStream *ost, AVFrame *in_picture, - int *frame_size, float quality) + int *frame_size) { int ret, format_video_sync; AVPacket pkt; @@ -561,9 +577,7 @@ static void do_video_out(AVFormatContext *s, big_picture.top_field_first = !!ost->top_field_first; } - /* handles same_quant here. This is not correct because it may - not be a global option */ - big_picture.quality = quality; + big_picture.quality = ost->st->codec->global_quality; if (!enc->me_threshold) big_picture.pict_type = 0; if (ost->forced_kf_index < ost->forced_kf_count && @@ -574,7 +588,7 @@ static void do_video_out(AVFormatContext *s, ret = avcodec_encode_video2(enc, &pkt, &big_picture, &got_packet); if (ret < 0) { av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n"); - exit_program(1); + exit(1); } if (got_packet) { @@ -607,8 +621,7 @@ static double psnr(double d) return -10.0 * log(d) / log(10.0); } -static void do_video_stats(AVFormatContext *os, OutputStream *ost, - int frame_size) +static void do_video_stats(OutputStream *ost, int frame_size) { AVCodecContext *enc; int frame_number; @@ -619,7 +632,7 @@ static void do_video_stats(AVFormatContext *os, OutputStream *ost, vstats_file = fopen(vstats_filename, "w"); if (!vstats_file) { perror("fopen"); - exit_program(1); + exit(1); } } @@ -644,7 +657,7 @@ static void do_video_stats(AVFormatContext *os, OutputStream *ost, } } -/** +/* * Read one frame for lavfi output for ost and encode it. */ static int poll_filter(OutputStream *ost) @@ -690,11 +703,9 @@ static int poll_filter(OutputStream *ost) if (!ost->frame_aspect_ratio) ost->st->codec->sample_aspect_ratio = picref->video->pixel_aspect; - do_video_out(of->ctx, ost, filtered_frame, &frame_size, - same_quant ? ost->last_quality : - ost->st->codec->global_quality); + do_video_out(of->ctx, ost, filtered_frame, &frame_size); if (vstats_filename && frame_size) - do_video_stats(of->ctx, ost, frame_size); + do_video_stats(ost, frame_size); break; case AVMEDIA_TYPE_AUDIO: do_audio_out(of->ctx, ost, filtered_frame); @@ -709,7 +720,7 @@ static int poll_filter(OutputStream *ost) return 0; } -/** +/* * Read as many frames from possible from lavfi and encode them. * * Always read from the active stream with the lowest timestamp. If no frames @@ -719,7 +730,7 @@ static int poll_filter(OutputStream *ost) */ static int poll_filters(void) { - int i, ret = 0; + int i, j, ret = 0; while (ret >= 0 && !received_sigterm) { OutputStream *ost = NULL; @@ -746,10 +757,14 @@ static int poll_filters(void) ret = poll_filter(ost); if (ret == AVERROR_EOF) { + OutputFile *of = output_files[ost->file_index]; + ost->finished = 1; - if (opt_shortest) - return ret; + if (of->shortest) { + for (j = 0; j < of->ctx->nb_streams; j++) + output_streams[of->ost_index + j]->finished = 1; + } ret = 0; } else if (ret == AVERROR(EAGAIN)) @@ -791,8 +806,15 @@ static void print_report(int is_last_report, int64_t timer_start) oc = output_files[0]->ctx; total_size = avio_size(oc->pb); - if (total_size < 0) // FIXME improve avio_size() so it works with non seekable output too + if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too total_size = avio_tell(oc->pb); + if (total_size < 0) { + char errbuf[128]; + av_strerror(total_size, errbuf, sizeof(errbuf)); + av_log(NULL, AV_LOG_VERBOSE, "Bitrate not available, " + "avio_tell() failed: %s\n", errbuf); + total_size = 0; + } buf[0] = '\0'; ti1 = 1e10; @@ -820,7 +842,7 @@ static void print_report(int is_last_report, int64_t timer_start) if (qp >= 0 && qp < FF_ARRAY_ELEMS(qp_histogram)) 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))); + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", (int)lrintf(log2(qp_histogram[j] + 1))); } if (enc->flags&CODEC_FLAG_PSNR) { int j; @@ -928,7 +950,7 @@ static void flush_encoders(void) ret = encode(enc, &pkt, NULL, &got_packet); if (ret < 0) { av_log(NULL, AV_LOG_FATAL, "%s encoding failed\n", desc); - exit_program(1); + exit(1); } *size += ret; if (ost->logfile && enc->stats_out) { @@ -942,6 +964,8 @@ static void flush_encoders(void) pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base); if (pkt.dts != AV_NOPTS_VALUE) pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base); + if (pkt.duration > 0) + pkt.duration = av_rescale_q(pkt.duration, enc->time_base, ost->st->time_base); write_frame(os, &pkt, ost); } @@ -1023,7 +1047,6 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p write_frame(of->ctx, &opkt, ost); ost->st->codec->frame_number++; - av_free_packet(&opkt); } static void rate_emu_sleep(InputStream *ist) @@ -1058,13 +1081,10 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) { AVFrame *decoded_frame; AVCodecContext *avctx = ist->st->codec; - int bps = av_get_bytes_per_sample(ist->st->codec->sample_fmt); int i, ret, resample_changed; if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame())) return AVERROR(ENOMEM); - else - avcodec_get_frame_defaults(ist->decoded_frame); decoded_frame = ist->decoded_frame; ret = avcodec_decode_audio4(avctx, decoded_frame, got_output, pkt); @@ -1085,64 +1105,6 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) pkt->pts = AV_NOPTS_VALUE; } - // preprocess audio (volume) - if (audio_volume != 256) { - int decoded_data_size = decoded_frame->nb_samples * avctx->channels * bps; - void *samples = decoded_frame->data[0]; - switch (avctx->sample_fmt) { - case AV_SAMPLE_FMT_U8: - { - uint8_t *volp = samples; - for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) { - int v = (((*volp - 128) * audio_volume + 128) >> 8) + 128; - *volp++ = av_clip_uint8(v); - } - break; - } - case AV_SAMPLE_FMT_S16: - { - int16_t *volp = samples; - for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) { - int v = ((*volp) * audio_volume + 128) >> 8; - *volp++ = av_clip_int16(v); - } - break; - } - case AV_SAMPLE_FMT_S32: - { - int32_t *volp = samples; - for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) { - int64_t v = (((int64_t)*volp * audio_volume + 128) >> 8); - *volp++ = av_clipl_int32(v); - } - break; - } - case AV_SAMPLE_FMT_FLT: - { - float *volp = samples; - float scale = audio_volume / 256.f; - for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) { - *volp++ *= scale; - } - break; - } - case AV_SAMPLE_FMT_DBL: - { - double *volp = samples; - double scale = audio_volume / 256.; - for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) { - *volp++ *= scale; - } - break; - } - default: - av_log(NULL, AV_LOG_FATAL, - "Audio volume adjustment on sample format %s is not supported.\n", - av_get_sample_fmt_name(ist->st->codec->sample_fmt)); - exit_program(1); - } - } - rate_emu_sleep(ist); resample_changed = ist->resample_sample_fmt != decoded_frame->format || @@ -1156,7 +1118,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) av_log(NULL, AV_LOG_FATAL, "Unable to find default channel " "layout for Input Stream #%d.%d\n", ist->file_index, ist->st->index); - exit_program(1); + exit(1); } decoded_frame->channel_layout = avctx->channel_layout; @@ -1182,7 +1144,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) if (ist_in_filtergraph(filtergraphs[i], ist) && configure_filtergraph(filtergraphs[i]) < 0) { av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n"); - exit_program(1); + exit(1); } } @@ -1201,12 +1163,9 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) AVFrame *decoded_frame; void *buffer_to_free = NULL; int i, ret = 0, resample_changed; - float quality; if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame())) return AVERROR(ENOMEM); - else - avcodec_get_frame_defaults(ist->decoded_frame); decoded_frame = ist->decoded_frame; ret = avcodec_decode_video2(ist->st->codec, @@ -1219,7 +1178,6 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) return ret; } - quality = same_quant ? decoded_frame->quality : 0; decoded_frame->pts = guess_correct_pts(&ist->pts_ctx, decoded_frame->pkt_pts, decoded_frame->pkt_dts); pkt->size = 0; @@ -1240,6 +1198,10 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) ist->resample_width, ist->resample_height, av_get_pix_fmt_name(ist->resample_pix_fmt), decoded_frame->width, decoded_frame->height, av_get_pix_fmt_name(decoded_frame->format)); + ret = poll_filters(); + if (ret < 0 && (ret != AVERROR_EOF && ret != AVERROR(EAGAIN))) + av_log(NULL, AV_LOG_ERROR, "Error while filtering.\n"); + ist->resample_width = decoded_frame->width; ist->resample_height = decoded_frame->height; ist->resample_pix_fmt = decoded_frame->format; @@ -1248,15 +1210,11 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) if (ist_in_filtergraph(filtergraphs[i], ist) && configure_filtergraph(filtergraphs[i]) < 0) { av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n"); - exit_program(1); + exit(1); } } for (i = 0; i < ist->nb_filters; i++) { - // XXX what an ugly hack - if (ist->filters[i]->graph->nb_outputs == 1) - ist->filters[i]->graph->outputs[0]->ost->last_quality = quality; - if (ist->st->codec->codec->capabilities & CODEC_CAP_DR1) { FrameBuffer *buf = decoded_frame->opaque; AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays( @@ -1414,7 +1372,7 @@ static void print_sdp(void) AVFormatContext **avc = av_malloc(sizeof(*avc) * nb_output_files); if (!avc) - exit_program(1); + exit(1); for (i = 0; i < nb_output_files; i++) avc[i] = output_files[i]->ctx; @@ -1426,7 +1384,7 @@ static void print_sdp(void) static int init_input_stream(int ist_index, char *error, int error_len) { - int i; + int i, ret; InputStream *ist = input_streams[ist_index]; if (ist->decoding_needed) { AVCodec *codec = ist->dec; @@ -1454,12 +1412,13 @@ static int init_input_stream(int ist_index, char *error, int error_len) if (!av_dict_get(ist->opts, "threads", NULL, 0)) av_dict_set(&ist->opts, "threads", "auto", 0); - if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) { + if ((ret = avcodec_open2(ist->st->codec, codec, &ist->opts)) < 0) { + if (ret == AVERROR_EXPERIMENTAL) + abort_codec_experimental(codec, 0); snprintf(error, error_len, "Error while opening decoder for input stream #%d:%d", ist->file_index, ist->st->index); - return AVERROR(EINVAL); + return ret; } - assert_codec_experimental(ist->st->codec, 0); assert_avoptions(ist->opts); } @@ -1502,7 +1461,7 @@ static void parse_forced_key_frames(char *kf, OutputStream *ost, 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"); - exit_program(1); + exit(1); } p = kf; @@ -1616,7 +1575,7 @@ static int transcode_init(void) case AVMEDIA_TYPE_AUDIO: if (audio_volume != 256) { av_log(NULL, AV_LOG_FATAL, "-acodec copy and -vol are incompatible (frames are not decoded)\n"); - exit_program(1); + exit(1); } codec->channel_layout = icodec->channel_layout; codec->sample_rate = icodec->sample_rate; @@ -1678,7 +1637,11 @@ static int transcode_init(void) (video_sync_method == VSYNC_CFR || (video_sync_method == VSYNC_AUTO && !(oc->oformat->flags & (AVFMT_NOTIMESTAMPS | AVFMT_VARIABLE_FPS))))) { - ost->frame_rate = ist->st->avg_frame_rate.num ? ist->st->avg_frame_rate : (AVRational){25, 1}; + ost->frame_rate = ist->framerate.num ? ist->framerate : + ist->st->avg_frame_rate.num ? + ist->st->avg_frame_rate : + (AVRational){25, 1}; + if (ost->enc && ost->enc->supported_framerates && !ost->force_fps) { int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates); ost->frame_rate = ost->enc->supported_framerates[idx]; @@ -1739,7 +1702,8 @@ static int transcode_init(void) FILE *f; snprintf(logfilename, sizeof(logfilename), "%s-%d.log", - pass_logfilename_prefix ? pass_logfilename_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX, + ost->logfile_prefix ? ost->logfile_prefix : + DEFAULT_PASS_LOGFILENAME_PREFIX, i); if (!strcmp(ost->enc->name, "libx264")) { av_dict_set(&ost->opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE); @@ -1749,7 +1713,7 @@ static int transcode_init(void) if (!f) { av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n", logfilename, strerror(errno)); - exit_program(1); + exit(1); } ost->logfile = f; } else { @@ -1758,7 +1722,7 @@ static int transcode_init(void) if (cmdutils_read_file(logfilename, &logbuffer, &logbuffer_size) < 0) { av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n", logfilename); - exit_program(1); + exit(1); } codec->stats_in = logbuffer; } @@ -1787,13 +1751,13 @@ static int transcode_init(void) } if (!av_dict_get(ost->opts, "threads", NULL, 0)) av_dict_set(&ost->opts, "threads", "auto", 0); - if (avcodec_open2(ost->st->codec, codec, &ost->opts) < 0) { + if ((ret = avcodec_open2(ost->st->codec, codec, &ost->opts)) < 0) { + if (ret == AVERROR_EXPERIMENTAL) + abort_codec_experimental(codec, 1); snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d:%d - maybe incorrect parameters such as bit_rate, rate, width or height", ost->file_index, ost->index); - ret = AVERROR(EINVAL); goto dump_format; } - assert_codec_experimental(ost->st->codec, 1); assert_avoptions(ost->opts); if (ost->st->codec->bit_rate && ost->st->codec->bit_rate < 1000) av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low." @@ -1920,10 +1884,7 @@ static int transcode_init(void) return 0; } -/** - * @return 1 if there are still streams where more output is wanted, - * 0 otherwise - */ +/* Return 1 if there remain streams where more output is wanted, 0 otherwise. */ static int need_output(void) { int i; @@ -2107,13 +2068,13 @@ static void reset_eagain(void) input_files[i]->eagain = 0; } -/** +/* * Read one packet from an input file and send it for * - decoding -> lavfi (audio/video) * - decoding -> encoding -> muxing (subtitles) * - muxing (streamcopy) * - * @return + * Return * - 0 -- one packet was read and processed * - AVERROR(EAGAIN) -- no packets were available for selected file, * this function should be called again @@ -2151,7 +2112,7 @@ static int process_input(void) if (ret != AVERROR_EOF) { print_error(is->filename, ret); if (exit_on_error) - exit_program(1); + exit(1); } ifile->eof_reached = 1; @@ -2170,10 +2131,7 @@ static int process_input(void) } } - if (opt_shortest) - return AVERROR_EOF; - else - return AVERROR(EAGAIN); + return AVERROR(EAGAIN); } reset_eagain(); @@ -2222,7 +2180,7 @@ static int process_input(void) av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", ist->file_index, ist->st->index); if (exit_on_error) - exit_program(1); + exit(1); } discard_packet: @@ -2387,19 +2345,12 @@ static int64_t getmaxrss(void) #endif } -static void parse_cpuflags(int argc, char **argv, const OptionDef *options) -{ - int idx = locate_option(argc, argv, options, "cpuflags"); - if (idx && argv[idx + 1]) - opt_cpuflags("cpuflags", argv[idx + 1]); -} - int main(int argc, char **argv) { - OptionsContext o = { 0 }; + int ret; int64_t ti; - reset_options(&o); + atexit(exit_program); av_log_set_flags(AV_LOG_SKIP_REPEATED); parse_loglevel(argc, argv, options); @@ -2414,37 +2365,32 @@ int main(int argc, char **argv) show_banner(); - parse_cpuflags(argc, argv, options); - - /* parse options */ - parse_options(&o, argc, argv, options, opt_output_file); + /* parse options and open all input/output files */ + ret = avconv_parse_options(argc, argv); + if (ret < 0) + exit(1); if (nb_output_files <= 0 && nb_input_files == 0) { show_usage(); av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name); - exit_program(1); + exit(1); } /* file converter / grab */ if (nb_output_files <= 0) { fprintf(stderr, "At least one output file must be specified\n"); - exit_program(1); - } - - if (nb_input_files == 0) { - av_log(NULL, AV_LOG_FATAL, "At least one input file must be specified\n"); - exit_program(1); + exit(1); } ti = getutime(); if (transcode() < 0) - exit_program(1); + exit(1); ti = getutime() - ti; if (do_benchmark) { int maxrss = getmaxrss() / 1024; printf("bench: utime=%0.3fs maxrss=%ikB\n", ti / 1000000.0, maxrss); } - exit_program(0); + exit(0); return 0; }