* qatar/master: avconv: add presets rtsp: Expose the flag options via private AVOptions for sdp and rtp, too rtsp: Make the rtsp flags avoptions set via a define rtpenc: Set a default video codec avoptions: Fix av_opt_flag_is_set rtp: Fix ff_rtp_get_payload_type doc: Update the documentation on setting options for RTSP rtsp: Remove the separate filter_source variable rtsp: Accept options via private avoptions instead of URL options rtsp: Simplify AVOption definitions rtsp: Merge the AVOption lists lavfi: port libmpcodecs delogo filter lavfi: port boxblur filter from libmpcodecs lavfi: add negate filter lavfi: add LUT (LookUp Table) generic filters AVOptions: don't segfault on NULL parameter in av_set_options_string() avio: Check for invalid buffer length. mpegenc/mpegtsenc: add muxrate private options. lavf: deprecate AVFormatContext.file_size mov: add support for TV metadata atoms tves, tvsn and stik Conflicts: Changelog doc/filters.texi doc/protocols.texi libavfilter/Makefile libavfilter/allfilters.c libavfilter/avfilter.h libavfilter/formats.c libavfilter/internal.h libavfilter/vf_boxblur.c libavfilter/vf_delogo.c libavfilter/vf_lut.c libavformat/mpegtsenc.c libavformat/utils.c libavformat/version.h libavutil/opt.c Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n0.9
| @@ -347,6 +347,8 @@ typedef struct OptionsContext { | |||||
| int nb_inter_matrices; | int nb_inter_matrices; | ||||
| SpecifierOpt *top_field_first; | SpecifierOpt *top_field_first; | ||||
| int nb_top_field_first; | int nb_top_field_first; | ||||
| SpecifierOpt *presets; | |||||
| int nb_presets; | |||||
| #if CONFIG_AVFILTER | #if CONFIG_AVFILTER | ||||
| SpecifierOpt *filters; | SpecifierOpt *filters; | ||||
| int nb_filters; | int nb_filters; | ||||
| @@ -3087,15 +3089,62 @@ static void parse_forced_key_frames(char *kf, OutputStream *ost, | |||||
| } | } | ||||
| } | } | ||||
| static uint8_t *get_line(AVIOContext *s) | |||||
| { | |||||
| AVIOContext *line; | |||||
| uint8_t *buf; | |||||
| char c; | |||||
| if (avio_open_dyn_buf(&line) < 0) { | |||||
| av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n"); | |||||
| exit_program(1); | |||||
| } | |||||
| while ((c = avio_r8(s)) && c != '\n') | |||||
| avio_w8(line, c); | |||||
| avio_w8(line, 0); | |||||
| avio_close_dyn_buf(line, &buf); | |||||
| return buf; | |||||
| } | |||||
| static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s) | |||||
| { | |||||
| int i, ret = 1; | |||||
| char filename[1000]; | |||||
| const char *base[3] = { getenv("AVCONV_DATADIR"), | |||||
| getenv("HOME"), | |||||
| AVCONV_DATADIR, | |||||
| }; | |||||
| for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) { | |||||
| if (!base[i]) | |||||
| continue; | |||||
| if (codec_name) { | |||||
| snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i], | |||||
| i != 1 ? "" : "/.avconv", codec_name, preset_name); | |||||
| ret = avio_open(s, filename, AVIO_FLAG_READ); | |||||
| } | |||||
| if (ret) { | |||||
| snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i], | |||||
| i != 1 ? "" : "/.avconv", preset_name); | |||||
| ret = avio_open(s, filename, AVIO_FLAG_READ); | |||||
| } | |||||
| } | |||||
| return ret; | |||||
| } | |||||
| static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type) | static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type) | ||||
| { | { | ||||
| OutputStream *ost; | OutputStream *ost; | ||||
| AVStream *st = av_new_stream(oc, oc->nb_streams < o->nb_streamid_map ? o->streamid_map[oc->nb_streams] : 0); | AVStream *st = av_new_stream(oc, oc->nb_streams < o->nb_streamid_map ? o->streamid_map[oc->nb_streams] : 0); | ||||
| int idx = oc->nb_streams - 1; | |||||
| int idx = oc->nb_streams - 1, ret = 0; | |||||
| int64_t max_frames = INT64_MAX; | int64_t max_frames = INT64_MAX; | ||||
| char *bsf = NULL, *next, *codec_tag = NULL; | char *bsf = NULL, *next, *codec_tag = NULL; | ||||
| AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL; | AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL; | ||||
| double qscale = -1; | double qscale = -1; | ||||
| char *buf = NULL, *arg = NULL, *preset = NULL; | |||||
| AVIOContext *s = NULL; | |||||
| if (!st) { | if (!st) { | ||||
| av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n"); | av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n"); | ||||
| @@ -3117,6 +3166,31 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e | |||||
| avcodec_get_context_defaults3(st->codec, ost->enc); | avcodec_get_context_defaults3(st->codec, ost->enc); | ||||
| st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy | st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy | ||||
| MATCH_PER_STREAM_OPT(presets, str, preset, oc, st); | |||||
| if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) { | |||||
| do { | |||||
| buf = get_line(s); | |||||
| if (!buf[0] || buf[0] == '#') { | |||||
| av_free(buf); | |||||
| continue; | |||||
| } | |||||
| if (!(arg = strchr(buf, '='))) { | |||||
| av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n"); | |||||
| exit_program(1); | |||||
| } | |||||
| *arg++ = 0; | |||||
| av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE); | |||||
| av_free(buf); | |||||
| } while (!s->eof_reached); | |||||
| avio_close(s); | |||||
| } | |||||
| if (ret) { | |||||
| av_log(NULL, AV_LOG_FATAL, | |||||
| "Preset %s specified for stream %d:%d, but could not be opened.\n", | |||||
| preset, ost->file_index, ost->index); | |||||
| exit_program(1); | |||||
| } | |||||
| MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st); | MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st); | ||||
| ost->max_frames = max_frames; | ost->max_frames = max_frames; | ||||
| @@ -4027,6 +4101,7 @@ static const OptionDef options[] = { | |||||
| { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" }, | { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" }, | ||||
| { "c", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, | { "c", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, | ||||
| { "codec", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, | { "codec", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, | ||||
| { "pre", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(presets)}, "preset name", "preset" }, | |||||
| { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(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 | OPT_FUNC2, {(void*)opt_map_metadata}, "set metadata information of outfile from infile", | { "map_metadata", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_metadata}, "set metadata information of outfile from infile", | ||||
| "outfile[,metadata]:infile[,metadata]" }, | "outfile[,metadata]:infile[,metadata]" }, | ||||
| @@ -186,6 +186,8 @@ codec-dependent. | |||||
| @var{filter_graph} is a description of the filter graph to apply to | @var{filter_graph} is a description of the filter graph to apply to | ||||
| the stream. Use @code{-filters} to show all the available filters | the stream. Use @code{-filters} to show all the available filters | ||||
| (including also sources and sinks). | (including also sources and sinks). | ||||
| @item -pre[:@var{stream_specifier}] @var{preset_name} (@emph{output,per-stream}) | |||||
| Specify the preset for matching stream(s). | |||||
| @item -stats (@emph{global}) | @item -stats (@emph{global}) | ||||
| Print encoding progress/statistics. On by default. | Print encoding progress/statistics. On by default. | ||||
| @@ -770,6 +772,21 @@ quality). | |||||
| @chapter Examples | @chapter Examples | ||||
| @c man begin EXAMPLES | @c man begin EXAMPLES | ||||
| @section Preset files | |||||
| A preset file contains a sequence of @var{option=value} pairs, one for | |||||
| each line, specifying a sequence of options which can be specified also on | |||||
| the command line. Lines starting with the hash ('#') character are ignored and | |||||
| are used to provide comments. Empty lines are also ignored. Check the | |||||
| @file{ffpresets} directory in the Libav source tree for examples. | |||||
| Preset files are specified with the @code{pre} option, this option takes a | |||||
| preset name as input. Avconv searches for a file named @var{preset_name}.avpreset in | |||||
| the directories @file{$AVCONV_DATADIR} (if set), and @file{$HOME/.avconv}, and in | |||||
| the data directory defined at configuration time (usually @file{$PREFIX/share/avconv}) | |||||
| in that order. For example, if the argument is @code{libx264-max}, it will | |||||
| search for the file @file{libx264-max.avpreset}. | |||||
| @section Video and Audio grabbing | @section Video and Audio grabbing | ||||
| If you specify the input format and device then avconv can grab video | If you specify the input format and device then avconv can grab video | ||||
| @@ -432,7 +432,7 @@ horizontal and vertical chroma subsample values. For example for the | |||||
| pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1. | pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1. | ||||
| @end table | @end table | ||||
| The radius must be a non-negative number, and must be not greater than | |||||
| The radius must be a non-negative number, and must not be greater than | |||||
| the value of the expression @code{min(w,h)/2} for the luma and alpha planes, | the value of the expression @code{min(w,h)/2} for the luma and alpha planes, | ||||
| and of @code{min(cw,ch)/2} for the chroma planes. | and of @code{min(cw,ch)/2} for the chroma planes. | ||||
| @@ -246,12 +246,15 @@ supporting it (currently Darwin Streaming Server and Mischa Spiegelmock's | |||||
| The required syntax for a RTSP url is: | The required syntax for a RTSP url is: | ||||
| @example | @example | ||||
| rtsp://@var{hostname}[:@var{port}]/@var{path}[?@var{options}] | |||||
| rtsp://@var{hostname}[:@var{port}]/@var{path} | |||||
| @end example | @end example | ||||
| @var{options} is a @code{&}-separated list. The following options | |||||
| The following options (set on the @file{ffmpeg}/@file{ffplay} command | |||||
| line, or set in code via @code{AVOption}s or in @code{avformat_open_input}), | |||||
| are supported: | are supported: | ||||
| Flags for @code{rtsp_transport}: | |||||
| @table @option | @table @option | ||||
| @item udp | @item udp | ||||
| @@ -261,21 +264,25 @@ Use UDP as lower transport protocol. | |||||
| Use TCP (interleaving within the RTSP control channel) as lower | Use TCP (interleaving within the RTSP control channel) as lower | ||||
| transport protocol. | transport protocol. | ||||
| @item multicast | |||||
| @item udp_multicast | |||||
| Use UDP multicast as lower transport protocol. | Use UDP multicast as lower transport protocol. | ||||
| @item http | @item http | ||||
| Use HTTP tunneling as lower transport protocol, which is useful for | Use HTTP tunneling as lower transport protocol, which is useful for | ||||
| passing proxies. | passing proxies. | ||||
| @item filter_src | |||||
| Accept packets only from negotiated peer address and port. | |||||
| @end table | @end table | ||||
| Multiple lower transport protocols may be specified, in that case they are | Multiple lower transport protocols may be specified, in that case they are | ||||
| tried one at a time (if the setup of one fails, the next one is tried). | tried one at a time (if the setup of one fails, the next one is tried). | ||||
| For the muxer, only the @code{tcp} and @code{udp} options are supported. | For the muxer, only the @code{tcp} and @code{udp} options are supported. | ||||
| Flags for @code{rtsp_flags}: | |||||
| @table @option | |||||
| @item filter_src | |||||
| Accept packets only from negotiated peer address and port. | |||||
| @end table | |||||
| When receiving data over UDP, the demuxer tries to reorder received packets | When receiving data over UDP, the demuxer tries to reorder received packets | ||||
| (since they may arrive out of order, or packets may get lost totally). In | (since they may arrive out of order, or packets may get lost totally). In | ||||
| order for this to be enabled, a maximum delay must be specified in the | order for this to be enabled, a maximum delay must be specified in the | ||||
| @@ -291,13 +298,13 @@ Example command lines: | |||||
| To watch a stream over UDP, with a max reordering delay of 0.5 seconds: | To watch a stream over UDP, with a max reordering delay of 0.5 seconds: | ||||
| @example | @example | ||||
| ffplay -max_delay 500000 rtsp://server/video.mp4?udp | |||||
| ffplay -max_delay 500000 -rtsp_transport udp rtsp://server/video.mp4 | |||||
| @end example | @end example | ||||
| To watch a stream tunneled over HTTP: | To watch a stream tunneled over HTTP: | ||||
| @example | @example | ||||
| ffplay rtsp://server/video.mp4?http | |||||
| ffplay -rtsp_transport http rtsp://server/video.mp4 | |||||
| @end example | @end example | ||||
| To send a stream in realtime to a RTSP server, for others to watch: | To send a stream in realtime to a RTSP server, for others to watch: | ||||
| @@ -355,6 +355,8 @@ typedef struct OptionsContext { | |||||
| int nb_inter_matrices; | int nb_inter_matrices; | ||||
| SpecifierOpt *top_field_first; | SpecifierOpt *top_field_first; | ||||
| int nb_top_field_first; | int nb_top_field_first; | ||||
| SpecifierOpt *presets; | |||||
| int nb_presets; | |||||
| #if CONFIG_AVFILTER | #if CONFIG_AVFILTER | ||||
| SpecifierOpt *filters; | SpecifierOpt *filters; | ||||
| int nb_filters; | int nb_filters; | ||||
| @@ -3202,15 +3204,62 @@ static void parse_forced_key_frames(char *kf, OutputStream *ost) | |||||
| } | } | ||||
| } | } | ||||
| static uint8_t *get_line(AVIOContext *s) | |||||
| { | |||||
| AVIOContext *line; | |||||
| uint8_t *buf; | |||||
| char c; | |||||
| if (avio_open_dyn_buf(&line) < 0) { | |||||
| av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n"); | |||||
| exit_program(1); | |||||
| } | |||||
| while ((c = avio_r8(s)) && c != '\n') | |||||
| avio_w8(line, c); | |||||
| avio_w8(line, 0); | |||||
| avio_close_dyn_buf(line, &buf); | |||||
| return buf; | |||||
| } | |||||
| static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s) | |||||
| { | |||||
| int i, ret = 1; | |||||
| char filename[1000]; | |||||
| const char *base[3] = { getenv("AVCONV_DATADIR"), | |||||
| getenv("HOME"), | |||||
| AVCONV_DATADIR, | |||||
| }; | |||||
| for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) { | |||||
| if (!base[i]) | |||||
| continue; | |||||
| if (codec_name) { | |||||
| snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i], | |||||
| i != 1 ? "" : "/.avconv", codec_name, preset_name); | |||||
| ret = avio_open(s, filename, AVIO_FLAG_READ); | |||||
| } | |||||
| if (ret) { | |||||
| snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i], | |||||
| i != 1 ? "" : "/.avconv", preset_name); | |||||
| ret = avio_open(s, filename, AVIO_FLAG_READ); | |||||
| } | |||||
| } | |||||
| return ret; | |||||
| } | |||||
| static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type) | static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type) | ||||
| { | { | ||||
| OutputStream *ost; | OutputStream *ost; | ||||
| AVStream *st = av_new_stream(oc, oc->nb_streams < o->nb_streamid_map ? o->streamid_map[oc->nb_streams] : 0); | AVStream *st = av_new_stream(oc, oc->nb_streams < o->nb_streamid_map ? o->streamid_map[oc->nb_streams] : 0); | ||||
| int idx = oc->nb_streams - 1; | |||||
| int idx = oc->nb_streams - 1, ret = 0; | |||||
| int64_t max_frames = INT64_MAX; | int64_t max_frames = INT64_MAX; | ||||
| char *bsf = NULL, *next, *codec_tag = NULL; | char *bsf = NULL, *next, *codec_tag = NULL; | ||||
| AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL; | AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL; | ||||
| double qscale = -1; | double qscale = -1; | ||||
| char *buf = NULL, *arg = NULL, *preset = NULL; | |||||
| AVIOContext *s = NULL; | |||||
| if (!st) { | if (!st) { | ||||
| av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n"); | av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n"); | ||||
| @@ -3232,6 +3281,31 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e | |||||
| avcodec_get_context_defaults3(st->codec, ost->enc); | avcodec_get_context_defaults3(st->codec, ost->enc); | ||||
| st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy | st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy | ||||
| MATCH_PER_STREAM_OPT(presets, str, preset, oc, st); | |||||
| if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) { | |||||
| do { | |||||
| buf = get_line(s); | |||||
| if (!buf[0] || buf[0] == '#') { | |||||
| av_free(buf); | |||||
| continue; | |||||
| } | |||||
| if (!(arg = strchr(buf, '='))) { | |||||
| av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n"); | |||||
| exit_program(1); | |||||
| } | |||||
| *arg++ = 0; | |||||
| av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE); | |||||
| av_free(buf); | |||||
| } while (!s->eof_reached); | |||||
| avio_close(s); | |||||
| } | |||||
| if (ret) { | |||||
| av_log(NULL, AV_LOG_FATAL, | |||||
| "Preset %s specified for stream %d:%d, but could not be opened.\n", | |||||
| preset, ost->file_index, ost->index); | |||||
| exit_program(1); | |||||
| } | |||||
| MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st); | MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st); | ||||
| ost->max_frames = max_frames; | ost->max_frames = max_frames; | ||||
| @@ -4209,6 +4283,7 @@ static const OptionDef options[] = { | |||||
| { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" }, | { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" }, | ||||
| { "c", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, | { "c", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, | ||||
| { "codec", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, | { "codec", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, | ||||
| { "pre", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(presets)}, "preset name", "preset" }, | |||||
| { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(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_meta_data", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_meta_data}, "DEPRECATED set meta data information of outfile from infile", | { "map_meta_data", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_meta_data}, "DEPRECATED set meta data information of outfile from infile", | ||||
| "outfile[,metadata]:infile[,metadata]" }, | "outfile[,metadata]:infile[,metadata]" }, | ||||
| @@ -30,7 +30,7 @@ | |||||
| #define LIBAVFILTER_VERSION_MAJOR 2 | #define LIBAVFILTER_VERSION_MAJOR 2 | ||||
| #define LIBAVFILTER_VERSION_MINOR 43 | #define LIBAVFILTER_VERSION_MINOR 43 | ||||
| #define LIBAVFILTER_VERSION_MICRO 6 | |||||
| #define LIBAVFILTER_VERSION_MICRO 7 | |||||
| #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ | #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ | ||||
| LIBAVFILTER_VERSION_MINOR, \ | LIBAVFILTER_VERSION_MINOR, \ | ||||
| @@ -81,7 +81,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) | |||||
| if (!args) { | if (!args) { | ||||
| av_log(ctx, AV_LOG_ERROR, | av_log(ctx, AV_LOG_ERROR, | ||||
| "Filter expects 2 or 4 arguments, none provided\n"); | |||||
| "Filter expects 2 or 4 or 6 arguments, none provided\n"); | |||||
| return AVERROR(EINVAL); | return AVERROR(EINVAL); | ||||
| } | } | ||||
| @@ -342,4 +342,4 @@ AVFilter avfilter_vf_boxblur = { | |||||
| .outputs = (AVFilterPad[]) {{ .name = "default", | .outputs = (AVFilterPad[]) {{ .name = "default", | ||||
| .type = AVMEDIA_TYPE_VIDEO, }, | .type = AVMEDIA_TYPE_VIDEO, }, | ||||
| { .name = NULL}}, | { .name = NULL}}, | ||||
| }; | |||||
| }; | |||||
| @@ -154,9 +154,9 @@ static const char *delogo_get_name(void *ctx) | |||||
| } | } | ||||
| static const AVClass delogo_class = { | static const AVClass delogo_class = { | ||||
| "DelogoContext", | |||||
| delogo_get_name, | |||||
| delogo_options | |||||
| .class_name = "DelogoContext", | |||||
| .item_name = delogo_get_name, | |||||
| .option = delogo_options, | |||||
| }; | }; | ||||
| static int query_formats(AVFilterContext *ctx) | static int query_formats(AVFilterContext *ctx) | ||||
| @@ -285,4 +285,4 @@ AVFilter avfilter_vf_delogo = { | |||||
| .outputs = (AVFilterPad[]) {{ .name = "default", | .outputs = (AVFilterPad[]) {{ .name = "default", | ||||
| .type = AVMEDIA_TYPE_VIDEO, }, | .type = AVMEDIA_TYPE_VIDEO, }, | ||||
| { .name = NULL}}, | { .name = NULL}}, | ||||
| }; | |||||
| }; | |||||
| @@ -350,21 +350,27 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) | |||||
| { .name = NULL}}, \ | { .name = NULL}}, \ | ||||
| } | } | ||||
| #if CONFIG_LUT_FILTER | |||||
| DEFINE_LUT_FILTER(lut, "Compute and apply a lookup table to the RGB/YUV input video.", init); | DEFINE_LUT_FILTER(lut, "Compute and apply a lookup table to the RGB/YUV input video.", init); | ||||
| #endif | |||||
| #if CONFIG_LUTYUV_FILTER | |||||
| DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video.", init); | DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video.", init); | ||||
| #endif | |||||
| #if CONFIG_LUTRGB_FILTER | |||||
| DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video.", init); | DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video.", init); | ||||
| #endif | |||||
| #if CONFIG_NEGATE_FILTER | #if CONFIG_NEGATE_FILTER | ||||
| static int negate_init(AVFilterContext *ctx, const char *args, void *opaque) | static int negate_init(AVFilterContext *ctx, const char *args, void *opaque) | ||||
| { | { | ||||
| LutContext *lut = ctx->priv; | LutContext *lut = ctx->priv; | ||||
| char lut_params[1024]; | |||||
| char lut_params[64]; | |||||
| if (args) | if (args) | ||||
| sscanf(args, "%d", &lut->negate_alpha); | sscanf(args, "%d", &lut->negate_alpha); | ||||
| av_log(ctx, AV_LOG_INFO, "negate_alpha:%d\n", lut->negate_alpha); | |||||
| av_log(ctx, AV_LOG_DEBUG, "negate_alpha:%d\n", lut->negate_alpha); | |||||
| snprintf(lut_params, sizeof(lut_params), "c0=negval:c1=negval:c2=negval:a=%s", | snprintf(lut_params, sizeof(lut_params), "c0=negval:c1=negval:c2=negval:a=%s", | ||||
| lut->negate_alpha ? "negval" : "val"); | lut->negate_alpha ? "negval" : "val"); | ||||
| @@ -374,4 +380,4 @@ static int negate_init(AVFilterContext *ctx, const char *args, void *opaque) | |||||
| DEFINE_LUT_FILTER(negate, "Negate input video.", negate_init); | DEFINE_LUT_FILTER(negate, "Negate input video.", negate_init); | ||||
| #endif | |||||
| #endif | |||||
| @@ -275,9 +275,6 @@ static int aiff_read_header(AVFormatContext *s, | |||||
| got_sound: | got_sound: | ||||
| /* Now positioned, get the sound data start and end */ | /* Now positioned, get the sound data start and end */ | ||||
| if (st->nb_frames) | |||||
| s->file_size = st->nb_frames * st->codec->block_align; | |||||
| av_set_pts_info(st, 64, 1, st->codec->sample_rate); | av_set_pts_info(st, 64, 1, st->codec->sample_rate); | ||||
| st->start_time = 0; | st->start_time = 0; | ||||
| st->duration = st->codec->frame_size ? | st->duration = st->codec->frame_size ? | ||||
| @@ -745,10 +745,12 @@ typedef struct AVFormatContext { | |||||
| */ | */ | ||||
| int64_t duration; | int64_t duration; | ||||
| #if FF_API_FILESIZE | |||||
| /** | /** | ||||
| * decoding: total file size, 0 if unknown | * decoding: total file size, 0 if unknown | ||||
| */ | */ | ||||
| int64_t file_size; | |||||
| attribute_deprecated int64_t file_size; | |||||
| #endif | |||||
| /** | /** | ||||
| * Decoding: total stream bitrate in bit/s, 0 if not | * Decoding: total stream bitrate in bit/s, 0 if not | ||||
| @@ -763,7 +765,12 @@ typedef struct AVFormatContext { | |||||
| /* av_seek_frame() support */ | /* av_seek_frame() support */ | ||||
| int64_t data_offset; /**< offset of the first packet */ | int64_t data_offset; /**< offset of the first packet */ | ||||
| int mux_rate; | |||||
| #if FF_API_MUXRATE | |||||
| /** | |||||
| * use mpeg muxer private options instead | |||||
| */ | |||||
| attribute_deprecated int mux_rate; | |||||
| #endif | |||||
| unsigned int packet_size; | unsigned int packet_size; | ||||
| int preload; | int preload; | ||||
| int max_delay; | int max_delay; | ||||
| @@ -778,13 +778,14 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen) | |||||
| { | { | ||||
| int i; | int i; | ||||
| if (buflen <= 0) | |||||
| return AVERROR(EINVAL); | |||||
| // reserve 1 byte for terminating 0 | // reserve 1 byte for terminating 0 | ||||
| buflen = FFMIN(buflen - 1, maxlen); | buflen = FFMIN(buflen - 1, maxlen); | ||||
| for (i = 0; i < buflen; i++) | for (i = 0; i < buflen; i++) | ||||
| if (!(buf[i] = avio_r8(s))) | if (!(buf[i] = avio_r8(s))) | ||||
| return i + 1; | return i + 1; | ||||
| if (buflen) | |||||
| buf[i] = 0; | |||||
| buf[i] = 0; | |||||
| for (; i < maxlen; i++) | for (; i < maxlen; i++) | ||||
| if (!avio_r8(s)) | if (!avio_r8(s)) | ||||
| return i + 1; | return i + 1; | ||||
| @@ -796,6 +797,8 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen) | |||||
| {\ | {\ | ||||
| char* q = buf;\ | char* q = buf;\ | ||||
| int ret = 0;\ | int ret = 0;\ | ||||
| if (buflen <= 0) \ | |||||
| return AVERROR(EINVAL); \ | |||||
| while (ret + 1 < maxlen) {\ | while (ret + 1 < maxlen) {\ | ||||
| uint8_t tmp;\ | uint8_t tmp;\ | ||||
| uint32_t ch;\ | uint32_t ch;\ | ||||
| @@ -292,8 +292,6 @@ static int read_header(AVFormatContext *s, | |||||
| "block size or frame size are variable.\n"); | "block size or frame size are variable.\n"); | ||||
| return AVERROR_INVALIDDATA; | return AVERROR_INVALIDDATA; | ||||
| } | } | ||||
| s->file_size = avio_size(pb); | |||||
| s->file_size = FFMAX(0, s->file_size); | |||||
| av_set_pts_info(st, 64, 1, st->codec->sample_rate); | av_set_pts_info(st, 64, 1, st->codec->sample_rate); | ||||
| st->start_time = 0; | st->start_time = 0; | ||||
| @@ -99,6 +99,33 @@ static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| static int mov_metadata_int8(MOVContext *c, AVIOContext *pb, | |||||
| unsigned len, const char *key) | |||||
| { | |||||
| char buf[16]; | |||||
| /* bypass padding bytes */ | |||||
| avio_r8(pb); | |||||
| avio_r8(pb); | |||||
| avio_r8(pb); | |||||
| snprintf(buf, sizeof(buf), "%hu", avio_r8(pb)); | |||||
| av_dict_set(&c->fc->metadata, key, buf, 0); | |||||
| return 0; | |||||
| } | |||||
| static int mov_metadata_stik(MOVContext *c, AVIOContext *pb, | |||||
| unsigned len, const char *key) | |||||
| { | |||||
| char buf[16]; | |||||
| snprintf(buf, sizeof(buf), "%hu", avio_r8(pb)); | |||||
| av_dict_set(&c->fc->metadata, key, buf, 0); | |||||
| return 0; | |||||
| } | |||||
| static const uint32_t mac_to_unicode[128] = { | static const uint32_t mac_to_unicode[128] = { | ||||
| 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1, | 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1, | ||||
| 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8, | 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8, | ||||
| @@ -174,6 +201,12 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) | |||||
| parse = mov_metadata_track_or_disc_number; break; | parse = mov_metadata_track_or_disc_number; break; | ||||
| case MKTAG( 'd','i','s','k'): key = "disc"; | case MKTAG( 'd','i','s','k'): key = "disc"; | ||||
| parse = mov_metadata_track_or_disc_number; break; | parse = mov_metadata_track_or_disc_number; break; | ||||
| case MKTAG( 't','v','e','s'): key = "episode_sort"; | |||||
| parse = mov_metadata_int8; break; | |||||
| case MKTAG( 't','v','s','n'): key = "season_number"; | |||||
| parse = mov_metadata_int8; break; | |||||
| case MKTAG( 's','t','i','k'): key = "media_type"; | |||||
| parse = mov_metadata_stik; break; | |||||
| } | } | ||||
| if (c->itunes_metadata && atom.size > 8) { | if (c->itunes_metadata && atom.size > 8) { | ||||
| @@ -20,7 +20,9 @@ | |||||
| */ | */ | ||||
| #include "libavutil/fifo.h" | #include "libavutil/fifo.h" | ||||
| #include "libavutil/log.h" | |||||
| #include "libavutil/mathematics.h" | #include "libavutil/mathematics.h" | ||||
| #include "libavutil/opt.h" | |||||
| #include "libavcodec/put_bits.h" | #include "libavcodec/put_bits.h" | ||||
| #include "avformat.h" | #include "avformat.h" | ||||
| #include "mpeg.h" | #include "mpeg.h" | ||||
| @@ -56,6 +58,7 @@ typedef struct { | |||||
| } StreamInfo; | } StreamInfo; | ||||
| typedef struct { | typedef struct { | ||||
| const AVClass *class; | |||||
| int packet_size; /* required packet size */ | int packet_size; /* required packet size */ | ||||
| int packet_number; | int packet_number; | ||||
| int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */ | int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */ | ||||
| @@ -416,9 +419,12 @@ static int mpeg_mux_init(AVFormatContext *ctx) | |||||
| video_bitrate += codec_rate; | video_bitrate += codec_rate; | ||||
| } | } | ||||
| #if FF_API_MUXRATE | |||||
| if(ctx->mux_rate){ | if(ctx->mux_rate){ | ||||
| s->mux_rate= (ctx->mux_rate + (8 * 50) - 1) / (8 * 50); | s->mux_rate= (ctx->mux_rate + (8 * 50) - 1) / (8 * 50); | ||||
| } else { | |||||
| } else | |||||
| #endif | |||||
| if (!s->mux_rate) { | |||||
| /* we increase slightly the bitrate to take into account the | /* we increase slightly the bitrate to take into account the | ||||
| headers. XXX: compute it exactly */ | headers. XXX: compute it exactly */ | ||||
| bitrate += bitrate*5/100; | bitrate += bitrate*5/100; | ||||
| @@ -1227,7 +1233,23 @@ static int mpeg_mux_end(AVFormatContext *ctx) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| #define OFFSET(x) offsetof(MpegMuxContext, x) | |||||
| #define E AV_OPT_FLAG_ENCODING_PARAM | |||||
| static const AVOption options[] = { | |||||
| { "muxrate", NULL, OFFSET(mux_rate), AV_OPT_TYPE_INT, {0}, 0, INT_MAX, E }, | |||||
| { NULL }, | |||||
| }; | |||||
| #define MPEGENC_CLASS(flavor)\ | |||||
| static const AVClass flavor ## _class = {\ | |||||
| .class_name = #flavor " muxer",\ | |||||
| .item_name = av_default_item_name,\ | |||||
| .version = LIBAVUTIL_VERSION_INT,\ | |||||
| .option = options,\ | |||||
| }; | |||||
| #if CONFIG_MPEG1SYSTEM_MUXER | #if CONFIG_MPEG1SYSTEM_MUXER | ||||
| MPEGENC_CLASS(mpeg) | |||||
| AVOutputFormat ff_mpeg1system_muxer = { | AVOutputFormat ff_mpeg1system_muxer = { | ||||
| .name = "mpeg", | .name = "mpeg", | ||||
| .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 System format"), | .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 System format"), | ||||
| @@ -1239,9 +1261,11 @@ AVOutputFormat ff_mpeg1system_muxer = { | |||||
| .write_header = mpeg_mux_init, | .write_header = mpeg_mux_init, | ||||
| .write_packet = mpeg_mux_write_packet, | .write_packet = mpeg_mux_write_packet, | ||||
| .write_trailer = mpeg_mux_end, | .write_trailer = mpeg_mux_end, | ||||
| .priv_class = &mpeg_class, | |||||
| }; | }; | ||||
| #endif | #endif | ||||
| #if CONFIG_MPEG1VCD_MUXER | #if CONFIG_MPEG1VCD_MUXER | ||||
| MPEGENC_CLASS(vcd) | |||||
| AVOutputFormat ff_mpeg1vcd_muxer = { | AVOutputFormat ff_mpeg1vcd_muxer = { | ||||
| .name = "vcd", | .name = "vcd", | ||||
| .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 System format (VCD)"), | .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 System format (VCD)"), | ||||
| @@ -1252,9 +1276,11 @@ AVOutputFormat ff_mpeg1vcd_muxer = { | |||||
| .write_header = mpeg_mux_init, | .write_header = mpeg_mux_init, | ||||
| .write_packet = mpeg_mux_write_packet, | .write_packet = mpeg_mux_write_packet, | ||||
| .write_trailer = mpeg_mux_end, | .write_trailer = mpeg_mux_end, | ||||
| .priv_class = &vcd_class, | |||||
| }; | }; | ||||
| #endif | #endif | ||||
| #if CONFIG_MPEG2VOB_MUXER | #if CONFIG_MPEG2VOB_MUXER | ||||
| MPEGENC_CLASS(vob) | |||||
| AVOutputFormat ff_mpeg2vob_muxer = { | AVOutputFormat ff_mpeg2vob_muxer = { | ||||
| .name = "vob", | .name = "vob", | ||||
| .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"), | .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"), | ||||
| @@ -1266,11 +1292,13 @@ AVOutputFormat ff_mpeg2vob_muxer = { | |||||
| .write_header = mpeg_mux_init, | .write_header = mpeg_mux_init, | ||||
| .write_packet = mpeg_mux_write_packet, | .write_packet = mpeg_mux_write_packet, | ||||
| .write_trailer = mpeg_mux_end, | .write_trailer = mpeg_mux_end, | ||||
| .priv_class = &vob_class, | |||||
| }; | }; | ||||
| #endif | #endif | ||||
| /* Same as mpeg2vob_mux except that the pack size is 2324 */ | /* Same as mpeg2vob_mux except that the pack size is 2324 */ | ||||
| #if CONFIG_MPEG2SVCD_MUXER | #if CONFIG_MPEG2SVCD_MUXER | ||||
| MPEGENC_CLASS(svcd) | |||||
| AVOutputFormat ff_mpeg2svcd_muxer = { | AVOutputFormat ff_mpeg2svcd_muxer = { | ||||
| .name = "svcd", | .name = "svcd", | ||||
| .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"), | .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"), | ||||
| @@ -1282,11 +1310,13 @@ AVOutputFormat ff_mpeg2svcd_muxer = { | |||||
| .write_header = mpeg_mux_init, | .write_header = mpeg_mux_init, | ||||
| .write_packet = mpeg_mux_write_packet, | .write_packet = mpeg_mux_write_packet, | ||||
| .write_trailer = mpeg_mux_end, | .write_trailer = mpeg_mux_end, | ||||
| .priv_class = &svcd_class, | |||||
| }; | }; | ||||
| #endif | #endif | ||||
| /* Same as mpeg2vob_mux except the 'is_dvd' flag is set to produce NAV pkts */ | /* Same as mpeg2vob_mux except the 'is_dvd' flag is set to produce NAV pkts */ | ||||
| #if CONFIG_MPEG2DVD_MUXER | #if CONFIG_MPEG2DVD_MUXER | ||||
| MPEGENC_CLASS(dvd) | |||||
| AVOutputFormat ff_mpeg2dvd_muxer = { | AVOutputFormat ff_mpeg2dvd_muxer = { | ||||
| .name = "dvd", | .name = "dvd", | ||||
| .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (DVD VOB)"), | .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (DVD VOB)"), | ||||
| @@ -1298,5 +1328,6 @@ AVOutputFormat ff_mpeg2dvd_muxer = { | |||||
| .write_header = mpeg_mux_init, | .write_header = mpeg_mux_init, | ||||
| .write_packet = mpeg_mux_write_packet, | .write_packet = mpeg_mux_write_packet, | ||||
| .write_trailer = mpeg_mux_end, | .write_trailer = mpeg_mux_end, | ||||
| .priv_class = &dvd_class, | |||||
| }; | }; | ||||
| #endif | #endif | ||||
| @@ -92,6 +92,7 @@ static const AVOption options[] = { | |||||
| {"mpegts_m2ts_mode", "Enable m2ts mode.", | {"mpegts_m2ts_mode", "Enable m2ts mode.", | ||||
| offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_INT, {.dbl = -1 }, | offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_INT, {.dbl = -1 }, | ||||
| -1,1, AV_OPT_FLAG_ENCODING_PARAM}, | -1,1, AV_OPT_FLAG_ENCODING_PARAM}, | ||||
| { "muxrate", NULL, offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT, {1}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, | |||||
| { NULL }, | { NULL }, | ||||
| }; | }; | ||||
| @@ -562,7 +563,10 @@ static int mpegts_write_header(AVFormatContext *s) | |||||
| service->pcr_pid = ts_st->pid; | service->pcr_pid = ts_st->pid; | ||||
| } | } | ||||
| ts->mux_rate = s->mux_rate ? s->mux_rate : 1; | |||||
| #if FF_API_MUXRATE | |||||
| if (s->mux_rate) | |||||
| ts->mux_rate = s->mux_rate; | |||||
| #endif | |||||
| if (ts->mux_rate > 1) { | if (ts->mux_rate > 1) { | ||||
| service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) / | service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) / | ||||
| @@ -74,7 +74,9 @@ static const AVClass *format_child_class_next(const AVClass *prev) | |||||
| static const AVOption options[]={ | static const AVOption options[]={ | ||||
| {"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT, {.dbl = 5000000 }, 32, INT_MAX, D}, | {"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT, {.dbl = 5000000 }, 32, INT_MAX, D}, | ||||
| #if FF_API_MUXRATE | |||||
| {"muxrate", "set mux rate", OFFSET(mux_rate), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E}, | {"muxrate", "set mux rate", OFFSET(mux_rate), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E}, | ||||
| #endif | |||||
| {"packetsize", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E}, | {"packetsize", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E}, | ||||
| {"fflags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, INT_MIN, INT_MAX, D|E, "fflags"}, | {"fflags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, INT_MIN, INT_MAX, D|E, "fflags"}, | ||||
| {"ignidx", "ignore index", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_IGNIDX }, INT_MIN, INT_MAX, D, "fflags"}, | {"ignidx", "ignore index", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_IGNIDX }, INT_MIN, INT_MAX, D, "fflags"}, | ||||
| @@ -92,8 +92,7 @@ static int qcp_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
| avio_rb32(pb); // "RIFF" | avio_rb32(pb); // "RIFF" | ||||
| s->file_size = avio_rl32(pb) + 8; | |||||
| avio_skip(pb, 8 + 4 + 1 + 1); // "QLCMfmt " + chunk-size + major-version + minor-version | |||||
| avio_skip(pb, 4 + 8 + 4 + 1 + 1); // filesize + "QLCMfmt " + chunk-size + major-version + minor-version | |||||
| st->codec->codec_type = AVMEDIA_TYPE_AUDIO; | st->codec->codec_type = AVMEDIA_TYPE_AUDIO; | ||||
| st->codec->channels = 1; | st->codec->channels = 1; | ||||
| @@ -98,7 +98,8 @@ int ff_rtp_get_payload_type(AVFormatContext *fmt, AVCodecContext *codec) | |||||
| /* Was the payload type already specified for the RTP muxer? */ | /* Was the payload type already specified for the RTP muxer? */ | ||||
| if (ofmt && ofmt->priv_class) { | if (ofmt && ofmt->priv_class) { | ||||
| int64_t payload_type; | int64_t payload_type; | ||||
| if (av_opt_get_int(fmt->priv_data, "payload_type", 0, &payload_type) >= 0) | |||||
| if (av_opt_get_int(fmt->priv_data, "payload_type", 0, &payload_type) >= 0 && | |||||
| payload_type >= 0) | |||||
| return (int)payload_type; | return (int)payload_type; | ||||
| } | } | ||||
| @@ -465,7 +465,7 @@ AVOutputFormat ff_rtp_muxer = { | |||||
| .long_name = NULL_IF_CONFIG_SMALL("RTP output format"), | .long_name = NULL_IF_CONFIG_SMALL("RTP output format"), | ||||
| .priv_data_size = sizeof(RTPMuxContext), | .priv_data_size = sizeof(RTPMuxContext), | ||||
| .audio_codec = CODEC_ID_PCM_MULAW, | .audio_codec = CODEC_ID_PCM_MULAW, | ||||
| .video_codec = CODEC_ID_NONE, | |||||
| .video_codec = CODEC_ID_MPEG4, | |||||
| .write_header = rtp_write_header, | .write_header = rtp_write_header, | ||||
| .write_packet = rtp_write_packet, | .write_packet = rtp_write_packet, | ||||
| .write_trailer = rtp_write_trailer, | .write_trailer = rtp_write_trailer, | ||||
| @@ -45,6 +45,7 @@ | |||||
| #include "rtpdec_formats.h" | #include "rtpdec_formats.h" | ||||
| #include "rtpenc_chain.h" | #include "rtpenc_chain.h" | ||||
| #include "url.h" | #include "url.h" | ||||
| #include "rtpenc.h" | |||||
| //#define DEBUG | //#define DEBUG | ||||
| @@ -56,6 +57,36 @@ | |||||
| #define SDP_MAX_SIZE 16384 | #define SDP_MAX_SIZE 16384 | ||||
| #define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH | #define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH | ||||
| #define OFFSET(x) offsetof(RTSPState, x) | |||||
| #define DEC AV_OPT_FLAG_DECODING_PARAM | |||||
| #define ENC AV_OPT_FLAG_ENCODING_PARAM | |||||
| #define RTSP_FLAG_OPTS(name, longname) \ | |||||
| { name, longname, OFFSET(rtsp_flags), AV_OPT_TYPE_FLAGS, {0}, INT_MIN, INT_MAX, DEC, "rtsp_flags" }, \ | |||||
| { "filter_src", "Only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, "rtsp_flags" } | |||||
| const AVOption ff_rtsp_options[] = { | |||||
| { "initial_pause", "Don't start playing the stream immediately", OFFSET(initial_pause), AV_OPT_TYPE_INT, {0}, 0, 1, DEC }, | |||||
| FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags), | |||||
| { "rtsp_transport", "RTSP transport protocols", OFFSET(lower_transport_mask), AV_OPT_TYPE_FLAGS, {0}, INT_MIN, INT_MAX, DEC|ENC, "rtsp_transport" }, \ | |||||
| { "udp", "UDP", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_UDP}, 0, 0, DEC|ENC, "rtsp_transport" }, \ | |||||
| { "tcp", "TCP", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_TCP}, 0, 0, DEC|ENC, "rtsp_transport" }, \ | |||||
| { "udp_multicast", "UDP multicast", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_UDP_MULTICAST}, 0, 0, DEC, "rtsp_transport" }, | |||||
| { "http", "HTTP tunneling", 0, AV_OPT_TYPE_CONST, {(1 << RTSP_LOWER_TRANSPORT_HTTP)}, 0, 0, DEC, "rtsp_transport" }, | |||||
| RTSP_FLAG_OPTS("rtsp_flags", "RTSP flags"), | |||||
| { NULL }, | |||||
| }; | |||||
| static const AVOption sdp_options[] = { | |||||
| RTSP_FLAG_OPTS("sdp_flags", "SDP flags"), | |||||
| { NULL }, | |||||
| }; | |||||
| static const AVOption rtp_options[] = { | |||||
| RTSP_FLAG_OPTS("rtp_flags", "RTP flags"), | |||||
| { NULL }, | |||||
| }; | |||||
| static void get_word_until_chars(char *buf, int buf_size, | static void get_word_until_chars(char *buf, int buf_size, | ||||
| const char *sep, const char **pp) | const char *sep, const char **pp) | ||||
| { | { | ||||
| @@ -1218,7 +1249,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, | |||||
| case RTSP_LOWER_TRANSPORT_UDP: { | case RTSP_LOWER_TRANSPORT_UDP: { | ||||
| char url[1024], options[30] = ""; | char url[1024], options[30] = ""; | ||||
| if (rt->filter_source) | |||||
| if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC) | |||||
| av_strlcpy(options, "?connect=1", sizeof(options)); | av_strlcpy(options, "?connect=1", sizeof(options)); | ||||
| /* Use source address if specified */ | /* Use source address if specified */ | ||||
| if (reply->transports[0].source[0]) { | if (reply->transports[0].source[0]) { | ||||
| @@ -1308,8 +1339,17 @@ int ff_rtsp_connect(AVFormatContext *s) | |||||
| if (!ff_network_init()) | if (!ff_network_init()) | ||||
| return AVERROR(EIO); | return AVERROR(EIO); | ||||
| redirect: | |||||
| rt->control_transport = RTSP_MODE_PLAIN; | rt->control_transport = RTSP_MODE_PLAIN; | ||||
| if (rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_HTTP)) { | |||||
| rt->lower_transport_mask = 1 << RTSP_LOWER_TRANSPORT_TCP; | |||||
| rt->control_transport = RTSP_MODE_TUNNEL; | |||||
| } | |||||
| /* Only pass through valid flags from here */ | |||||
| rt->lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_NB) - 1; | |||||
| redirect: | |||||
| lower_transport_mask = rt->lower_transport_mask; | |||||
| /* extract hostname and port */ | /* extract hostname and port */ | ||||
| av_url_split(NULL, 0, auth, sizeof(auth), | av_url_split(NULL, 0, auth, sizeof(auth), | ||||
| host, sizeof(host), &port, path, sizeof(path), s->filename); | host, sizeof(host), &port, path, sizeof(path), s->filename); | ||||
| @@ -1319,6 +1359,7 @@ redirect: | |||||
| if (port < 0) | if (port < 0) | ||||
| port = RTSP_DEFAULT_PORT; | port = RTSP_DEFAULT_PORT; | ||||
| #if FF_API_RTSP_URL_OPTIONS | |||||
| /* search for options */ | /* search for options */ | ||||
| option_list = strrchr(path, '?'); | option_list = strrchr(path, '?'); | ||||
| if (option_list) { | if (option_list) { | ||||
| @@ -1326,6 +1367,7 @@ redirect: | |||||
| * the options back into the same string. */ | * the options back into the same string. */ | ||||
| filename = option_list; | filename = option_list; | ||||
| while (option_list) { | while (option_list) { | ||||
| int handled = 1; | |||||
| /* move the option pointer */ | /* move the option pointer */ | ||||
| option = ++option_list; | option = ++option_list; | ||||
| option_list = strchr(option_list, '&'); | option_list = strchr(option_list, '&'); | ||||
| @@ -1343,7 +1385,7 @@ redirect: | |||||
| lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_TCP); | lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_TCP); | ||||
| rt->control_transport = RTSP_MODE_TUNNEL; | rt->control_transport = RTSP_MODE_TUNNEL; | ||||
| } else if (!strcmp(option, "filter_src")) { | } else if (!strcmp(option, "filter_src")) { | ||||
| rt->filter_source = 1; | |||||
| rt->rtsp_flags |= RTSP_FLAG_FILTER_SRC; | |||||
| } else { | } else { | ||||
| /* Write options back into the buffer, using memmove instead | /* Write options back into the buffer, using memmove instead | ||||
| * of strcpy since the strings may overlap. */ | * of strcpy since the strings may overlap. */ | ||||
| @@ -1351,10 +1393,16 @@ redirect: | |||||
| memmove(++filename, option, len); | memmove(++filename, option, len); | ||||
| filename += len; | filename += len; | ||||
| if (option_list) *filename = '&'; | if (option_list) *filename = '&'; | ||||
| handled = 0; | |||||
| } | } | ||||
| if (handled) | |||||
| av_log(s, AV_LOG_WARNING, "Options passed via URL are " | |||||
| "deprecated, use -rtsp_transport " | |||||
| "and -rtsp_flags instead.\n"); | |||||
| } | } | ||||
| *filename = 0; | *filename = 0; | ||||
| } | } | ||||
| #endif | |||||
| if (!lower_transport_mask) | if (!lower_transport_mask) | ||||
| lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1; | lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1; | ||||
| @@ -1797,8 +1845,9 @@ static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST); | namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST); | ||||
| ff_url_join(url, sizeof(url), "rtp", NULL, | ff_url_join(url, sizeof(url), "rtp", NULL, | ||||
| namebuf, rtsp_st->sdp_port, | namebuf, rtsp_st->sdp_port, | ||||
| "?localport=%d&ttl=%d", rtsp_st->sdp_port, | |||||
| rtsp_st->sdp_ttl); | |||||
| "?localport=%d&ttl=%d&connect=%d", rtsp_st->sdp_port, | |||||
| rtsp_st->sdp_ttl, | |||||
| rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0); | |||||
| if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE) < 0) { | if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE) < 0) { | ||||
| err = AVERROR_INVALIDDATA; | err = AVERROR_INVALIDDATA; | ||||
| goto fail; | goto fail; | ||||
| @@ -1820,6 +1869,13 @@ static int sdp_read_close(AVFormatContext *s) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| static const AVClass sdp_demuxer_class = { | |||||
| .class_name = "SDP demuxer", | |||||
| .item_name = av_default_item_name, | |||||
| .option = sdp_options, | |||||
| .version = LIBAVUTIL_VERSION_INT, | |||||
| }; | |||||
| AVInputFormat ff_sdp_demuxer = { | AVInputFormat ff_sdp_demuxer = { | ||||
| .name = "sdp", | .name = "sdp", | ||||
| .long_name = NULL_IF_CONFIG_SMALL("SDP"), | .long_name = NULL_IF_CONFIG_SMALL("SDP"), | ||||
| @@ -1828,6 +1884,7 @@ AVInputFormat ff_sdp_demuxer = { | |||||
| .read_header = sdp_read_header, | .read_header = sdp_read_header, | ||||
| .read_packet = ff_rtsp_fetch_packet, | .read_packet = ff_rtsp_fetch_packet, | ||||
| .read_close = sdp_read_close, | .read_close = sdp_read_close, | ||||
| .priv_class = &sdp_demuxer_class | |||||
| }; | }; | ||||
| #endif /* CONFIG_SDP_DEMUXER */ | #endif /* CONFIG_SDP_DEMUXER */ | ||||
| @@ -1924,6 +1981,13 @@ fail: | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| static const AVClass rtp_demuxer_class = { | |||||
| .class_name = "RTP demuxer", | |||||
| .item_name = av_default_item_name, | |||||
| .option = rtp_options, | |||||
| .version = LIBAVUTIL_VERSION_INT, | |||||
| }; | |||||
| AVInputFormat ff_rtp_demuxer = { | AVInputFormat ff_rtp_demuxer = { | ||||
| .name = "rtp", | .name = "rtp", | ||||
| .long_name = NULL_IF_CONFIG_SMALL("RTP input format"), | .long_name = NULL_IF_CONFIG_SMALL("RTP input format"), | ||||
| @@ -1933,6 +1997,7 @@ AVInputFormat ff_rtp_demuxer = { | |||||
| .read_packet = ff_rtsp_fetch_packet, | .read_packet = ff_rtsp_fetch_packet, | ||||
| .read_close = sdp_read_close, | .read_close = sdp_read_close, | ||||
| .flags = AVFMT_NOFILE, | .flags = AVFMT_NOFILE, | ||||
| .priv_class = &rtp_demuxer_class | |||||
| }; | }; | ||||
| #endif /* CONFIG_RTP_DEMUXER */ | #endif /* CONFIG_RTP_DEMUXER */ | ||||
| @@ -29,6 +29,7 @@ | |||||
| #include "httpauth.h" | #include "httpauth.h" | ||||
| #include "libavutil/log.h" | #include "libavutil/log.h" | ||||
| #include "libavutil/opt.h" | |||||
| /** | /** | ||||
| * Network layer over which RTP/etc packet data will be transported. | * Network layer over which RTP/etc packet data will be transported. | ||||
| @@ -37,7 +38,10 @@ enum RTSPLowerTransport { | |||||
| RTSP_LOWER_TRANSPORT_UDP = 0, /**< UDP/unicast */ | RTSP_LOWER_TRANSPORT_UDP = 0, /**< UDP/unicast */ | ||||
| RTSP_LOWER_TRANSPORT_TCP = 1, /**< TCP; interleaved in RTSP */ | RTSP_LOWER_TRANSPORT_TCP = 1, /**< TCP; interleaved in RTSP */ | ||||
| RTSP_LOWER_TRANSPORT_UDP_MULTICAST = 2, /**< UDP/multicast */ | RTSP_LOWER_TRANSPORT_UDP_MULTICAST = 2, /**< UDP/multicast */ | ||||
| RTSP_LOWER_TRANSPORT_NB | |||||
| RTSP_LOWER_TRANSPORT_NB, | |||||
| RTSP_LOWER_TRANSPORT_HTTP = 8, /**< HTTP tunneled - not a proper | |||||
| transport mode as such, | |||||
| only for use via AVOptions */ | |||||
| }; | }; | ||||
| /** | /** | ||||
| @@ -313,10 +317,6 @@ typedef struct RTSPState { | |||||
| /** Reusable buffer for receiving packets */ | /** Reusable buffer for receiving packets */ | ||||
| uint8_t* recvbuf; | uint8_t* recvbuf; | ||||
| /** Filter incoming UDP packets - receive packets only from the right | |||||
| * source address and port. */ | |||||
| int filter_source; | |||||
| /** | /** | ||||
| * A mask with all requested transport methods | * A mask with all requested transport methods | ||||
| */ | */ | ||||
| @@ -349,8 +349,17 @@ typedef struct RTSPState { | |||||
| /** Whether the server accepts the x-Dynamic-Rate header */ | /** Whether the server accepts the x-Dynamic-Rate header */ | ||||
| int accept_dynamic_rate; | int accept_dynamic_rate; | ||||
| /** | |||||
| * Various option flags for the RTSP muxer/demuxer. | |||||
| */ | |||||
| int rtsp_flags; | |||||
| } RTSPState; | } RTSPState; | ||||
| #define RTSP_FLAG_FILTER_SRC 0x1 /**< Filter incoming UDP packets - | |||||
| receive packets only from the right | |||||
| source address and port. */ | |||||
| /** | /** | ||||
| * Describes a single stream, as identified by a single m= line block in the | * Describes a single stream, as identified by a single m= line block in the | ||||
| * SDP content. In the case of RDT, one RTSPStream can represent multiple | * SDP content. In the case of RDT, one RTSPStream can represent multiple | ||||
| @@ -537,4 +546,6 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, | |||||
| */ | */ | ||||
| void ff_rtsp_undo_setup(AVFormatContext *s); | void ff_rtsp_undo_setup(AVFormatContext *s); | ||||
| extern const AVOption ff_rtsp_options[]; | |||||
| #endif /* AVFORMAT_RTSP_H */ | #endif /* AVFORMAT_RTSP_H */ | ||||
| @@ -22,7 +22,6 @@ | |||||
| #include "libavutil/avstring.h" | #include "libavutil/avstring.h" | ||||
| #include "libavutil/intreadwrite.h" | #include "libavutil/intreadwrite.h" | ||||
| #include "libavutil/mathematics.h" | #include "libavutil/mathematics.h" | ||||
| #include "libavutil/opt.h" | |||||
| #include "avformat.h" | #include "avformat.h" | ||||
| #include "internal.h" | #include "internal.h" | ||||
| @@ -388,15 +387,10 @@ static int rtsp_read_close(AVFormatContext *s) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| static const AVOption options[] = { | |||||
| { "initial_pause", "Don't start playing the stream immediately", offsetof(RTSPState, initial_pause), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM }, | |||||
| { NULL }, | |||||
| }; | |||||
| const AVClass rtsp_demuxer_class = { | const AVClass rtsp_demuxer_class = { | ||||
| .class_name = "RTSP demuxer", | .class_name = "RTSP demuxer", | ||||
| .item_name = av_default_item_name, | .item_name = av_default_item_name, | ||||
| .option = options, | |||||
| .option = ff_rtsp_options, | |||||
| .version = LIBAVUTIL_VERSION_INT, | .version = LIBAVUTIL_VERSION_INT, | ||||
| }; | }; | ||||
| @@ -33,20 +33,13 @@ | |||||
| #include "libavutil/intreadwrite.h" | #include "libavutil/intreadwrite.h" | ||||
| #include "libavutil/avstring.h" | #include "libavutil/avstring.h" | ||||
| #include "url.h" | #include "url.h" | ||||
| #include "libavutil/opt.h" | |||||
| #include "rtpenc.h" | |||||
| #define SDP_MAX_SIZE 16384 | #define SDP_MAX_SIZE 16384 | ||||
| static const AVOption options[] = { | |||||
| FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags), | |||||
| { NULL }, | |||||
| }; | |||||
| static const AVClass rtsp_muxer_class = { | static const AVClass rtsp_muxer_class = { | ||||
| .class_name = "RTSP muxer", | .class_name = "RTSP muxer", | ||||
| .item_name = av_default_item_name, | .item_name = av_default_item_name, | ||||
| .option = options, | |||||
| .option = ff_rtsp_options, | |||||
| .version = LIBAVUTIL_VERSION_INT, | .version = LIBAVUTIL_VERSION_INT, | ||||
| }; | }; | ||||
| @@ -1902,7 +1902,7 @@ static int has_duration(AVFormatContext *ic) | |||||
| static void update_stream_timings(AVFormatContext *ic) | static void update_stream_timings(AVFormatContext *ic) | ||||
| { | { | ||||
| int64_t start_time, start_time1, start_time_text, end_time, end_time1; | int64_t start_time, start_time1, start_time_text, end_time, end_time1; | ||||
| int64_t duration, duration1; | |||||
| int64_t duration, duration1, filesize; | |||||
| int i; | int i; | ||||
| AVStream *st; | AVStream *st; | ||||
| @@ -1945,9 +1945,9 @@ static void update_stream_timings(AVFormatContext *ic) | |||||
| if (duration != INT64_MIN && ic->duration == AV_NOPTS_VALUE) { | if (duration != INT64_MIN && ic->duration == AV_NOPTS_VALUE) { | ||||
| ic->duration = duration; | ic->duration = duration; | ||||
| } | } | ||||
| if (ic->file_size > 0 && ic->duration != AV_NOPTS_VALUE) { | |||||
| if (ic->pb && (filesize = avio_size(ic->pb)) > 0 && ic->duration != AV_NOPTS_VALUE) { | |||||
| /* compute the bitrate */ | /* compute the bitrate */ | ||||
| ic->bit_rate = (double)ic->file_size * 8.0 * AV_TIME_BASE / | |||||
| ic->bit_rate = (double)filesize * 8.0 * AV_TIME_BASE / | |||||
| (double)ic->duration; | (double)ic->duration; | ||||
| } | } | ||||
| } | } | ||||
| @@ -1988,9 +1988,8 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic) | |||||
| /* if duration is already set, we believe it */ | /* if duration is already set, we believe it */ | ||||
| if (ic->duration == AV_NOPTS_VALUE && | if (ic->duration == AV_NOPTS_VALUE && | ||||
| ic->bit_rate != 0 && | |||||
| ic->file_size != 0) { | |||||
| filesize = ic->file_size; | |||||
| ic->bit_rate != 0) { | |||||
| filesize = ic->pb ? avio_size(ic->pb) : 0; | |||||
| if (filesize > 0) { | if (filesize > 0) { | ||||
| for(i = 0; i < ic->nb_streams; i++) { | for(i = 0; i < ic->nb_streams; i++) { | ||||
| st = ic->streams[i]; | st = ic->streams[i]; | ||||
| @@ -2034,7 +2033,7 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) | |||||
| /* estimate the end time (duration) */ | /* estimate the end time (duration) */ | ||||
| /* XXX: may need to support wrapping */ | /* XXX: may need to support wrapping */ | ||||
| filesize = ic->file_size; | |||||
| filesize = ic->pb ? avio_size(ic->pb) : 0; | |||||
| end_time = AV_NOPTS_VALUE; | end_time = AV_NOPTS_VALUE; | ||||
| do{ | do{ | ||||
| offset = filesize - (DURATION_MAX_READ_SIZE<<retry); | offset = filesize - (DURATION_MAX_READ_SIZE<<retry); | ||||
| @@ -2098,7 +2097,6 @@ static void estimate_timings(AVFormatContext *ic, int64_t old_offset) | |||||
| if (file_size < 0) | if (file_size < 0) | ||||
| file_size = 0; | file_size = 0; | ||||
| } | } | ||||
| ic->file_size = file_size; | |||||
| if ((!strcmp(ic->iformat->name, "mpeg") || | if ((!strcmp(ic->iformat->name, "mpeg") || | ||||
| !strcmp(ic->iformat->name, "mpegts")) && | !strcmp(ic->iformat->name, "mpegts")) && | ||||
| @@ -25,7 +25,7 @@ | |||||
| #define LIBAVFORMAT_VERSION_MAJOR 53 | #define LIBAVFORMAT_VERSION_MAJOR 53 | ||||
| #define LIBAVFORMAT_VERSION_MINOR 16 | #define LIBAVFORMAT_VERSION_MINOR 16 | ||||
| #define LIBAVFORMAT_VERSION_MICRO 0 | |||||
| #define LIBAVFORMAT_VERSION_MICRO 1 | |||||
| #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | ||||
| LIBAVFORMAT_VERSION_MINOR, \ | LIBAVFORMAT_VERSION_MINOR, \ | ||||
| @@ -89,5 +89,14 @@ | |||||
| #ifndef FF_API_TIMESTAMP | #ifndef FF_API_TIMESTAMP | ||||
| #define FF_API_TIMESTAMP (LIBAVFORMAT_VERSION_MAJOR < 54) | #define FF_API_TIMESTAMP (LIBAVFORMAT_VERSION_MAJOR < 54) | ||||
| #endif | #endif | ||||
| #ifndef FF_API_FILESIZE | |||||
| #define FF_API_FILESIZE (LIBAVFORMAT_VERSION_MAJOR < 54) | |||||
| #endif | |||||
| #ifndef FF_API_MUXRATE | |||||
| #define FF_API_MUXRATE (LIBAVFORMAT_VERSION_MAJOR < 54) | |||||
| #endif | |||||
| #ifndef FF_API_RTSP_URL_OPTIONS | |||||
| #define FF_API_RTSP_URL_OPTIONS (LIBAVFORMAT_VERSION_MAJOR < 54) | |||||
| #endif | |||||
| #endif /* AVFORMAT_VERSION_H */ | #endif /* AVFORMAT_VERSION_H */ | ||||
| @@ -503,7 +503,8 @@ int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_ | |||||
| int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) | int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) | ||||
| { | { | ||||
| const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0); | const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0); | ||||
| const AVOption *flag = av_opt_find(obj, flag_name, NULL, 0, 0); | |||||
| const AVOption *flag = av_opt_find(obj, flag_name, | |||||
| field ? field->unit : NULL, 0, 0); | |||||
| int64_t res; | int64_t res; | ||||
| if (!field || !flag || flag->type != AV_OPT_TYPE_CONST || | if (!field || !flag || flag->type != AV_OPT_TYPE_CONST || | ||||
| @@ -700,6 +701,7 @@ int av_set_options_string(void *ctx, const char *opts, | |||||
| if (!opts) | if (!opts) | ||||
| return 0; | return 0; | ||||
| while (*opts) { | while (*opts) { | ||||
| if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0) | if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0) | ||||
| return ret; | return ret; | ||||