From 5ee5dc4e9a094db235fd86454b019b02fa250eee Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 31 Aug 2011 19:27:17 +0200 Subject: nutenc: add namespace to the api facing functions Rename write_{header,packet,trailer} to nut_write_{header,packet,trailer} in order to make easier debugging them. --- libavformat/nutenc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c index 1ed073f00c..f8a078cb8a 100644 --- a/libavformat/nutenc.c +++ b/libavformat/nutenc.c @@ -578,7 +578,7 @@ static int write_headers(AVFormatContext *avctx, AVIOContext *bc){ return 0; } -static int write_header(AVFormatContext *s){ +static int nut_write_header(AVFormatContext *s){ NUTContext *nut = s->priv_data; AVIOContext *bc = s->pb; int i, j, ret; @@ -691,7 +691,7 @@ static int find_best_header_idx(NUTContext *nut, AVPacket *pkt){ return best_i; } -static int write_packet(AVFormatContext *s, AVPacket *pkt){ +static int nut_write_packet(AVFormatContext *s, AVPacket *pkt){ NUTContext *nut = s->priv_data; StreamContext *nus= &nut->stream[pkt->stream_index]; AVIOContext *bc = s->pb, *dyn_bc; @@ -845,7 +845,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt){ return 0; } -static int write_trailer(AVFormatContext *s){ +static int nut_write_trailer(AVFormatContext *s){ NUTContext *nut= s->priv_data; AVIOContext *bc= s->pb; @@ -874,9 +874,9 @@ AVOutputFormat ff_nut_muxer = { .audio_codec = CODEC_ID_MP2, #endif .video_codec = CODEC_ID_MPEG4, - .write_header = write_header, - .write_packet = write_packet, - .write_trailer = write_trailer, + .write_header = nut_write_header, + .write_packet = nut_write_packet, + .write_trailer = nut_write_trailer, .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, .codec_tag = (const AVCodecTag * const []){ ff_codec_bmp_tags, ff_nut_video_tags, ff_codec_wav_tags, ff_nut_subtitle_tags, 0 }, }; -- cgit v1.2.3 From 346ea9e22240b4442f479518f6c3b40c9bec9487 Mon Sep 17 00:00:00 2001 From: Stefan Fritsch Date: Sun, 4 Sep 2011 10:56:24 +0200 Subject: http: Consider the stream as seekable if the reply contains Accept-Ranges: bytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The initial request contains "Range: 0-", which servers normally have responded with "HTTP/1.1 206 Partial Content" reply with a Content-Range header, which was used as indicator for seekability. Apache, since 2.2.20, responds with "HTTP/1.1 200 OK" for these requests, which is more friendly to caches and proxies, but the seekability still is indicated via the Accept-Ranges: bytes header. Signed-off-by: Martin Storsjö --- libavformat/http.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/http.c b/libavformat/http.c index aa8c6657db..a20bfdfe66 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -265,6 +265,8 @@ static int process_line(URLContext *h, char *line, int line_count, s->filesize = atoll(slash+1); } h->is_streamed = 0; /* we _can_ in fact seek */ + } else if (!strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5)) { + h->is_streamed = 0; } else if (!strcasecmp (tag, "Transfer-Encoding") && !strncasecmp(p, "chunked", 7)) { s->filesize = -1; s->chunksize = 0; -- cgit v1.2.3 From dad09ff93f5df1ec987493f404d43cd16991e992 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 29 Aug 2011 07:03:24 +0200 Subject: cmdutils: move exit_program() declaration to cmdutils from avconv Allows cmdutils to call each tool's own cleanup function. --- avconv.c | 6 +-- avplay.c | 5 +++ avprobe.c | 5 +++ avserver.c | 5 +++ cmdutils.c | 15 ++++--- cmdutils.h | 6 +++ ffmpeg.c | 146 ++++++++++++++++++++++++++++++------------------------------- 7 files changed, 105 insertions(+), 83 deletions(-) diff --git a/avconv.c b/avconv.c index b2dce53fff..52a71085fa 100644 --- a/avconv.c +++ b/avconv.c @@ -433,7 +433,7 @@ static int decode_interrupt_cb(void) return received_nb_signals > 1; } -static int exit_program(int ret) +void exit_program(int ret) { int i; @@ -483,7 +483,6 @@ static int exit_program(int ret) } exit(ret); /* not all OS-es handle main() return value */ - return ret; } static void assert_avoptions(AVDictionary *m) @@ -4192,5 +4191,6 @@ int main(int argc, char **argv) printf("bench: utime=%0.3fs maxrss=%ikB\n", ti / 1000000.0, maxrss); } - return exit_program(0); + exit_program(0); + return 0; } diff --git a/avplay.c b/avplay.c index 1880668d65..212ab2c9b2 100644 --- a/avplay.c +++ b/avplay.c @@ -278,6 +278,11 @@ static AVPacket flush_pkt; static SDL_Surface *screen; +void exit_program(int ret) +{ + exit(ret); +} + static int packet_queue_put(PacketQueue *q, AVPacket *pkt); /* packet queue handling */ diff --git a/avprobe.c b/avprobe.c index f0ba6bae09..a8a0f14eb7 100644 --- a/avprobe.c +++ b/avprobe.c @@ -56,6 +56,11 @@ static const char *unit_hertz_str = "Hz" ; static const char *unit_byte_str = "byte" ; static const char *unit_bit_per_second_str = "bit/s"; +void exit_program(int ret) +{ + exit(ret); +} + static char *value_string(char *buf, int buf_size, double val, const char *unit) { if (unit == unit_second_str && use_value_sexagesimal_format) { diff --git a/avserver.c b/avserver.c index 2b028a3f4e..1b11cbf973 100644 --- a/avserver.c +++ b/avserver.c @@ -320,6 +320,11 @@ static AVLFG random_state; static FILE *logfile = NULL; +void exit_program(int ret) +{ + exit(ret); +} + /* FIXME: make avserver work with IPv6 */ /* resolve host with also IP address parsing */ static int resolve_host(struct in_addr *sin_addr, const char *hostname) diff --git a/cmdutils.c b/cmdutils.c index a6402af596..a86c55bc6d 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -92,7 +92,8 @@ double parse_number_or_die(const char *context, const char *numstr, int type, do else return d; fprintf(stderr, error, context, numstr, min, max); - exit(1); + exit_program(1); + return 0; } int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration) @@ -101,7 +102,7 @@ int64_t parse_time_or_die(const char *context, const char *timestr, int is_durat if (av_parse_time(&us, timestr, is_duration) < 0) { fprintf(stderr, "Invalid %s specification for %s: %s\n", is_duration ? "duration" : "date", context, timestr); - exit(1); + exit_program(1); } return us; } @@ -237,14 +238,14 @@ void parse_options(int argc, char **argv, const OptionDef *options, if (!po->name) { unknown_opt: fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt); - exit(1); + exit_program(1); } arg = NULL; if (po->flags & HAS_ARG) { arg = argv[optindex++]; if (!arg) { fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt); - exit(1); + exit_program(1); } } if (po->flags & OPT_STRING) { @@ -262,11 +263,11 @@ unknown_opt: } else if (po->u.func_arg) { if (po->u.func_arg(opt, arg) < 0) { fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt); - exit(1); + exit_program(1); } } if(po->flags & OPT_EXIT) - exit(0); + exit_program(0); } else { if (parse_arg_function) parse_arg_function(opt); @@ -336,7 +337,7 @@ int opt_loglevel(const char *opt, const char *arg) "Possible levels are numbers or:\n", arg); for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) fprintf(stderr, "\"%s\"\n", log_levels[i].name); - exit(1); + exit_program(1); } av_log_set_level(level); return 0; diff --git a/cmdutils.h b/cmdutils.h index 48ea213bde..65b1ae48b7 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -327,4 +327,10 @@ extern AVFilter ffsink; int get_filtered_video_frame(AVFilterContext *sink, AVFrame *frame, AVFilterBufferRef **picref, AVRational *pts_tb); +/** + * Do all the necessary cleanup and abort. + * This function is implemented in the avtools, not cmdutils. + */ +void exit_program(int ret); + #endif /* LIBAV_CMDUTILS_H */ diff --git a/ffmpeg.c b/ffmpeg.c index 36d870172e..eec028f8eb 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -445,7 +445,7 @@ static int decode_interrupt_cb(void) return received_nb_signals > 1; } -static int ffmpeg_exit(int ret) +void exit_program(int ret) { int i; @@ -501,7 +501,6 @@ static int ffmpeg_exit(int ret) } exit(ret); /* not all OS-es handle main() return value */ - return ret; } static void assert_avoptions(AVDictionary *m) @@ -509,7 +508,7 @@ static void assert_avoptions(AVDictionary *m) AVDictionaryEntry *t; if ((t = av_dict_get(m, "", NULL, AV_DICT_IGNORE_SUFFIX))) { av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key); - ffmpeg_exit(1); + exit_program(1); } } @@ -526,7 +525,7 @@ static void assert_codec_experimental(AVCodecContext *c, int encoder) if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL)) av_log(NULL, AV_LOG_ERROR, "Or use the non experimental %s '%s'.\n", codec_string, codec->name); - ffmpeg_exit(1); + exit_program(1); } } @@ -535,13 +534,13 @@ 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); + exit_program(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); + exit_program(1); } memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size); *size = new_size; @@ -664,7 +663,7 @@ static OutputStream *new_output_stream(AVFormatContext *oc, int file_idx, AVCode if (!st) { av_log(NULL, AV_LOG_ERROR, "Could not alloc stream.\n"); - ffmpeg_exit(1); + exit_program(1); } output_streams_for_file[file_idx] = @@ -676,7 +675,7 @@ static OutputStream *new_output_stream(AVFormatContext *oc, int file_idx, AVCode av_mallocz(sizeof(OutputStream)); if (!ost) { fprintf(stderr, "Could not alloc output stream\n"); - ffmpeg_exit(1); + exit_program(1); } ost->file_index = file_idx; ost->index = idx; @@ -756,7 +755,7 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx avctx->codec ? avctx->codec->name : "copy"); print_error("", a); if (exit_on_error) - ffmpeg_exit(1); + exit_program(1); } *pkt= new_pkt; @@ -766,7 +765,7 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx ret= av_interleaved_write_frame(s, pkt); if(ret < 0){ print_error("av_interleaved_write_frame()", ret); - ffmpeg_exit(1); + exit_program(1); } } @@ -802,14 +801,14 @@ need_realloc: if(audio_out_size > INT_MAX || audio_buf_size > INT_MAX){ fprintf(stderr, "Buffer sizes too large\n"); - ffmpeg_exit(1); + exit_program(1); } av_fast_malloc(&audio_buf, &allocated_audio_buf_size, audio_buf_size); av_fast_malloc(&audio_out, &allocated_audio_out_size, audio_out_size); if (!audio_buf || !audio_out){ fprintf(stderr, "Out of memory in do_audio_out\n"); - ffmpeg_exit(1); + exit_program(1); } if (enc->channels != dec->channels || enc->sample_rate != dec->sample_rate) @@ -849,7 +848,7 @@ need_realloc: 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); + exit_program(1); } } } @@ -865,7 +864,7 @@ need_realloc: fprintf(stderr, "Cannot convert %s sample format to %s sample format\n", av_get_sample_fmt_name(dec->sample_fmt), av_get_sample_fmt_name(enc->sample_fmt)); - ffmpeg_exit(1); + exit_program(1); } ost->reformat_pair=MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt); } @@ -938,7 +937,7 @@ need_realloc: if (av_audio_convert(ost->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) { printf("av_audio_convert() failed\n"); if (exit_on_error) - ffmpeg_exit(1); + exit_program(1); return; } buftmp = audio_buf; @@ -950,7 +949,7 @@ need_realloc: /* output resampled raw samples */ if (av_fifo_realloc2(ost->fifo, av_fifo_size(ost->fifo) + size_out) < 0) { fprintf(stderr, "av_fifo_realloc2() failed\n"); - ffmpeg_exit(1); + exit_program(1); } av_fifo_generic_write(ost->fifo, buftmp, size_out, NULL); @@ -968,7 +967,7 @@ need_realloc: (short *)audio_buf); if (ret < 0) { fprintf(stderr, "Audio encoding failed\n"); - ffmpeg_exit(1); + exit_program(1); } audio_size += ret; pkt.stream_index= ost->index; @@ -995,7 +994,7 @@ need_realloc: if(size_out > audio_out_size){ fprintf(stderr, "Internal error, buffer size too small\n"); - ffmpeg_exit(1); + exit_program(1); } //FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio() @@ -1003,7 +1002,7 @@ need_realloc: (short *)buftmp); if (ret < 0) { fprintf(stderr, "Audio encoding failed\n"); - ffmpeg_exit(1); + exit_program(1); } audio_size += ret; pkt.stream_index= ost->index; @@ -1073,7 +1072,7 @@ 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) - ffmpeg_exit(1); + exit_program(1); return; } @@ -1101,7 +1100,7 @@ static void do_subtitle_out(AVFormatContext *s, subtitle_out_max_size, sub); if (subtitle_out_size < 0) { fprintf(stderr, "Subtitle encoding failed\n"); - ffmpeg_exit(1); + exit_program(1); } av_init_packet(&pkt); @@ -1188,7 +1187,7 @@ static void do_video_out(AVFormatContext *s, ost->resample_width, ost->resample_height, av_get_pix_fmt_name(ost->resample_pix_fmt), dec->width , dec->height , av_get_pix_fmt_name(dec->pix_fmt)); if(!ost->video_resample) - ffmpeg_exit(1); + exit_program(1); } #if !CONFIG_AVFILTER @@ -1207,7 +1206,7 @@ static void do_video_out(AVFormatContext *s, ost->sws_flags, NULL, NULL, NULL); if (ost->img_resample_ctx == NULL) { fprintf(stderr, "Cannot get resampling context\n"); - ffmpeg_exit(1); + exit_program(1); } } sws_scale(ost->img_resample_ctx, formatted_picture->data, formatted_picture->linesize, @@ -1267,7 +1266,7 @@ static void do_video_out(AVFormatContext *s, &big_picture); if (ret < 0) { fprintf(stderr, "Video encoding failed\n"); - ffmpeg_exit(1); + exit_program(1); } if(ret>0){ @@ -1313,7 +1312,7 @@ static void do_video_stats(AVFormatContext *os, OutputStream *ost, vstats_file = fopen(vstats_filename, "w"); if (!vstats_file) { perror("fopen"); - ffmpeg_exit(1); + exit_program(1); } } @@ -1818,7 +1817,7 @@ static int output_packet(InputStream *ist, int ist_index, } else { /* pad */ int frame_bytes = enc->frame_size*osize*enc->channels; if (allocated_audio_buf_size < frame_bytes) - ffmpeg_exit(1); + exit_program(1); generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes); } @@ -1832,7 +1831,7 @@ static int output_packet(InputStream *ist, int ist_index, } if (ret < 0) { fprintf(stderr, "Audio encoding failed\n"); - ffmpeg_exit(1); + exit_program(1); } audio_size += ret; pkt.flags |= AV_PKT_FLAG_KEY; @@ -1841,7 +1840,7 @@ static int output_packet(InputStream *ist, int ist_index, ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL); if (ret < 0) { fprintf(stderr, "Video encoding failed\n"); - ffmpeg_exit(1); + exit_program(1); } video_size += ret; if(enc->coded_frame && enc->coded_frame->key_frame) @@ -1933,7 +1932,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"); - ffmpeg_exit(1); + exit_program(1); } for (i = 0; i < n; i++) { p = i ? strchr(p, ',') + 1 : kf; @@ -2024,7 +2023,7 @@ static int transcode(AVFormatContext **output_files, fprintf(stderr, "Codec type mismatch for mapping #%d.%d -> #%d.%d\n", stream_maps[n].file_index, stream_maps[n].stream_index, ost->file_index, ost->index); - ffmpeg_exit(1); + exit_program(1); } } else { @@ -2074,7 +2073,7 @@ static int transcode(AVFormatContext **output_files, av_dump_format(output_files[i], i, output_files[i]->filename, 1); fprintf(stderr, "Could not find input stream matching output stream #%d.%d\n", ost->file_index, ost->index); - ffmpeg_exit(1); + exit_program(1); } } } @@ -2139,7 +2138,7 @@ static int transcode(AVFormatContext **output_files, case AVMEDIA_TYPE_AUDIO: if(audio_volume != 256) { fprintf(stderr,"-acodec copy and -vol are incompatible (frames are not decoded)\n"); - ffmpeg_exit(1); + exit_program(1); } codec->channel_layout = icodec->channel_layout; codec->sample_rate = icodec->sample_rate; @@ -2213,7 +2212,7 @@ static int transcode(AVFormatContext **output_files, if (ost->st->codec->pix_fmt == PIX_FMT_NONE) { fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n"); - ffmpeg_exit(1); + exit_program(1); } if (!codec->width || !codec->height) { @@ -2230,7 +2229,7 @@ static int transcode(AVFormatContext **output_files, if(avpicture_alloc((AVPicture*)&ost->pict_tmp, codec->pix_fmt, codec->width, codec->height)) { fprintf(stderr, "Cannot allocate temp picture, check pix fmt\n"); - ffmpeg_exit(1); + exit_program(1); } ost->img_resample_ctx = sws_getContext( icodec->width, @@ -2242,7 +2241,7 @@ static int transcode(AVFormatContext **output_files, ost->sws_flags, NULL, NULL, NULL); if (ost->img_resample_ctx == NULL) { fprintf(stderr, "Cannot get resampling context\n"); - ffmpeg_exit(1); + exit_program(1); } #endif codec->bits_per_raw_sample= 0; @@ -2290,7 +2289,7 @@ static int transcode(AVFormatContext **output_files, f = fopen(logfilename, "wb"); if (!f) { fprintf(stderr, "Cannot write log file '%s' for pass-1 encoding: %s\n", logfilename, strerror(errno)); - ffmpeg_exit(1); + exit_program(1); } ost->logfile = f; } else { @@ -2298,7 +2297,7 @@ static int transcode(AVFormatContext **output_files, 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); - ffmpeg_exit(1); + exit_program(1); } codec->stats_in = logbuffer; } @@ -2670,7 +2669,7 @@ static int transcode(AVFormatContext **output_files, fprintf(stderr, "Error while decoding stream #%d.%d\n", ist->file_index, ist->st->index); if (exit_on_error) - ffmpeg_exit(1); + exit_program(1); av_free_packet(&pkt); goto redo; } @@ -2785,7 +2784,7 @@ static int opt_frame_rate(const char *opt, const char *arg) { if (av_parse_video_rate(&frame_rate, arg) < 0) { fprintf(stderr, "Incorrect value for %s: %s\n", opt, arg); - ffmpeg_exit(1); + exit_program(1); } return 0; } @@ -2820,7 +2819,7 @@ static int opt_frame_pix_fmt(const char *opt, const char *arg) } } else { show_pix_fmts(); - ffmpeg_exit(0); + exit_program(0); } return 0; } @@ -2856,7 +2855,7 @@ static int opt_metadata(const char *opt, const char *arg) if(!mid){ fprintf(stderr, "Missing =\n"); - ffmpeg_exit(1); + exit_program(1); } *mid++= 0; @@ -2904,7 +2903,7 @@ static int opt_audio_sample_fmt(const char *opt, const char *arg) 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)); - ffmpeg_exit(0); + exit_program(0); } return 0; } @@ -3026,7 +3025,7 @@ static void parse_meta_type(char *arg, char *type, int *index, char **endptr) break; default: fprintf(stderr, "Invalid metadata type %c.\n", *arg); - ffmpeg_exit(1); + exit_program(1); } } else *type = 'g'; @@ -3142,11 +3141,11 @@ static enum CodecID find_codec_or_die(const char *name, int type, int encoder) avcodec_find_decoder_by_name(name); if(!codec) { fprintf(stderr, "Unknown %s '%s'\n", codec_string, name); - ffmpeg_exit(1); + exit_program(1); } if(codec->type != type) { fprintf(stderr, "Invalid %s type '%s'\n", codec_string, name); - ffmpeg_exit(1); + exit_program(1); } return codec->id; } @@ -3164,7 +3163,7 @@ static int opt_input_file(const char *opt, const char *filename) if (last_asked_format) { if (!(file_iformat = av_find_input_format(last_asked_format))) { fprintf(stderr, "Unknown input format: '%s'\n", last_asked_format); - ffmpeg_exit(1); + exit_program(1); } last_asked_format = NULL; } @@ -3179,7 +3178,7 @@ static int opt_input_file(const char *opt, const char *filename) ic = avformat_alloc_context(); if (!ic) { print_error(filename, AVERROR(ENOMEM)); - ffmpeg_exit(1); + exit_program(1); } if (audio_sample_rate) { snprintf(buf, sizeof(buf), "%d", audio_sample_rate); @@ -3212,7 +3211,7 @@ static int opt_input_file(const char *opt, const char *filename) err = avformat_open_input(&ic, filename, file_iformat, &format_opts); if (err < 0) { print_error(filename, err); - ffmpeg_exit(1); + exit_program(1); } assert_avoptions(format_opts); @@ -3235,7 +3234,7 @@ static int opt_input_file(const char *opt, const char *filename) } if(!found){ fprintf(stderr, "Specified program id not found\n"); - ffmpeg_exit(1); + exit_program(1); } opt_programid=0; } @@ -3255,7 +3254,7 @@ static int opt_input_file(const char *opt, const char *filename) if (ret < 0 && verbose >= 0) { fprintf(stderr, "%s: could not find codec parameters\n", filename); av_close_input_file(ic); - ffmpeg_exit(1); + exit_program(1); } timestamp = start_time; @@ -3491,7 +3490,7 @@ static void new_video_stream(AVFormatContext *oc, int file_idx) int e=sscanf(p, "%d,%d,%d", &start, &end, &q); if(e!=3){ fprintf(stderr, "error parsing rc_override\n"); - ffmpeg_exit(1); + exit_program(1); } video_enc->rc_override= av_realloc(video_enc->rc_override, @@ -3615,7 +3614,7 @@ static void new_data_stream(AVFormatContext *oc, int file_idx) data_enc = st->codec; if (!data_stream_copy) { fprintf(stderr, "Data stream encoding not supported yet (only streamcopy)\n"); - ffmpeg_exit(1); + exit_program(1); } data_enc->codec_type = AVMEDIA_TYPE_DATA; @@ -3689,7 +3688,7 @@ static int opt_new_stream(const char *opt, const char *arg) int file_idx = nb_output_files - 1; if (nb_output_files <= 0) { fprintf(stderr, "At least one output file must be specified\n"); - ffmpeg_exit(1); + exit_program(1); } oc = output_files[file_idx]; @@ -3714,7 +3713,7 @@ static int opt_streamid(const char *opt, const char *arg) fprintf(stderr, "Invalid value '%s' for option '%s', required syntax is 'index:value'\n", arg, opt); - ffmpeg_exit(1); + exit_program(1); } *p++ = '\0'; idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, INT_MAX); @@ -3736,14 +3735,14 @@ static void opt_output_file(const char *filename) oc = avformat_alloc_context(); if (!oc) { print_error(filename, AVERROR(ENOMEM)); - ffmpeg_exit(1); + exit_program(1); } if (last_asked_format) { file_oformat = av_guess_format(last_asked_format, NULL, NULL); if (!file_oformat) { fprintf(stderr, "Requested output format '%s' is not a suitable output format\n", last_asked_format); - ffmpeg_exit(1); + exit_program(1); } last_asked_format = NULL; } else { @@ -3751,7 +3750,7 @@ static void opt_output_file(const char *filename) if (!file_oformat) { fprintf(stderr, "Unable to find a suitable output format for '%s'\n", filename); - ffmpeg_exit(1); + exit_program(1); } } @@ -3765,7 +3764,7 @@ static void opt_output_file(const char *filename) int err = read_avserver_streams(oc, filename); if (err < 0) { print_error(filename, err); - ffmpeg_exit(1); + exit_program(1); } } else { use_video = file_oformat->video_codec != CODEC_ID_NONE || video_stream_copy || video_codec_name; @@ -3810,7 +3809,7 @@ static void opt_output_file(const char *filename) if (oc->oformat->flags & AVFMT_NEEDNUMBER) { if (!av_filename_number_test(oc->filename)) { print_error(oc->filename, AVERROR(EINVAL)); - ffmpeg_exit(1); + exit_program(1); } } @@ -3826,12 +3825,12 @@ static void opt_output_file(const char *filename) fflush(stderr); if (!read_yesno()) { fprintf(stderr, "Not overwriting - exiting\n"); - ffmpeg_exit(1); + exit_program(1); } } else { fprintf(stderr,"File '%s' already exists. Exiting.\n", filename); - ffmpeg_exit(1); + exit_program(1); } } } @@ -3839,7 +3838,7 @@ static void opt_output_file(const char *filename) /* open the file */ if ((err = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) { print_error(filename, err); - ffmpeg_exit(1); + exit_program(1); } } @@ -3917,7 +3916,7 @@ static void parse_matrix_coeffs(uint16_t *dest, const char *str) p = strchr(p, ','); if(!p) { fprintf(stderr, "Syntax error in matrix \"%s\" at coeff %d\n", str, i); - ffmpeg_exit(1); + exit_program(1); } p++; } @@ -4065,7 +4064,7 @@ static int opt_target(const char *opt, const char *arg) fprintf(stderr, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n"); fprintf(stderr, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n"); fprintf(stderr, "or set a framerate with \"-r xxx\".\n"); - ffmpeg_exit(1); + exit_program(1); } if(!strcmp(arg, "vcd")) { @@ -4182,7 +4181,7 @@ static int opt_bsf(const char *opt, const char *arg) if(!bsfc){ fprintf(stderr, "Unknown bitstream filter %s\n", arg); - ffmpeg_exit(1); + exit_program(1); } bsfp= *opt == 'v' ? &video_bitstream_filters : @@ -4206,7 +4205,7 @@ static int opt_preset(const char *opt, const char *arg) if (!(f = get_preset_file(filename, sizeof(filename), arg, *opt == 'f', codec_name))) { fprintf(stderr, "File for preset '%s' not found\n", arg); - ffmpeg_exit(1); + exit_program(1); } while(!feof(f)){ @@ -4216,7 +4215,7 @@ static int opt_preset(const char *opt, const char *arg) e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2; if(e){ fprintf(stderr, "%s: Invalid syntax: '%s'\n", filename, line); - ffmpeg_exit(1); + exit_program(1); } if(!strcmp(tmp, "acodec")){ opt_audio_codec(tmp, tmp2); @@ -4228,7 +4227,7 @@ static int opt_preset(const char *opt, const char *arg) opt_data_codec(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); - ffmpeg_exit(1); + exit_program(1); } } @@ -4402,29 +4401,30 @@ int main(int argc, char **argv) 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"); - ffmpeg_exit(1); + exit_program(1); } /* file converter / grab */ if (nb_output_files <= 0) { fprintf(stderr, "At least one output file must be specified\n"); - ffmpeg_exit(1); + exit_program(1); } if (nb_input_files == 0) { fprintf(stderr, "At least one input file must be specified\n"); - ffmpeg_exit(1); + exit_program(1); } ti = getutime(); if (transcode(output_files, nb_output_files, input_files, nb_input_files, stream_maps, nb_stream_maps) < 0) - ffmpeg_exit(1); + exit_program(1); ti = getutime() - ti; if (do_benchmark) { int maxrss = getmaxrss() / 1024; printf("bench: utime=%0.3fs maxrss=%ikB\n", ti / 1000000.0, maxrss); } - return ffmpeg_exit(0); + exit_program(0); + return 0; } -- cgit v1.2.3 From cac651c83417dde3b64a6620cac32f078c9c399f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 29 Aug 2011 07:11:57 +0200 Subject: cmdutils: move grow_array() from avconv to cmdutils. --- avconv.c | 20 -------------------- cmdutils.c | 19 +++++++++++++++++++ cmdutils.h | 10 ++++++++++ ffmpeg.c | 20 -------------------- 4 files changed, 29 insertions(+), 40 deletions(-) diff --git a/avconv.c b/avconv.c index 52a71085fa..33da836a90 100644 --- a/avconv.c +++ b/avconv.c @@ -511,26 +511,6 @@ static void assert_codec_experimental(AVCodecContext *c, int encoder) } } -/* 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"); - exit_program(1); - } - if (*size < new_size) { - uint8_t *tmp = av_realloc(array, new_size*elem_size); - if (!tmp) { - fprintf(stderr, "Could not alloc buffer.\n"); - exit_program(1); - } - memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size); - *size = new_size; - return tmp; - } - return array; -} - static void choose_sample_fmt(AVStream *st, AVCodec *codec) { if(codec && codec->sample_fmts){ diff --git a/cmdutils.c b/cmdutils.c index a86c55bc6d..9e34e43128 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -931,4 +931,23 @@ int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame, return 1; } +void *grow_array(void *array, int elem_size, int *size, int new_size) +{ + if (new_size >= INT_MAX / elem_size) { + av_log(NULL, AV_LOG_ERROR, "Array too big.\n"); + exit_program(1); + } + if (*size < new_size) { + uint8_t *tmp = av_realloc(array, new_size*elem_size); + if (!tmp) { + av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n"); + exit_program(1); + } + memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size); + *size = new_size; + return tmp; + } + return array; +} + #endif /* CONFIG_AVFILTER */ diff --git a/cmdutils.h b/cmdutils.h index 65b1ae48b7..2173f0d34b 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -333,4 +333,14 @@ int get_filtered_video_frame(AVFilterContext *sink, AVFrame *frame, */ void exit_program(int ret); +/** + * Realloc array to hold new_size elements of elem_size. + * Calls exit_program() on failure. + * + * @param elem_size size in bytes of each element + * @param size new element count will be written here + * @return reallocated array + */ +void *grow_array(void *array, int elem_size, int *size, int new_size); + #endif /* LIBAV_CMDUTILS_H */ diff --git a/ffmpeg.c b/ffmpeg.c index eec028f8eb..242cd3ffa7 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -529,26 +529,6 @@ static void assert_codec_experimental(AVCodecContext *c, int encoder) } } -/* 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"); - exit_program(1); - } - if (*size < new_size) { - uint8_t *tmp = av_realloc(array, new_size*elem_size); - if (!tmp) { - fprintf(stderr, "Could not alloc buffer.\n"); - exit_program(1); - } - memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size); - *size = new_size; - return tmp; - } - return array; -} - static void choose_sample_fmt(AVStream *st, AVCodec *codec) { if(codec && codec->sample_fmts){ -- cgit v1.2.3 From 7efe05ab298ae18437c9796f43b9f47474763a39 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 28 Aug 2011 14:27:27 +0200 Subject: cmdutils: declare only one pointer type in OptionDef This will be useful in the following commit. --- cmdutils.c | 12 +++++++----- cmdutils.h | 5 +---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/cmdutils.c b/cmdutils.c index 9e34e43128..53ef7aed3c 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -216,6 +216,7 @@ void parse_options(int argc, char **argv, const OptionDef *options, /* parse options */ optindex = 1; while (optindex < argc) { + void *dst; opt = argv[optindex++]; if (handleoptions && opt[0] == '-' && opt[1] != '\0') { @@ -248,18 +249,19 @@ unknown_opt: exit_program(1); } } + dst = po->u.dst_ptr; if (po->flags & OPT_STRING) { char *str; str = av_strdup(arg); - *po->u.str_arg = str; + *(char**)dst = str; } else if (po->flags & OPT_BOOL) { - *po->u.int_arg = bool_val; + *(int*)dst = bool_val; } else if (po->flags & OPT_INT) { - *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX); + *(int*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX); } else if (po->flags & OPT_INT64) { - *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX); + *(int64_t*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX); } else if (po->flags & OPT_FLOAT) { - *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY); + *(float*)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY); } else if (po->u.func_arg) { if (po->u.func_arg(opt, arg) < 0) { fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt); diff --git a/cmdutils.h b/cmdutils.h index 2173f0d34b..e72c730fa7 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -125,11 +125,8 @@ typedef struct { #define OPT_EXIT 0x0800 #define OPT_DATA 0x1000 union { - int *int_arg; - char **str_arg; - float *float_arg; + void *dst_ptr; int (*func_arg)(const char *, const char *); - int64_t *int64_arg; } u; const char *help; const char *argname; -- cgit v1.2.3 From 7cc8d6385aaf1005700305f21d5d56b51b38c537 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 28 Aug 2011 14:43:54 +0200 Subject: cmdutils: add support for caller-provided option context. This is the first step to removing the globals plague from avtools. --- avconv.c | 4 ++-- avplay.c | 4 ++-- avprobe.c | 4 ++-- avserver.c | 2 +- cmdutils.c | 14 +++++++++----- cmdutils.h | 10 ++++++++-- ffmpeg.c | 4 ++-- 7 files changed, 26 insertions(+), 16 deletions(-) diff --git a/avconv.c b/avconv.c index 33da836a90..92273f1ce7 100644 --- a/avconv.c +++ b/avconv.c @@ -3403,7 +3403,7 @@ static int read_avserver_streams(AVFormatContext *s, const char *filename) return 0; } -static void opt_output_file(const char *filename) +static void opt_output_file(void *optctx, const char *filename) { AVFormatContext *oc; int i, err; @@ -4143,7 +4143,7 @@ int main(int argc, char **argv) show_banner(); /* parse options */ - parse_options(argc, argv, options, opt_output_file); + parse_options(NULL, argc, argv, options, opt_output_file); if(nb_output_files <= 0 && nb_input_files == 0) { show_usage(); diff --git a/avplay.c b/avplay.c index 212ab2c9b2..198dce1d2b 100644 --- a/avplay.c +++ b/avplay.c @@ -3015,7 +3015,7 @@ static void show_help(void) ); } -static void opt_input_file(const char *filename) +static void opt_input_file(void *optctx, const char *filename) { if (input_filename) { fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n", @@ -3048,7 +3048,7 @@ int main(int argc, char **argv) show_banner(); - parse_options(argc, argv, options, opt_input_file); + parse_options(NULL, argc, argv, options, opt_input_file); if (!input_filename) { show_usage(); diff --git a/avprobe.c b/avprobe.c index a8a0f14eb7..5e83916f87 100644 --- a/avprobe.c +++ b/avprobe.c @@ -346,7 +346,7 @@ static int opt_format(const char *opt, const char *arg) return 0; } -static void opt_input_file(const char *arg) +static void opt_input_file(void *optctx, const char *arg) { if (input_filename) { fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n", @@ -406,7 +406,7 @@ int main(int argc, char **argv) #endif show_banner(); - parse_options(argc, argv, options, opt_input_file); + parse_options(NULL, argc, argv, options, opt_input_file); if (!input_filename) { show_usage(); diff --git a/avserver.c b/avserver.c index 1b11cbf973..df9d07d1ad 100644 --- a/avserver.c +++ b/avserver.c @@ -4676,7 +4676,7 @@ int main(int argc, char **argv) my_program_dir = getcwd(0, 0); avserver_daemon = 1; - parse_options(argc, argv, options, NULL); + parse_options(NULL, argc, argv, options, NULL); unsetenv("http_proxy"); /* Kill the http_proxy */ diff --git a/cmdutils.c b/cmdutils.c index 53ef7aed3c..ea25836f8f 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -203,8 +203,8 @@ static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr) } #endif /* WIN32 && !__MINGW32CE__ */ -void parse_options(int argc, char **argv, const OptionDef *options, - void (* parse_arg_function)(const char*)) +void parse_options(void *optctx, int argc, char **argv, const OptionDef *options, + void (* parse_arg_function)(void *, const char*)) { const char *opt, *arg; int optindex, handleoptions=1; @@ -249,7 +249,9 @@ unknown_opt: exit_program(1); } } - dst = po->u.dst_ptr; + /* new-style options contain an offset into optctx, old-style address of + * a global var*/ + dst = po->flags & OPT_OFFSET ? (uint8_t*)optctx + po->u.off : po->u.dst_ptr; if (po->flags & OPT_STRING) { char *str; str = av_strdup(arg); @@ -263,7 +265,9 @@ unknown_opt: } else if (po->flags & OPT_FLOAT) { *(float*)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY); } else if (po->u.func_arg) { - if (po->u.func_arg(opt, arg) < 0) { + int ret = po->flags & OPT_FUNC2 ? po->u.func2_arg(optctx, opt, arg) : + po->u.func_arg(opt, arg); + if (ret < 0) { fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt); exit_program(1); } @@ -272,7 +276,7 @@ unknown_opt: exit_program(0); } else { if (parse_arg_function) - parse_arg_function(opt); + parse_arg_function(optctx, opt); } } } diff --git a/cmdutils.h b/cmdutils.h index e72c730fa7..a4716cad61 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -124,9 +124,13 @@ typedef struct { #define OPT_INT64 0x0400 #define OPT_EXIT 0x0800 #define OPT_DATA 0x1000 +#define OPT_FUNC2 0x2000 +#define OPT_OFFSET 0x4000 /* option is specified as an offset in a passed optctx */ union { void *dst_ptr; int (*func_arg)(const char *, const char *); + int (*func2_arg)(void *, const char *, const char *); + size_t off; } u; const char *help; const char *argname; @@ -136,14 +140,16 @@ void show_help_options(const OptionDef *options, const char *msg, int mask, int /** * Parse the command line arguments. + * + * @param optctx an opaque options context * @param options Array with the definitions required to interpret every * option of the form: -option_name [argument] * @param parse_arg_function Name of the function called to process every * argument without a leading option name flag. NULL if such arguments do * not have to be processed. */ -void parse_options(int argc, char **argv, const OptionDef *options, - void (* parse_arg_function)(const char*)); +void parse_options(void *optctx, int argc, char **argv, const OptionDef *options, + void (* parse_arg_function)(void *optctx, const char*)); /** * Check if the given stream matches a stream specifier. diff --git a/ffmpeg.c b/ffmpeg.c index 242cd3ffa7..a440b9dacb 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -3702,7 +3702,7 @@ static int opt_streamid(const char *opt, const char *arg) return 0; } -static void opt_output_file(const char *filename) +static void opt_output_file(void *optctx, const char *filename) { AVFormatContext *oc; int err, use_video, use_audio, use_subtitle, use_data; @@ -4376,7 +4376,7 @@ int main(int argc, char **argv) "(see Changelog for the list of incompatible changes).\n"); /* parse options */ - parse_options(argc, argv, options, opt_output_file); + parse_options(NULL, argc, argv, options, opt_output_file); if(nb_output_files <= 0 && nb_input_files == 0) { show_usage(); -- cgit v1.2.3 From 2f8e586df14649ebf1538dc610928c844e0068ec Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 29 Aug 2011 08:11:03 +0200 Subject: cmdutils: split per-option code out of parse_options(). This allows options like -target, which are just shortcuts for other options, to work without dummy function for all options they invoke. --- cmdutils.c | 112 +++++++++++++++++++++++++++++++++---------------------------- cmdutils.h | 7 ++++ 2 files changed, 67 insertions(+), 52 deletions(-) diff --git a/cmdutils.c b/cmdutils.c index ea25836f8f..1eed404647 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -203,12 +203,66 @@ static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr) } #endif /* WIN32 && !__MINGW32CE__ */ +int parse_option(void *optctx, const char *opt, const char *arg, const OptionDef *options) +{ + const OptionDef *po; + int bool_val = 1; + void *dst; + + po = find_option(options, opt); + if (!po->name && opt[0] == 'n' && opt[1] == 'o') { + /* handle 'no' bool option */ + po = find_option(options, opt + 2); + if (!(po->name && (po->flags & OPT_BOOL))) + goto unknown_opt; + bool_val = 0; + } + if (!po->name) + po = find_option(options, "default"); + if (!po->name) { +unknown_opt: + av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt); + return AVERROR(EINVAL); + } + if (po->flags & HAS_ARG && !arg) { + av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'\n", opt); + return AVERROR(EINVAL); + } + + /* new-style options contain an offset into optctx, old-style address of + * a global var*/ + dst = po->flags & (OPT_OFFSET) ? (uint8_t*)optctx + po->u.off : po->u.dst_ptr; + + if (po->flags & OPT_STRING) { + char *str; + str = av_strdup(arg); + *(char**)dst = str; + } else if (po->flags & OPT_BOOL) { + *(int*)dst = bool_val; + } else if (po->flags & OPT_INT) { + *(int*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX); + } else if (po->flags & OPT_INT64) { + *(int64_t*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX); + } else if (po->flags & OPT_FLOAT) { + *(float*)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY); + } else if (po->u.func_arg) { + int ret = po->flags & OPT_FUNC2 ? po->u.func2_arg(optctx, opt, arg) : + po->u.func_arg(opt, arg); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Failed to set value '%s' for option '%s'\n", arg, opt); + return ret; + } + } + if (po->flags & OPT_EXIT) + exit_program(0); + return !!(po->flags & HAS_ARG); +} + void parse_options(void *optctx, int argc, char **argv, const OptionDef *options, void (* parse_arg_function)(void *, const char*)) { - const char *opt, *arg; - int optindex, handleoptions=1; - const OptionDef *po; + const char *opt; + int optindex, handleoptions = 1, ret; /* perform system-dependent conversions for arguments list */ prepare_app_arguments(&argc, &argv); @@ -216,64 +270,18 @@ void parse_options(void *optctx, int argc, char **argv, const OptionDef *options /* parse options */ optindex = 1; while (optindex < argc) { - void *dst; opt = argv[optindex++]; if (handleoptions && opt[0] == '-' && opt[1] != '\0') { - int bool_val = 1; if (opt[1] == '-' && opt[2] == '\0') { handleoptions = 0; continue; } opt++; - po= find_option(options, opt); - if (!po->name && opt[0] == 'n' && opt[1] == 'o') { - /* handle 'no' bool option */ - po = find_option(options, opt + 2); - if (!(po->name && (po->flags & OPT_BOOL))) - goto unknown_opt; - bool_val = 0; - } - if (!po->name) - po= find_option(options, "default"); - if (!po->name) { -unknown_opt: - fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt); + + if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0) exit_program(1); - } - arg = NULL; - if (po->flags & HAS_ARG) { - arg = argv[optindex++]; - if (!arg) { - fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt); - exit_program(1); - } - } - /* new-style options contain an offset into optctx, old-style address of - * a global var*/ - dst = po->flags & OPT_OFFSET ? (uint8_t*)optctx + po->u.off : po->u.dst_ptr; - if (po->flags & OPT_STRING) { - char *str; - str = av_strdup(arg); - *(char**)dst = str; - } else if (po->flags & OPT_BOOL) { - *(int*)dst = bool_val; - } else if (po->flags & OPT_INT) { - *(int*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX); - } else if (po->flags & OPT_INT64) { - *(int64_t*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX); - } else if (po->flags & OPT_FLOAT) { - *(float*)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY); - } else if (po->u.func_arg) { - int ret = po->flags & OPT_FUNC2 ? po->u.func2_arg(optctx, opt, arg) : - po->u.func_arg(opt, arg); - if (ret < 0) { - fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt); - exit_program(1); - } - } - if(po->flags & OPT_EXIT) - exit_program(0); + optindex += ret; } else { if (parse_arg_function) parse_arg_function(optctx, opt); diff --git a/cmdutils.h b/cmdutils.h index a4716cad61..f0c9079647 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -151,6 +151,13 @@ void show_help_options(const OptionDef *options, const char *msg, int mask, int void parse_options(void *optctx, int argc, char **argv, const OptionDef *options, void (* parse_arg_function)(void *optctx, const char*)); +/** + * Parse one given option. + * + * @return on success 1 if arg was consumed, 0 otherwise; negative number on error + */ +int parse_option(void *optctx, const char *opt, const char *arg, const OptionDef *options); + /** * Check if the given stream matches a stream specifier. * -- cgit v1.2.3 From 6361c5e1e61033259e91b480f23ae81bed775c8b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 29 Aug 2011 07:54:56 +0200 Subject: cmdutils: allow storing per-stream/chapter/.... options in a generic way --- cmdutils.c | 13 ++++++++++++- cmdutils.h | 13 +++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/cmdutils.c b/cmdutils.c index 1eed404647..6c64d47d01 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -207,6 +207,7 @@ int parse_option(void *optctx, const char *opt, const char *arg, const OptionDef { const OptionDef *po; int bool_val = 1; + int *dstcount; void *dst; po = find_option(options, opt); @@ -231,7 +232,17 @@ unknown_opt: /* new-style options contain an offset into optctx, old-style address of * a global var*/ - dst = po->flags & (OPT_OFFSET) ? (uint8_t*)optctx + po->u.off : po->u.dst_ptr; + dst = po->flags & (OPT_OFFSET|OPT_SPEC) ? (uint8_t*)optctx + po->u.off : po->u.dst_ptr; + + if (po->flags & OPT_SPEC) { + SpecifierOpt **so = dst; + char *p = strchr(opt, ':'); + + dstcount = (int*)(so + 1); + *so = grow_array(*so, sizeof(**so), dstcount, *dstcount + 1); + (*so)[*dstcount - 1].specifier = av_strdup(p ? p + 1 : ""); + dst = &(*so)[*dstcount - 1].u; + } if (po->flags & OPT_STRING) { char *str; diff --git a/cmdutils.h b/cmdutils.h index f0c9079647..003c928fc6 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -108,6 +108,16 @@ double parse_number_or_die(const char *context, const char *numstr, int type, do */ int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration); +typedef struct SpecifierOpt { + char *specifier; /**< stream/chapter/program/... specifier */ + union { + uint8_t *str; + int i; + int64_t i64; + float f; + } u; +} SpecifierOpt; + typedef struct { const char *name; int flags; @@ -126,6 +136,9 @@ typedef struct { #define OPT_DATA 0x1000 #define OPT_FUNC2 0x2000 #define OPT_OFFSET 0x4000 /* option is specified as an offset in a passed optctx */ +#define OPT_SPEC 0x8000 /* option is to be stored in an array of SpecifierOpt. + Implies OPT_OFFSET. Next element after the offset is + an int containing element count in the array. */ union { void *dst_ptr; int (*func_arg)(const char *, const char *); -- cgit v1.2.3 From 575ec4e17d4e9824bc015651dc99f0c778402866 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 28 Aug 2011 17:21:56 +0200 Subject: avconv: add a context for options. Move stream maps to it. Eventually all non-global options should be stored in it. --- avconv.c | 79 +++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/avconv.c b/avconv.c index 92273f1ce7..d1b99cdce1 100644 --- a/avconv.c +++ b/avconv.c @@ -100,9 +100,6 @@ static const OptionDef options[]; static const char *last_asked_format = NULL; static AVDictionary *ts_scale; -static StreamMap *stream_maps = NULL; -static int nb_stream_maps; - static AVDictionary *codec_names; /* first item specifies output metadata, second is input */ @@ -317,6 +314,42 @@ static int nb_output_streams = 0; static OutputFile *output_files = NULL; static int nb_output_files = 0; +typedef struct OptionsContext { + /* output options */ + StreamMap *stream_maps; + int nb_stream_maps; +} OptionsContext; + +static void reset_options(OptionsContext *o) +{ + const OptionDef *po = options; + + /* all OPT_SPEC and OPT_STRING can be freed in generic way */ + while (po->name) { + void *dst = (uint8_t*)o + po->u.off; + + if (po->flags & OPT_SPEC) { + SpecifierOpt **so = dst; + int i, *count = (int*)(so + 1); + for (i = 0; i < *count; i++) { + av_freep(&(*so)[i].specifier); + if (po->flags & OPT_STRING) + av_freep(&(*so)[i].u.str); + } + av_freep(so); + *count = 0; + } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING) + av_freep(dst); + po++; + } + + av_freep(&o->stream_maps); + + memset(o, 0, sizeof(*o)); + uninit_opts(); + init_opts(); +} + #if CONFIG_AVFILTER static int configure_video_filters(InputStream *ist, OutputStream *ost) @@ -2609,7 +2642,7 @@ static int opt_codec_tag(const char *opt, const char *arg) return 0; } -static int opt_map(const char *opt, const char *arg) +static int opt_map(OptionsContext *o, const char *opt, const char *arg) { StreamMap *m = NULL; int i, negative = 0, file_idx; @@ -2654,8 +2687,8 @@ static int opt_map(const char *opt, const char *arg) } if (negative) /* disable some already defined maps */ - for (i = 0; i < nb_stream_maps; i++) { - m = &stream_maps[i]; + for (i = 0; i < o->nb_stream_maps; i++) { + m = &o->stream_maps[i]; if (check_stream_specifier(input_files[m->file_index].ctx, input_files[m->file_index].ctx->streams[m->stream_index], *p == ':' ? p + 1 : p) > 0) @@ -2666,8 +2699,9 @@ static int opt_map(const char *opt, const char *arg) if (check_stream_specifier(input_files[file_idx].ctx, input_files[file_idx].ctx->streams[i], *p == ':' ? p + 1 : p) <= 0) continue; - stream_maps = grow_array(stream_maps, sizeof(*stream_maps), &nb_stream_maps, nb_stream_maps + 1); - m = &stream_maps[nb_stream_maps - 1]; + o->stream_maps = grow_array(o->stream_maps, sizeof(*o->stream_maps), + &o->nb_stream_maps, o->nb_stream_maps + 1); + m = &o->stream_maps[o->nb_stream_maps - 1]; m->file_index = file_idx; m->stream_index = i; @@ -2896,7 +2930,7 @@ static void add_input_streams(AVFormatContext *ic) } } -static int opt_input_file(const char *opt, const char *filename) +static int opt_input_file(OptionsContext *o, const char *opt, const char *filename) { AVFormatContext *ic; AVInputFormat *file_iformat = NULL; @@ -3039,8 +3073,8 @@ static int opt_input_file(const char *opt, const char *filename) av_dict_free(&opts[i]); av_freep(&opts); av_dict_free(&codec_names); - uninit_opts(); - init_opts(); + + reset_options(o); return 0; } @@ -3405,6 +3439,7 @@ static int read_avserver_streams(AVFormatContext *s, const char *filename) static void opt_output_file(void *optctx, const char *filename) { + OptionsContext *o = optctx; AVFormatContext *oc; int i, err; AVOutputFormat *file_oformat; @@ -3448,7 +3483,7 @@ static void opt_output_file(void *optctx, const char *filename) print_error(filename, err); exit_program(1); } - } else if (!nb_stream_maps) { + } else if (!o->nb_stream_maps) { /* pick the "best" stream of each type */ #define NEW_STREAM(type, index)\ if (index >= 0) {\ @@ -3496,8 +3531,8 @@ static void opt_output_file(void *optctx, const char *filename) } /* do something with data? */ } else { - for (i = 0; i < nb_stream_maps; i++) { - StreamMap *map = &stream_maps[i]; + for (i = 0; i < o->nb_stream_maps; i++) { + StreamMap *map = &o->stream_maps[i]; if (map->disabled) continue; @@ -3665,16 +3700,13 @@ static void opt_output_file(void *optctx, const char *filename) metadata_global_autocopy = 1; metadata_streams_autocopy = 1; metadata_chapters_autocopy = 1; - av_freep(&stream_maps); - nb_stream_maps = 0; av_freep(&streamid_map); nb_streamid_map = 0; av_dict_free(&codec_names); av_freep(&forced_key_frames); - uninit_opts(); - init_opts(); + reset_options(o); } /* same option as mencoder */ @@ -4014,11 +4046,11 @@ static const OptionDef options[] = { /* main options */ #include "cmdutils_common_opts.h" { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" }, - { "i", HAS_ARG, {(void*)opt_input_file}, "input file name", "filename" }, + { "i", HAS_ARG | OPT_FUNC2, {(void*)opt_input_file}, "input file name", "filename" }, { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" }, { "c", HAS_ARG, {(void*)opt_codec}, "codec name", "codec" }, { "codec", HAS_ARG, {(void*)opt_codec}, "codec name", "codec" }, - { "map", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" }, + { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" }, { "map_metadata", HAS_ARG | OPT_EXPERT, {(void*)opt_map_metadata}, "set metadata information of outfile from infile", "outfile[,metadata]:infile[,metadata]" }, { "map_chapters", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&chapters_input_file}, "set chapters mapping", "input_file_index" }, @@ -4123,8 +4155,11 @@ static const OptionDef options[] = { int main(int argc, char **argv) { + OptionsContext o = { 0 }; int64_t ti; + reset_options(&o); + av_log_set_flags(AV_LOG_SKIP_REPEATED); avcodec_register_all(); @@ -4138,12 +4173,10 @@ int main(int argc, char **argv) avio_set_interrupt_cb(decode_interrupt_cb); - init_opts(); - show_banner(); /* parse options */ - parse_options(NULL, argc, argv, options, opt_output_file); + parse_options(&o, argc, argv, options, opt_output_file); if(nb_output_files <= 0 && nb_input_files == 0) { show_usage(); -- cgit v1.2.3 From 6b779cccaab1856575b1840e09510b0f54e988a6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 28 Aug 2011 18:20:17 +0200 Subject: avconv: move start_time, recording_time and input_ts_offset to options context --- avconv.c | 68 +++++++++++++++++++----------------------------- cmdutils.c | 2 ++ cmdutils.h | 1 + tests/fate.mak | 4 +-- tests/fate2.mak | 2 +- tests/lavf-regression.sh | 4 +-- 6 files changed, 35 insertions(+), 46 deletions(-) diff --git a/avconv.c b/avconv.c index d1b99cdce1..1e354ff58d 100644 --- a/avconv.c +++ b/avconv.c @@ -158,9 +158,6 @@ static unsigned int data_codec_tag = 0; static float mux_preload= 0.5; static float mux_max_delay= 0.7; -static int64_t recording_time = INT64_MAX; -static int64_t start_time = 0; -static int64_t input_ts_offset = 0; static int file_overwrite = 0; static AVDictionary *metadata; static int do_benchmark = 0; @@ -315,9 +312,17 @@ static OutputFile *output_files = NULL; static int nb_output_files = 0; typedef struct OptionsContext { + /* input/output options */ + int64_t start_time; + + /* input options */ + int64_t input_ts_offset; + /* output options */ StreamMap *stream_maps; int nb_stream_maps; + + int64_t recording_time; } OptionsContext; static void reset_options(OptionsContext *o) @@ -346,6 +351,9 @@ static void reset_options(OptionsContext *o) av_freep(&o->stream_maps); memset(o, 0, sizeof(*o)); + + o->recording_time = INT64_MAX; + uninit_opts(); init_opts(); } @@ -2778,24 +2786,6 @@ static int opt_input_ts_scale(const char *opt, const char *arg) return av_dict_set(&ts_scale, opt, arg, 0); } -static int opt_recording_time(const char *opt, const char *arg) -{ - recording_time = parse_time_or_die(opt, arg, 1); - return 0; -} - -static int opt_start_time(const char *opt, const char *arg) -{ - start_time = parse_time_or_die(opt, arg, 1); - return 0; -} - -static int opt_input_ts_offset(const char *opt, const char *arg) -{ - input_ts_offset = parse_time_or_die(opt, arg, 1); - return 0; -} - static enum CodecID find_codec_or_die(const char *name, enum AVMediaType type, int encoder) { const char *codec_string = encoder ? "encoder" : "decoder"; @@ -3030,20 +3020,18 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena exit_program(1); } - timestamp = start_time; + timestamp = o->start_time; /* add the stream start time */ if (ic->start_time != AV_NOPTS_VALUE) timestamp += ic->start_time; /* if seeking requested, we execute it */ - if (start_time != 0) { + if (o->start_time != 0) { ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD); if (ret < 0) { fprintf(stderr, "%s: could not seek to position %0.3f\n", filename, (double)timestamp / AV_TIME_BASE); } - /* reset seek info */ - start_time = 0; } /* update the current parameters so that they match the one of the input stream */ @@ -3056,7 +3044,7 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena input_files = grow_array(input_files, sizeof(*input_files), &nb_input_files, nb_input_files + 1); input_files[nb_input_files - 1].ctx = ic; input_files[nb_input_files - 1].ist_index = nb_input_streams - ic->nb_streams; - input_files[nb_input_files - 1].ts_offset = input_ts_offset - (copy_ts ? 0 : timestamp); + input_files[nb_input_files - 1].ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp); input_files[nb_input_files - 1].nb_streams = ic->nb_streams; frame_rate = (AVRational){0, 0}; @@ -3067,7 +3055,6 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena audio_channels = 0; audio_sample_fmt = AV_SAMPLE_FMT_NONE; av_dict_free(&ts_scale); - input_ts_offset = 0; for (i = 0; i < orig_nb_streams; i++) av_dict_free(&opts[i]); @@ -3364,18 +3351,18 @@ static int opt_streamid(const char *opt, const char *arg) return 0; } -static int copy_chapters(int infile, int outfile) +static int copy_chapters(InputFile *ifile, OutputFile *ofile) { - AVFormatContext *is = input_files[infile].ctx; - AVFormatContext *os = output_files[outfile].ctx; + AVFormatContext *is = ifile->ctx; + AVFormatContext *os = ofile->ctx; 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[infile].ts_offset, + int64_t ts_off = av_rescale_q(ofile->start_time - ifile->ts_offset, 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); + int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX : + av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base); if (in_ch->end < ts_off) @@ -3563,8 +3550,8 @@ static void opt_output_file(void *optctx, const char *filename) output_files = grow_array(output_files, sizeof(*output_files), &nb_output_files, nb_output_files + 1); output_files[nb_output_files - 1].ctx = oc; output_files[nb_output_files - 1].ost_index = nb_output_streams - oc->nb_streams; - output_files[nb_output_files - 1].recording_time = recording_time; - output_files[nb_output_files - 1].start_time = start_time; + output_files[nb_output_files - 1].recording_time = o->recording_time; + output_files[nb_output_files - 1].start_time = o->start_time; output_files[nb_output_files - 1].limit_filesize = limit_filesize; av_dict_copy(&output_files[nb_output_files - 1].opts, format_opts, 0); @@ -3626,7 +3613,7 @@ static void opt_output_file(void *optctx, const char *filename) } } if (chapters_input_file >= 0) - copy_chapters(chapters_input_file, nb_output_files - 1); + copy_chapters(&input_files[chapters_input_file], &output_files[nb_output_files - 1]); /* copy metadata */ for (i = 0; i < nb_meta_data_maps; i++) { @@ -3691,8 +3678,6 @@ static void opt_output_file(void *optctx, const char *filename) audio_channels = 0; audio_sample_fmt = AV_SAMPLE_FMT_NONE; chapters_input_file = INT_MAX; - recording_time = INT64_MAX; - start_time = 0; limit_filesize = UINT64_MAX; av_freep(&meta_data_maps); @@ -4042,6 +4027,7 @@ static int opt_bsf(const char *opt, const char *arg) return 0; } +#define OFFSET(x) offsetof(OptionsContext, x) static const OptionDef options[] = { /* main options */ #include "cmdutils_common_opts.h" @@ -4054,10 +4040,10 @@ static const OptionDef options[] = { { "map_metadata", HAS_ARG | OPT_EXPERT, {(void*)opt_map_metadata}, "set metadata information of outfile from infile", "outfile[,metadata]:infile[,metadata]" }, { "map_chapters", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&chapters_input_file}, "set chapters mapping", "input_file_index" }, - { "t", HAS_ARG, {(void*)opt_recording_time}, "record or transcode \"duration\" seconds of audio/video", "duration" }, + { "t", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(recording_time)}, "record or transcode \"duration\" seconds of audio/video", "duration" }, { "fs", HAS_ARG | OPT_INT64, {(void*)&limit_filesize}, "set the limit file size in bytes", "limit_size" }, // - { "ss", HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" }, - { "itsoffset", HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" }, + { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(start_time)}, "set the start time offset", "time_off" }, + { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(input_ts_offset)}, "set the input ts offset", "time_off" }, { "itsscale", HAS_ARG, {(void*)opt_input_ts_scale}, "set the input ts scale", "scale" }, { "metadata", HAS_ARG, {(void*)opt_metadata}, "add metadata", "string=string" }, { "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[AVMEDIA_TYPE_DATA]}, "set the number of data frames to record", "number" }, diff --git a/cmdutils.c b/cmdutils.c index 6c64d47d01..3a41f45dbd 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -254,6 +254,8 @@ unknown_opt: *(int*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX); } else if (po->flags & OPT_INT64) { *(int64_t*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX); + } else if (po->flags & OPT_TIME) { + *(int64_t*)dst = parse_time_or_die(opt, arg, 1); } else if (po->flags & OPT_FLOAT) { *(float*)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY); } else if (po->u.func_arg) { diff --git a/cmdutils.h b/cmdutils.h index 003c928fc6..61cfc229b7 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -139,6 +139,7 @@ typedef struct { #define OPT_SPEC 0x8000 /* option is to be stored in an array of SpecifierOpt. Implies OPT_OFFSET. Next element after the offset is an int containing element count in the array. */ +#define OPT_TIME 0x10000 union { void *dst_ptr; int (*func_arg)(const char *, const char *); diff --git a/tests/fate.mak b/tests/fate.mak index 0e3331178b..a349e5cf23 100644 --- a/tests/fate.mak +++ b/tests/fate.mak @@ -35,7 +35,7 @@ fate-bink-demux-video: CMD = framecrc -i $(SAMPLES)/bink/hol2br.bik FATE_TESTS += fate-caf fate-caf: CMD = crc -i $(SAMPLES)/caf/caf-pcm16.caf FATE_TESTS += fate-cdgraphics -fate-cdgraphics: CMD = framecrc -t 1 -i $(SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgb24 +fate-cdgraphics: CMD = framecrc -i $(SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgb24 -t 1 FATE_TESTS += fate-cljr fate-cljr: CMD = framecrc -i $(SAMPLES)/cljr/testcljr-partial.avi FATE_TESTS += fate-corepng @@ -129,7 +129,7 @@ fate-id-cin-video: CMD = framecrc -i $(SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rg FATE_TESTS += fate-idroq-video-dpcm fate-idroq-video-dpcm: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq FATE_TESTS += fate-idroq-video-encode -fate-idroq-video-encode: CMD = md5 -t 0.2 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f RoQ +fate-idroq-video-encode: CMD = md5 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f RoQ -t 0.2 FATE_TESTS += fate-iff-byterun1 fate-iff-byterun1: CMD = framecrc -i $(SAMPLES)/iff/ASH.LBM -pix_fmt rgb24 FATE_TESTS += fate-iff-fibonacci diff --git a/tests/fate2.mak b/tests/fate2.mak index a743f0cd59..6a01412eb3 100644 --- a/tests/fate2.mak +++ b/tests/fate2.mak @@ -125,7 +125,7 @@ fate-atrac3-3: CMP = oneoff fate-atrac3-3: REF = $(SAMPLES)/atrac3/mc_sich_at3_132_small.pcm FATE_TESTS += fate-gsm -fate-gsm: CMD = framecrc -t 10 -i $(SAMPLES)/gsm/sample-gsm-8000.mov +fate-gsm: CMD = framecrc -i $(SAMPLES)/gsm/sample-gsm-8000.mov -t 10 FATE_TESTS += fate-gsm-ms fate-gsm-ms: CMD = framecrc -i $(SAMPLES)/gsm/ciao.wav diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh index 1d7f640124..303e7bd1ac 100755 --- a/tests/lavf-regression.sh +++ b/tests/lavf-regression.sh @@ -227,8 +227,8 @@ conversions="yuv420p yuv422p yuv444p yuyv422 yuv410p yuv411p yuvj420p \ monob yuv440p yuvj440p" for pix_fmt in $conversions ; do file=${outfile}${pix_fmt}.yuv - run_avconv $DEC_OPTS -r 1 -t 1 -f image2 -vcodec pgmyuv -i $raw_src \ - $ENC_OPTS -f rawvideo -s 352x288 -pix_fmt $pix_fmt $target_path/$raw_dst + run_avconv $DEC_OPTS -r 1 -f image2 -vcodec pgmyuv -i $raw_src \ + $ENC_OPTS -f rawvideo -t 1 -s 352x288 -pix_fmt $pix_fmt $target_path/$raw_dst do_avconv $file $DEC_OPTS -f rawvideo -s 352x288 -pix_fmt $pix_fmt -i $target_path/$raw_dst \ $ENC_OPTS -f rawvideo -s 352x288 -pix_fmt yuv444p done -- cgit v1.2.3 From 13ccba50d45662a15777b549b2fcd9b4621b0e01 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 28 Aug 2011 18:20:17 +0200 Subject: avconv: move limit_filesize to options context --- avconv.c | 8 ++++---- tests/fate/mp3.mak | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/avconv.c b/avconv.c index 1e354ff58d..a3ab7b94cc 100644 --- a/avconv.c +++ b/avconv.c @@ -190,7 +190,6 @@ static int64_t extra_size = 0; static int nb_frames_dup = 0; static int nb_frames_drop = 0; static int input_sync; -static uint64_t limit_filesize = UINT64_MAX; static int force_fps = 0; static char *forced_key_frames = NULL; @@ -323,6 +322,7 @@ typedef struct OptionsContext { int nb_stream_maps; int64_t recording_time; + uint64_t limit_filesize; } OptionsContext; static void reset_options(OptionsContext *o) @@ -353,6 +353,7 @@ static void reset_options(OptionsContext *o) memset(o, 0, sizeof(*o)); o->recording_time = INT64_MAX; + o->limit_filesize = UINT64_MAX; uninit_opts(); init_opts(); @@ -3552,7 +3553,7 @@ static void opt_output_file(void *optctx, const char *filename) output_files[nb_output_files - 1].ost_index = nb_output_streams - oc->nb_streams; output_files[nb_output_files - 1].recording_time = o->recording_time; output_files[nb_output_files - 1].start_time = o->start_time; - output_files[nb_output_files - 1].limit_filesize = limit_filesize; + output_files[nb_output_files - 1].limit_filesize = o->limit_filesize; av_dict_copy(&output_files[nb_output_files - 1].opts, format_opts, 0); /* check filename in case of an image number is expected */ @@ -3678,7 +3679,6 @@ static void opt_output_file(void *optctx, const char *filename) audio_channels = 0; audio_sample_fmt = AV_SAMPLE_FMT_NONE; chapters_input_file = INT_MAX; - limit_filesize = UINT64_MAX; av_freep(&meta_data_maps); nb_meta_data_maps = 0; @@ -4041,7 +4041,7 @@ static const OptionDef options[] = { "outfile[,metadata]:infile[,metadata]" }, { "map_chapters", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&chapters_input_file}, "set chapters mapping", "input_file_index" }, { "t", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(recording_time)}, "record or transcode \"duration\" seconds of audio/video", "duration" }, - { "fs", HAS_ARG | OPT_INT64, {(void*)&limit_filesize}, "set the limit file size in bytes", "limit_size" }, // + { "fs", HAS_ARG | OPT_INT64 | OPT_OFFSET, {.off = OFFSET(limit_filesize)}, "set the limit file size in bytes", "limit_size" }, // { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(start_time)}, "set the start time offset", "time_off" }, { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(input_ts_offset)}, "set the input ts offset", "time_off" }, { "itsscale", HAS_ARG, {(void*)opt_input_ts_scale}, "set the input ts scale", "scale" }, diff --git a/tests/fate/mp3.mak b/tests/fate/mp3.mak index 859a4f3802..9dfa829008 100644 --- a/tests/fate/mp3.mak +++ b/tests/fate/mp3.mak @@ -4,32 +4,32 @@ fate-mp3-float-conf-compl: CMP = stddev fate-mp3-float-conf-compl: REF = $(SAMPLES)/mp3-conformance/compl.pcm FATE_MP3 += fate-mp3-float-conf-he_32khz -fate-mp3-float-conf-he_32khz: CMD = pcm -acodec mp3float -fs 343296 -i $(SAMPLES)/mp3-conformance/he_32khz.bit +fate-mp3-float-conf-he_32khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_32khz.bit -fs 343296 fate-mp3-float-conf-he_32khz: CMP = stddev fate-mp3-float-conf-he_32khz: REF = $(SAMPLES)/mp3-conformance/he_32khz.pcm FATE_MP3 += fate-mp3-float-conf-he_44khz -fate-mp3-float-conf-he_44khz: CMD = pcm -acodec mp3float -fs 942336 -i $(SAMPLES)/mp3-conformance/he_44khz.bit +fate-mp3-float-conf-he_44khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_44khz.bit -fs 942336 fate-mp3-float-conf-he_44khz: CMP = stddev fate-mp3-float-conf-he_44khz: REF = $(SAMPLES)/mp3-conformance/he_44khz.pcm FATE_MP3 += fate-mp3-float-conf-he_48khz -fate-mp3-float-conf-he_48khz: CMD = pcm -acodec mp3float -fs 343296 -i $(SAMPLES)/mp3-conformance/he_48khz.bit +fate-mp3-float-conf-he_48khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_48khz.bit -fs 343296 fate-mp3-float-conf-he_48khz: CMP = stddev fate-mp3-float-conf-he_48khz: REF = $(SAMPLES)/mp3-conformance/he_48khz.pcm FATE_MP3 += fate-mp3-float-conf-hecommon -fate-mp3-float-conf-hecommon: CMD = pcm -acodec mp3float -fs 133632 -i $(SAMPLES)/mp3-conformance/hecommon.bit +fate-mp3-float-conf-hecommon: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/hecommon.bit -fs 133632 fate-mp3-float-conf-hecommon: CMP = stddev fate-mp3-float-conf-hecommon: REF = $(SAMPLES)/mp3-conformance/hecommon.pcm FATE_MP3 += fate-mp3-float-conf-si -fate-mp3-float-conf-si: CMD = pcm -acodec mp3float -fs 269568 -i $(SAMPLES)/mp3-conformance/si.bit +fate-mp3-float-conf-si: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/si.bit -fs 269568 fate-mp3-float-conf-si: CMP = stddev fate-mp3-float-conf-si: REF = $(SAMPLES)/mp3-conformance/si.pcm FATE_MP3 += fate-mp3-float-conf-si_block -fate-mp3-float-conf-si_block: CMD = pcm -acodec mp3float -fs 145152 -i $(SAMPLES)/mp3-conformance/si_block.bit +fate-mp3-float-conf-si_block: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/si_block.bit -fs 145152 fate-mp3-float-conf-si_block: CMP = stddev fate-mp3-float-conf-si_block: REF = $(SAMPLES)/mp3-conformance/si_block.pcm -- cgit v1.2.3 From 7041bb3b1ad6d1e7fd2fecd51246207af0440ffc Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 28 Aug 2011 18:20:17 +0200 Subject: avconv: move format to options context --- avconv.c | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/avconv.c b/avconv.c index a3ab7b94cc..98eed860ab 100644 --- a/avconv.c +++ b/avconv.c @@ -97,7 +97,6 @@ typedef struct MetadataMap { static const OptionDef options[]; -static const char *last_asked_format = NULL; static AVDictionary *ts_scale; static AVDictionary *codec_names; @@ -313,6 +312,7 @@ static int nb_output_files = 0; typedef struct OptionsContext { /* input/output options */ int64_t start_time; + const char *format; /* input options */ int64_t input_ts_offset; @@ -2465,12 +2465,6 @@ static int transcode(OutputFile *output_files, return ret; } -static int opt_format(const char *opt, const char *arg) -{ - last_asked_format = arg; - return 0; -} - static int opt_video_rc_override_string(const char *opt, const char *arg) { video_rc_override_string = arg; @@ -2931,12 +2925,11 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena AVDictionary **opts; int orig_nb_streams; // number of streams before avformat_find_stream_info - if (last_asked_format) { - if (!(file_iformat = av_find_input_format(last_asked_format))) { - fprintf(stderr, "Unknown input format: '%s'\n", last_asked_format); + if (o->format) { + if (!(file_iformat = av_find_input_format(o->format))) { + fprintf(stderr, "Unknown input format: '%s'\n", o->format); exit_program(1); } - last_asked_format = NULL; } if (!strcmp(filename, "-")) @@ -3443,13 +3436,12 @@ static void opt_output_file(void *optctx, const char *filename) exit_program(1); } - if (last_asked_format) { - file_oformat = av_guess_format(last_asked_format, NULL, NULL); + if (o->format) { + file_oformat = av_guess_format(o->format, NULL, NULL); if (!file_oformat) { - fprintf(stderr, "Requested output format '%s' is not a suitable output format\n", last_asked_format); + fprintf(stderr, "Requested output format '%s' is not a suitable output format\n", o->format); exit_program(1); } - last_asked_format = NULL; } else { file_oformat = av_guess_format(NULL, filename, NULL); if (!file_oformat) { @@ -3843,7 +3835,7 @@ static void show_help(void) av_opt_show2(&class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0); } -static int opt_target(const char *opt, const char *arg) +static int opt_target(OptionsContext *o, const char *opt, const char *arg) { enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN; static const char *const frame_rates[] = {"25", "30000/1001", "24000/1001"}; @@ -3902,7 +3894,7 @@ static int opt_target(const char *opt, const char *arg) if(!strcmp(arg, "vcd")) { opt_codec("c:v", "mpeg1video"); opt_codec("c:a", "mp2"); - opt_format("f", "vcd"); + parse_option(o, "f", "vcd", options); opt_frame_size("s", norm == PAL ? "352x288" : "352x240"); opt_frame_rate("r", frame_rates[norm]); @@ -3930,7 +3922,7 @@ static int opt_target(const char *opt, const char *arg) opt_codec("c:v", "mpeg2video"); opt_codec("c:a", "mp2"); - opt_format("f", "svcd"); + parse_option(o, "f", "svcd", options); opt_frame_size("s", norm == PAL ? "480x576" : "480x480"); opt_frame_rate("r", frame_rates[norm]); @@ -3952,7 +3944,7 @@ static int opt_target(const char *opt, const char *arg) opt_codec("c:v", "mpeg2video"); opt_codec("c:a", "ac3"); - opt_format("f", "dvd"); + parse_option(o, "f", "dvd", options); opt_frame_size("vcodec", norm == PAL ? "720x576" : "720x480"); opt_frame_rate("r", frame_rates[norm]); @@ -3971,7 +3963,7 @@ static int opt_target(const char *opt, const char *arg) } else if(!strncmp(arg, "dv", 2)) { - opt_format("f", "dv"); + parse_option(o, "f", "dv", options); opt_frame_size("s", norm == PAL ? "720x576" : "720x480"); opt_frame_pix_fmt("pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" : @@ -4031,7 +4023,7 @@ static int opt_bsf(const char *opt, const char *arg) static const OptionDef options[] = { /* main options */ #include "cmdutils_common_opts.h" - { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" }, + { "f", HAS_ARG | OPT_STRING | OPT_OFFSET, {.off = OFFSET(format)}, "force format", "fmt" }, { "i", HAS_ARG | OPT_FUNC2, {(void*)opt_input_file}, "input file name", "filename" }, { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" }, { "c", HAS_ARG, {(void*)opt_codec}, "codec name", "codec" }, @@ -4056,7 +4048,7 @@ static const OptionDef options[] = { "when dumping packets, also dump the payload" }, { "re", OPT_BOOL | OPT_EXPERT, {(void*)&rate_emu}, "read input at native frame rate", "" }, { "v", HAS_ARG, {(void*)opt_verbose}, "set the verbosity level", "number" }, - { "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" }, + { "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" }, { "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", "" }, { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" }, -- cgit v1.2.3 From fb47997edb9d8ff16fc380d005a08c0545624aa6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 4 Sep 2011 09:56:47 +0200 Subject: lavc: fix type for thread_type option It should be flags, not int. --- libavcodec/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/options.c b/libavcodec/options.c index 9684ed547b..f910f2e0c8 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -483,7 +483,7 @@ static const AVOption options[]={ {"lpc_passes", "deprecated, use flac-specific options", OFFSET(lpc_passes), FF_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E}, #endif {"slices", "number of slices, used in parallelized decoding", OFFSET(slices), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, V|E}, -{"thread_type", "select multithreading type", OFFSET(thread_type), FF_OPT_TYPE_INT, {.dbl = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|E|D, "thread_type"}, +{"thread_type", "select multithreading type", OFFSET(thread_type), FF_OPT_TYPE_FLAGS, {.dbl = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|E|D, "thread_type"}, {"slice", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, {"frame", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, {"audio_service_type", "audio service type", OFFSET(audio_service_type), FF_OPT_TYPE_INT, {.dbl = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"}, -- cgit v1.2.3