* 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>
| ... | ... |
@@ -347,6 +347,8 @@ typedef struct OptionsContext {
|
| 347 | 347 |
int nb_inter_matrices; |
| 348 | 348 |
SpecifierOpt *top_field_first; |
| 349 | 349 |
int nb_top_field_first; |
| 350 |
+ SpecifierOpt *presets; |
|
| 351 |
+ int nb_presets; |
|
| 350 | 352 |
#if CONFIG_AVFILTER |
| 351 | 353 |
SpecifierOpt *filters; |
| 352 | 354 |
int nb_filters; |
| ... | ... |
@@ -3087,15 +3089,62 @@ static void parse_forced_key_frames(char *kf, OutputStream *ost, |
| 3087 | 3087 |
} |
| 3088 | 3088 |
} |
| 3089 | 3089 |
|
| 3090 |
+static uint8_t *get_line(AVIOContext *s) |
|
| 3091 |
+{
|
|
| 3092 |
+ AVIOContext *line; |
|
| 3093 |
+ uint8_t *buf; |
|
| 3094 |
+ char c; |
|
| 3095 |
+ |
|
| 3096 |
+ if (avio_open_dyn_buf(&line) < 0) {
|
|
| 3097 |
+ av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n"); |
|
| 3098 |
+ exit_program(1); |
|
| 3099 |
+ } |
|
| 3100 |
+ |
|
| 3101 |
+ while ((c = avio_r8(s)) && c != '\n') |
|
| 3102 |
+ avio_w8(line, c); |
|
| 3103 |
+ avio_w8(line, 0); |
|
| 3104 |
+ avio_close_dyn_buf(line, &buf); |
|
| 3105 |
+ |
|
| 3106 |
+ return buf; |
|
| 3107 |
+} |
|
| 3108 |
+ |
|
| 3109 |
+static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s) |
|
| 3110 |
+{
|
|
| 3111 |
+ int i, ret = 1; |
|
| 3112 |
+ char filename[1000]; |
|
| 3113 |
+ const char *base[3] = { getenv("AVCONV_DATADIR"),
|
|
| 3114 |
+ getenv("HOME"),
|
|
| 3115 |
+ AVCONV_DATADIR, |
|
| 3116 |
+ }; |
|
| 3117 |
+ |
|
| 3118 |
+ for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) {
|
|
| 3119 |
+ if (!base[i]) |
|
| 3120 |
+ continue; |
|
| 3121 |
+ if (codec_name) {
|
|
| 3122 |
+ snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i], |
|
| 3123 |
+ i != 1 ? "" : "/.avconv", codec_name, preset_name); |
|
| 3124 |
+ ret = avio_open(s, filename, AVIO_FLAG_READ); |
|
| 3125 |
+ } |
|
| 3126 |
+ if (ret) {
|
|
| 3127 |
+ snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i], |
|
| 3128 |
+ i != 1 ? "" : "/.avconv", preset_name); |
|
| 3129 |
+ ret = avio_open(s, filename, AVIO_FLAG_READ); |
|
| 3130 |
+ } |
|
| 3131 |
+ } |
|
| 3132 |
+ return ret; |
|
| 3133 |
+} |
|
| 3134 |
+ |
|
| 3090 | 3135 |
static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type) |
| 3091 | 3136 |
{
|
| 3092 | 3137 |
OutputStream *ost; |
| 3093 | 3138 |
AVStream *st = av_new_stream(oc, oc->nb_streams < o->nb_streamid_map ? o->streamid_map[oc->nb_streams] : 0); |
| 3094 |
- int idx = oc->nb_streams - 1; |
|
| 3139 |
+ int idx = oc->nb_streams - 1, ret = 0; |
|
| 3095 | 3140 |
int64_t max_frames = INT64_MAX; |
| 3096 | 3141 |
char *bsf = NULL, *next, *codec_tag = NULL; |
| 3097 | 3142 |
AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL; |
| 3098 | 3143 |
double qscale = -1; |
| 3144 |
+ char *buf = NULL, *arg = NULL, *preset = NULL; |
|
| 3145 |
+ AVIOContext *s = NULL; |
|
| 3099 | 3146 |
|
| 3100 | 3147 |
if (!st) {
|
| 3101 | 3148 |
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 |
| 3117 | 3117 |
avcodec_get_context_defaults3(st->codec, ost->enc); |
| 3118 | 3118 |
st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy |
| 3119 | 3119 |
|
| 3120 |
+ MATCH_PER_STREAM_OPT(presets, str, preset, oc, st); |
|
| 3121 |
+ if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
|
|
| 3122 |
+ do {
|
|
| 3123 |
+ buf = get_line(s); |
|
| 3124 |
+ if (!buf[0] || buf[0] == '#') {
|
|
| 3125 |
+ av_free(buf); |
|
| 3126 |
+ continue; |
|
| 3127 |
+ } |
|
| 3128 |
+ if (!(arg = strchr(buf, '='))) {
|
|
| 3129 |
+ av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n"); |
|
| 3130 |
+ exit_program(1); |
|
| 3131 |
+ } |
|
| 3132 |
+ *arg++ = 0; |
|
| 3133 |
+ av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE); |
|
| 3134 |
+ av_free(buf); |
|
| 3135 |
+ } while (!s->eof_reached); |
|
| 3136 |
+ avio_close(s); |
|
| 3137 |
+ } |
|
| 3138 |
+ if (ret) {
|
|
| 3139 |
+ av_log(NULL, AV_LOG_FATAL, |
|
| 3140 |
+ "Preset %s specified for stream %d:%d, but could not be opened.\n", |
|
| 3141 |
+ preset, ost->file_index, ost->index); |
|
| 3142 |
+ exit_program(1); |
|
| 3143 |
+ } |
|
| 3144 |
+ |
|
| 3120 | 3145 |
MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st); |
| 3121 | 3146 |
ost->max_frames = max_frames; |
| 3122 | 3147 |
|
| ... | ... |
@@ -4027,6 +4101,7 @@ static const OptionDef options[] = {
|
| 4027 | 4027 |
{ "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
|
| 4028 | 4028 |
{ "c", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" },
|
| 4029 | 4029 |
{ "codec", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" },
|
| 4030 |
+ { "pre", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(presets)}, "preset name", "preset" },
|
|
| 4030 | 4031 |
{ "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" },
|
| 4031 | 4032 |
{ "map_metadata", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_metadata}, "set metadata information of outfile from infile",
|
| 4032 | 4033 |
"outfile[,metadata]:infile[,metadata]" }, |
| ... | ... |
@@ -186,6 +186,8 @@ codec-dependent. |
| 186 | 186 |
@var{filter_graph} is a description of the filter graph to apply to
|
| 187 | 187 |
the stream. Use @code{-filters} to show all the available filters
|
| 188 | 188 |
(including also sources and sinks). |
| 189 |
+@item -pre[:@var{stream_specifier}] @var{preset_name} (@emph{output,per-stream})
|
|
| 190 |
+Specify the preset for matching stream(s). |
|
| 189 | 191 |
|
| 190 | 192 |
@item -stats (@emph{global})
|
| 191 | 193 |
Print encoding progress/statistics. On by default. |
| ... | ... |
@@ -770,6 +772,21 @@ quality). |
| 770 | 770 |
@chapter Examples |
| 771 | 771 |
@c man begin EXAMPLES |
| 772 | 772 |
|
| 773 |
+@section Preset files |
|
| 774 |
+ |
|
| 775 |
+A preset file contains a sequence of @var{option=value} pairs, one for
|
|
| 776 |
+each line, specifying a sequence of options which can be specified also on |
|
| 777 |
+the command line. Lines starting with the hash ('#') character are ignored and
|
|
| 778 |
+are used to provide comments. Empty lines are also ignored. Check the |
|
| 779 |
+@file{ffpresets} directory in the Libav source tree for examples.
|
|
| 780 |
+ |
|
| 781 |
+Preset files are specified with the @code{pre} option, this option takes a
|
|
| 782 |
+preset name as input. Avconv searches for a file named @var{preset_name}.avpreset in
|
|
| 783 |
+the directories @file{$AVCONV_DATADIR} (if set), and @file{$HOME/.avconv}, and in
|
|
| 784 |
+the data directory defined at configuration time (usually @file{$PREFIX/share/avconv})
|
|
| 785 |
+in that order. For example, if the argument is @code{libx264-max}, it will
|
|
| 786 |
+search for the file @file{libx264-max.avpreset}.
|
|
| 787 |
+ |
|
| 773 | 788 |
@section Video and Audio grabbing |
| 774 | 789 |
|
| 775 | 790 |
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 |
| 432 | 432 |
pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
|
| 433 | 433 |
@end table |
| 434 | 434 |
|
| 435 |
-The radius must be a non-negative number, and must be not greater than |
|
| 435 |
+The radius must be a non-negative number, and must not be greater than |
|
| 436 | 436 |
the value of the expression @code{min(w,h)/2} for the luma and alpha planes,
|
| 437 | 437 |
and of @code{min(cw,ch)/2} for the chroma planes.
|
| 438 | 438 |
|
| ... | ... |
@@ -246,12 +246,15 @@ supporting it (currently Darwin Streaming Server and Mischa Spiegelmock's |
| 246 | 246 |
|
| 247 | 247 |
The required syntax for a RTSP url is: |
| 248 | 248 |
@example |
| 249 |
-rtsp://@var{hostname}[:@var{port}]/@var{path}[?@var{options}]
|
|
| 249 |
+rtsp://@var{hostname}[:@var{port}]/@var{path}
|
|
| 250 | 250 |
@end example |
| 251 | 251 |
|
| 252 |
-@var{options} is a @code{&}-separated list. The following options
|
|
| 252 |
+The following options (set on the @file{ffmpeg}/@file{ffplay} command
|
|
| 253 |
+line, or set in code via @code{AVOption}s or in @code{avformat_open_input}),
|
|
| 253 | 254 |
are supported: |
| 254 | 255 |
|
| 256 |
+Flags for @code{rtsp_transport}:
|
|
| 257 |
+ |
|
| 255 | 258 |
@table @option |
| 256 | 259 |
|
| 257 | 260 |
@item udp |
| ... | ... |
@@ -261,21 +264,25 @@ Use UDP as lower transport protocol. |
| 261 | 261 |
Use TCP (interleaving within the RTSP control channel) as lower |
| 262 | 262 |
transport protocol. |
| 263 | 263 |
|
| 264 |
-@item multicast |
|
| 264 |
+@item udp_multicast |
|
| 265 | 265 |
Use UDP multicast as lower transport protocol. |
| 266 | 266 |
|
| 267 | 267 |
@item http |
| 268 | 268 |
Use HTTP tunneling as lower transport protocol, which is useful for |
| 269 | 269 |
passing proxies. |
| 270 |
- |
|
| 271 |
-@item filter_src |
|
| 272 |
-Accept packets only from negotiated peer address and port. |
|
| 273 | 270 |
@end table |
| 274 | 271 |
|
| 275 | 272 |
Multiple lower transport protocols may be specified, in that case they are |
| 276 | 273 |
tried one at a time (if the setup of one fails, the next one is tried). |
| 277 | 274 |
For the muxer, only the @code{tcp} and @code{udp} options are supported.
|
| 278 | 275 |
|
| 276 |
+Flags for @code{rtsp_flags}:
|
|
| 277 |
+ |
|
| 278 |
+@table @option |
|
| 279 |
+@item filter_src |
|
| 280 |
+Accept packets only from negotiated peer address and port. |
|
| 281 |
+@end table |
|
| 282 |
+ |
|
| 279 | 283 |
When receiving data over UDP, the demuxer tries to reorder received packets |
| 280 | 284 |
(since they may arrive out of order, or packets may get lost totally). In |
| 281 | 285 |
order for this to be enabled, a maximum delay must be specified in the |
| ... | ... |
@@ -291,13 +298,13 @@ Example command lines: |
| 291 | 291 |
To watch a stream over UDP, with a max reordering delay of 0.5 seconds: |
| 292 | 292 |
|
| 293 | 293 |
@example |
| 294 |
-ffplay -max_delay 500000 rtsp://server/video.mp4?udp |
|
| 294 |
+ffplay -max_delay 500000 -rtsp_transport udp rtsp://server/video.mp4 |
|
| 295 | 295 |
@end example |
| 296 | 296 |
|
| 297 | 297 |
To watch a stream tunneled over HTTP: |
| 298 | 298 |
|
| 299 | 299 |
@example |
| 300 |
-ffplay rtsp://server/video.mp4?http |
|
| 300 |
+ffplay -rtsp_transport http rtsp://server/video.mp4 |
|
| 301 | 301 |
@end example |
| 302 | 302 |
|
| 303 | 303 |
To send a stream in realtime to a RTSP server, for others to watch: |
| ... | ... |
@@ -355,6 +355,8 @@ typedef struct OptionsContext {
|
| 355 | 355 |
int nb_inter_matrices; |
| 356 | 356 |
SpecifierOpt *top_field_first; |
| 357 | 357 |
int nb_top_field_first; |
| 358 |
+ SpecifierOpt *presets; |
|
| 359 |
+ int nb_presets; |
|
| 358 | 360 |
#if CONFIG_AVFILTER |
| 359 | 361 |
SpecifierOpt *filters; |
| 360 | 362 |
int nb_filters; |
| ... | ... |
@@ -3202,15 +3204,62 @@ static void parse_forced_key_frames(char *kf, OutputStream *ost) |
| 3202 | 3202 |
} |
| 3203 | 3203 |
} |
| 3204 | 3204 |
|
| 3205 |
+static uint8_t *get_line(AVIOContext *s) |
|
| 3206 |
+{
|
|
| 3207 |
+ AVIOContext *line; |
|
| 3208 |
+ uint8_t *buf; |
|
| 3209 |
+ char c; |
|
| 3210 |
+ |
|
| 3211 |
+ if (avio_open_dyn_buf(&line) < 0) {
|
|
| 3212 |
+ av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n"); |
|
| 3213 |
+ exit_program(1); |
|
| 3214 |
+ } |
|
| 3215 |
+ |
|
| 3216 |
+ while ((c = avio_r8(s)) && c != '\n') |
|
| 3217 |
+ avio_w8(line, c); |
|
| 3218 |
+ avio_w8(line, 0); |
|
| 3219 |
+ avio_close_dyn_buf(line, &buf); |
|
| 3220 |
+ |
|
| 3221 |
+ return buf; |
|
| 3222 |
+} |
|
| 3223 |
+ |
|
| 3224 |
+static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s) |
|
| 3225 |
+{
|
|
| 3226 |
+ int i, ret = 1; |
|
| 3227 |
+ char filename[1000]; |
|
| 3228 |
+ const char *base[3] = { getenv("AVCONV_DATADIR"),
|
|
| 3229 |
+ getenv("HOME"),
|
|
| 3230 |
+ AVCONV_DATADIR, |
|
| 3231 |
+ }; |
|
| 3232 |
+ |
|
| 3233 |
+ for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) {
|
|
| 3234 |
+ if (!base[i]) |
|
| 3235 |
+ continue; |
|
| 3236 |
+ if (codec_name) {
|
|
| 3237 |
+ snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i], |
|
| 3238 |
+ i != 1 ? "" : "/.avconv", codec_name, preset_name); |
|
| 3239 |
+ ret = avio_open(s, filename, AVIO_FLAG_READ); |
|
| 3240 |
+ } |
|
| 3241 |
+ if (ret) {
|
|
| 3242 |
+ snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i], |
|
| 3243 |
+ i != 1 ? "" : "/.avconv", preset_name); |
|
| 3244 |
+ ret = avio_open(s, filename, AVIO_FLAG_READ); |
|
| 3245 |
+ } |
|
| 3246 |
+ } |
|
| 3247 |
+ return ret; |
|
| 3248 |
+} |
|
| 3249 |
+ |
|
| 3205 | 3250 |
static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type) |
| 3206 | 3251 |
{
|
| 3207 | 3252 |
OutputStream *ost; |
| 3208 | 3253 |
AVStream *st = av_new_stream(oc, oc->nb_streams < o->nb_streamid_map ? o->streamid_map[oc->nb_streams] : 0); |
| 3209 |
- int idx = oc->nb_streams - 1; |
|
| 3254 |
+ int idx = oc->nb_streams - 1, ret = 0; |
|
| 3210 | 3255 |
int64_t max_frames = INT64_MAX; |
| 3211 | 3256 |
char *bsf = NULL, *next, *codec_tag = NULL; |
| 3212 | 3257 |
AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL; |
| 3213 | 3258 |
double qscale = -1; |
| 3259 |
+ char *buf = NULL, *arg = NULL, *preset = NULL; |
|
| 3260 |
+ AVIOContext *s = NULL; |
|
| 3214 | 3261 |
|
| 3215 | 3262 |
if (!st) {
|
| 3216 | 3263 |
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 |
| 3232 | 3232 |
avcodec_get_context_defaults3(st->codec, ost->enc); |
| 3233 | 3233 |
st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy |
| 3234 | 3234 |
|
| 3235 |
+ MATCH_PER_STREAM_OPT(presets, str, preset, oc, st); |
|
| 3236 |
+ if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
|
|
| 3237 |
+ do {
|
|
| 3238 |
+ buf = get_line(s); |
|
| 3239 |
+ if (!buf[0] || buf[0] == '#') {
|
|
| 3240 |
+ av_free(buf); |
|
| 3241 |
+ continue; |
|
| 3242 |
+ } |
|
| 3243 |
+ if (!(arg = strchr(buf, '='))) {
|
|
| 3244 |
+ av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n"); |
|
| 3245 |
+ exit_program(1); |
|
| 3246 |
+ } |
|
| 3247 |
+ *arg++ = 0; |
|
| 3248 |
+ av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE); |
|
| 3249 |
+ av_free(buf); |
|
| 3250 |
+ } while (!s->eof_reached); |
|
| 3251 |
+ avio_close(s); |
|
| 3252 |
+ } |
|
| 3253 |
+ if (ret) {
|
|
| 3254 |
+ av_log(NULL, AV_LOG_FATAL, |
|
| 3255 |
+ "Preset %s specified for stream %d:%d, but could not be opened.\n", |
|
| 3256 |
+ preset, ost->file_index, ost->index); |
|
| 3257 |
+ exit_program(1); |
|
| 3258 |
+ } |
|
| 3259 |
+ |
|
| 3235 | 3260 |
MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st); |
| 3236 | 3261 |
ost->max_frames = max_frames; |
| 3237 | 3262 |
|
| ... | ... |
@@ -4209,6 +4283,7 @@ static const OptionDef options[] = {
|
| 4209 | 4209 |
{ "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
|
| 4210 | 4210 |
{ "c", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" },
|
| 4211 | 4211 |
{ "codec", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" },
|
| 4212 |
+ { "pre", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(presets)}, "preset name", "preset" },
|
|
| 4212 | 4213 |
{ "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" },
|
| 4213 | 4214 |
{ "map_meta_data", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_meta_data}, "DEPRECATED set meta data information of outfile from infile",
|
| 4214 | 4215 |
"outfile[,metadata]:infile[,metadata]" }, |
| ... | ... |
@@ -30,7 +30,7 @@ |
| 30 | 30 |
|
| 31 | 31 |
#define LIBAVFILTER_VERSION_MAJOR 2 |
| 32 | 32 |
#define LIBAVFILTER_VERSION_MINOR 43 |
| 33 |
-#define LIBAVFILTER_VERSION_MICRO 6 |
|
| 33 |
+#define LIBAVFILTER_VERSION_MICRO 7 |
|
| 34 | 34 |
|
| 35 | 35 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
| 36 | 36 |
LIBAVFILTER_VERSION_MINOR, \ |
| ... | ... |
@@ -81,7 +81,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) |
| 81 | 81 |
|
| 82 | 82 |
if (!args) {
|
| 83 | 83 |
av_log(ctx, AV_LOG_ERROR, |
| 84 |
- "Filter expects 2 or 4 arguments, none provided\n"); |
|
| 84 |
+ "Filter expects 2 or 4 or 6 arguments, none provided\n"); |
|
| 85 | 85 |
return AVERROR(EINVAL); |
| 86 | 86 |
} |
| 87 | 87 |
|
| ... | ... |
@@ -342,4 +342,4 @@ AVFilter avfilter_vf_boxblur = {
|
| 342 | 342 |
.outputs = (AVFilterPad[]) {{ .name = "default",
|
| 343 | 343 |
.type = AVMEDIA_TYPE_VIDEO, }, |
| 344 | 344 |
{ .name = NULL}},
|
| 345 |
-}; |
|
| 345 |
+}; |
|
| 346 | 346 |
\ No newline at end of file |
| ... | ... |
@@ -154,9 +154,9 @@ static const char *delogo_get_name(void *ctx) |
| 154 | 154 |
} |
| 155 | 155 |
|
| 156 | 156 |
static const AVClass delogo_class = {
|
| 157 |
- "DelogoContext", |
|
| 158 |
- delogo_get_name, |
|
| 159 |
- delogo_options |
|
| 157 |
+ .class_name = "DelogoContext", |
|
| 158 |
+ .item_name = delogo_get_name, |
|
| 159 |
+ .option = delogo_options, |
|
| 160 | 160 |
}; |
| 161 | 161 |
|
| 162 | 162 |
static int query_formats(AVFilterContext *ctx) |
| ... | ... |
@@ -285,4 +285,4 @@ AVFilter avfilter_vf_delogo = {
|
| 285 | 285 |
.outputs = (AVFilterPad[]) {{ .name = "default",
|
| 286 | 286 |
.type = AVMEDIA_TYPE_VIDEO, }, |
| 287 | 287 |
{ .name = NULL}},
|
| 288 |
-}; |
|
| 288 |
+}; |
|
| 289 | 289 |
\ No newline at end of file |
| ... | ... |
@@ -350,21 +350,27 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) |
| 350 | 350 |
{ .name = NULL}}, \
|
| 351 | 351 |
} |
| 352 | 352 |
|
| 353 |
+#if CONFIG_LUT_FILTER |
|
| 353 | 354 |
DEFINE_LUT_FILTER(lut, "Compute and apply a lookup table to the RGB/YUV input video.", init); |
| 355 |
+#endif |
|
| 356 |
+#if CONFIG_LUTYUV_FILTER |
|
| 354 | 357 |
DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video.", init); |
| 358 |
+#endif |
|
| 359 |
+#if CONFIG_LUTRGB_FILTER |
|
| 355 | 360 |
DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video.", init); |
| 361 |
+#endif |
|
| 356 | 362 |
|
| 357 | 363 |
#if CONFIG_NEGATE_FILTER |
| 358 | 364 |
|
| 359 | 365 |
static int negate_init(AVFilterContext *ctx, const char *args, void *opaque) |
| 360 | 366 |
{
|
| 361 | 367 |
LutContext *lut = ctx->priv; |
| 362 |
- char lut_params[1024]; |
|
| 368 |
+ char lut_params[64]; |
|
| 363 | 369 |
|
| 364 | 370 |
if (args) |
| 365 | 371 |
sscanf(args, "%d", &lut->negate_alpha); |
| 366 | 372 |
|
| 367 |
- av_log(ctx, AV_LOG_INFO, "negate_alpha:%d\n", lut->negate_alpha); |
|
| 373 |
+ av_log(ctx, AV_LOG_DEBUG, "negate_alpha:%d\n", lut->negate_alpha); |
|
| 368 | 374 |
|
| 369 | 375 |
snprintf(lut_params, sizeof(lut_params), "c0=negval:c1=negval:c2=negval:a=%s", |
| 370 | 376 |
lut->negate_alpha ? "negval" : "val"); |
| ... | ... |
@@ -374,4 +380,4 @@ static int negate_init(AVFilterContext *ctx, const char *args, void *opaque) |
| 374 | 374 |
|
| 375 | 375 |
DEFINE_LUT_FILTER(negate, "Negate input video.", negate_init); |
| 376 | 376 |
|
| 377 |
-#endif |
|
| 377 |
+#endif |
|
| 378 | 378 |
\ No newline at end of file |
| ... | ... |
@@ -275,9 +275,6 @@ static int aiff_read_header(AVFormatContext *s, |
| 275 | 275 |
|
| 276 | 276 |
got_sound: |
| 277 | 277 |
/* Now positioned, get the sound data start and end */ |
| 278 |
- if (st->nb_frames) |
|
| 279 |
- s->file_size = st->nb_frames * st->codec->block_align; |
|
| 280 |
- |
|
| 281 | 278 |
av_set_pts_info(st, 64, 1, st->codec->sample_rate); |
| 282 | 279 |
st->start_time = 0; |
| 283 | 280 |
st->duration = st->codec->frame_size ? |
| ... | ... |
@@ -745,10 +745,12 @@ typedef struct AVFormatContext {
|
| 745 | 745 |
*/ |
| 746 | 746 |
int64_t duration; |
| 747 | 747 |
|
| 748 |
+#if FF_API_FILESIZE |
|
| 748 | 749 |
/** |
| 749 | 750 |
* decoding: total file size, 0 if unknown |
| 750 | 751 |
*/ |
| 751 |
- int64_t file_size; |
|
| 752 |
+ attribute_deprecated int64_t file_size; |
|
| 753 |
+#endif |
|
| 752 | 754 |
|
| 753 | 755 |
/** |
| 754 | 756 |
* Decoding: total stream bitrate in bit/s, 0 if not |
| ... | ... |
@@ -763,7 +765,12 @@ typedef struct AVFormatContext {
|
| 763 | 763 |
/* av_seek_frame() support */ |
| 764 | 764 |
int64_t data_offset; /**< offset of the first packet */ |
| 765 | 765 |
|
| 766 |
- int mux_rate; |
|
| 766 |
+#if FF_API_MUXRATE |
|
| 767 |
+ /** |
|
| 768 |
+ * use mpeg muxer private options instead |
|
| 769 |
+ */ |
|
| 770 |
+ attribute_deprecated int mux_rate; |
|
| 771 |
+#endif |
|
| 767 | 772 |
unsigned int packet_size; |
| 768 | 773 |
int preload; |
| 769 | 774 |
int max_delay; |
| ... | ... |
@@ -778,13 +778,14 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen) |
| 778 | 778 |
{
|
| 779 | 779 |
int i; |
| 780 | 780 |
|
| 781 |
+ if (buflen <= 0) |
|
| 782 |
+ return AVERROR(EINVAL); |
|
| 781 | 783 |
// reserve 1 byte for terminating 0 |
| 782 | 784 |
buflen = FFMIN(buflen - 1, maxlen); |
| 783 | 785 |
for (i = 0; i < buflen; i++) |
| 784 | 786 |
if (!(buf[i] = avio_r8(s))) |
| 785 | 787 |
return i + 1; |
| 786 |
- if (buflen) |
|
| 787 |
- buf[i] = 0; |
|
| 788 |
+ buf[i] = 0; |
|
| 788 | 789 |
for (; i < maxlen; i++) |
| 789 | 790 |
if (!avio_r8(s)) |
| 790 | 791 |
return i + 1; |
| ... | ... |
@@ -796,6 +797,8 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen) |
| 796 | 796 |
{\
|
| 797 | 797 |
char* q = buf;\ |
| 798 | 798 |
int ret = 0;\ |
| 799 |
+ if (buflen <= 0) \ |
|
| 800 |
+ return AVERROR(EINVAL); \ |
|
| 799 | 801 |
while (ret + 1 < maxlen) {\
|
| 800 | 802 |
uint8_t tmp;\ |
| 801 | 803 |
uint32_t ch;\ |
| ... | ... |
@@ -292,8 +292,6 @@ static int read_header(AVFormatContext *s, |
| 292 | 292 |
"block size or frame size are variable.\n"); |
| 293 | 293 |
return AVERROR_INVALIDDATA; |
| 294 | 294 |
} |
| 295 |
- s->file_size = avio_size(pb); |
|
| 296 |
- s->file_size = FFMAX(0, s->file_size); |
|
| 297 | 295 |
|
| 298 | 296 |
av_set_pts_info(st, 64, 1, st->codec->sample_rate); |
| 299 | 297 |
st->start_time = 0; |
| ... | ... |
@@ -99,6 +99,33 @@ static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, |
| 99 | 99 |
return 0; |
| 100 | 100 |
} |
| 101 | 101 |
|
| 102 |
+static int mov_metadata_int8(MOVContext *c, AVIOContext *pb, |
|
| 103 |
+ unsigned len, const char *key) |
|
| 104 |
+{
|
|
| 105 |
+ char buf[16]; |
|
| 106 |
+ |
|
| 107 |
+ /* bypass padding bytes */ |
|
| 108 |
+ avio_r8(pb); |
|
| 109 |
+ avio_r8(pb); |
|
| 110 |
+ avio_r8(pb); |
|
| 111 |
+ |
|
| 112 |
+ snprintf(buf, sizeof(buf), "%hu", avio_r8(pb)); |
|
| 113 |
+ av_dict_set(&c->fc->metadata, key, buf, 0); |
|
| 114 |
+ |
|
| 115 |
+ return 0; |
|
| 116 |
+} |
|
| 117 |
+ |
|
| 118 |
+static int mov_metadata_stik(MOVContext *c, AVIOContext *pb, |
|
| 119 |
+ unsigned len, const char *key) |
|
| 120 |
+{
|
|
| 121 |
+ char buf[16]; |
|
| 122 |
+ |
|
| 123 |
+ snprintf(buf, sizeof(buf), "%hu", avio_r8(pb)); |
|
| 124 |
+ av_dict_set(&c->fc->metadata, key, buf, 0); |
|
| 125 |
+ |
|
| 126 |
+ return 0; |
|
| 127 |
+} |
|
| 128 |
+ |
|
| 102 | 129 |
static const uint32_t mac_to_unicode[128] = {
|
| 103 | 130 |
0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1, |
| 104 | 131 |
0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8, |
| ... | ... |
@@ -174,6 +201,12 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
| 174 | 174 |
parse = mov_metadata_track_or_disc_number; break; |
| 175 | 175 |
case MKTAG( 'd','i','s','k'): key = "disc"; |
| 176 | 176 |
parse = mov_metadata_track_or_disc_number; break; |
| 177 |
+ case MKTAG( 't','v','e','s'): key = "episode_sort"; |
|
| 178 |
+ parse = mov_metadata_int8; break; |
|
| 179 |
+ case MKTAG( 't','v','s','n'): key = "season_number"; |
|
| 180 |
+ parse = mov_metadata_int8; break; |
|
| 181 |
+ case MKTAG( 's','t','i','k'): key = "media_type"; |
|
| 182 |
+ parse = mov_metadata_stik; break; |
|
| 177 | 183 |
} |
| 178 | 184 |
|
| 179 | 185 |
if (c->itunes_metadata && atom.size > 8) {
|
| ... | ... |
@@ -20,7 +20,9 @@ |
| 20 | 20 |
*/ |
| 21 | 21 |
|
| 22 | 22 |
#include "libavutil/fifo.h" |
| 23 |
+#include "libavutil/log.h" |
|
| 23 | 24 |
#include "libavutil/mathematics.h" |
| 25 |
+#include "libavutil/opt.h" |
|
| 24 | 26 |
#include "libavcodec/put_bits.h" |
| 25 | 27 |
#include "avformat.h" |
| 26 | 28 |
#include "mpeg.h" |
| ... | ... |
@@ -56,6 +58,7 @@ typedef struct {
|
| 56 | 56 |
} StreamInfo; |
| 57 | 57 |
|
| 58 | 58 |
typedef struct {
|
| 59 |
+ const AVClass *class; |
|
| 59 | 60 |
int packet_size; /* required packet size */ |
| 60 | 61 |
int packet_number; |
| 61 | 62 |
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) |
| 416 | 416 |
video_bitrate += codec_rate; |
| 417 | 417 |
} |
| 418 | 418 |
|
| 419 |
+#if FF_API_MUXRATE |
|
| 419 | 420 |
if(ctx->mux_rate){
|
| 420 | 421 |
s->mux_rate= (ctx->mux_rate + (8 * 50) - 1) / (8 * 50); |
| 421 |
- } else {
|
|
| 422 |
+ } else |
|
| 423 |
+#endif |
|
| 424 |
+ if (!s->mux_rate) {
|
|
| 422 | 425 |
/* we increase slightly the bitrate to take into account the |
| 423 | 426 |
headers. XXX: compute it exactly */ |
| 424 | 427 |
bitrate += bitrate*5/100; |
| ... | ... |
@@ -1227,7 +1233,23 @@ static int mpeg_mux_end(AVFormatContext *ctx) |
| 1227 | 1227 |
return 0; |
| 1228 | 1228 |
} |
| 1229 | 1229 |
|
| 1230 |
+#define OFFSET(x) offsetof(MpegMuxContext, x) |
|
| 1231 |
+#define E AV_OPT_FLAG_ENCODING_PARAM |
|
| 1232 |
+static const AVOption options[] = {
|
|
| 1233 |
+ { "muxrate", NULL, OFFSET(mux_rate), AV_OPT_TYPE_INT, {0}, 0, INT_MAX, E },
|
|
| 1234 |
+ { NULL },
|
|
| 1235 |
+}; |
|
| 1236 |
+ |
|
| 1237 |
+#define MPEGENC_CLASS(flavor)\ |
|
| 1238 |
+static const AVClass flavor ## _class = {\
|
|
| 1239 |
+ .class_name = #flavor " muxer",\ |
|
| 1240 |
+ .item_name = av_default_item_name,\ |
|
| 1241 |
+ .version = LIBAVUTIL_VERSION_INT,\ |
|
| 1242 |
+ .option = options,\ |
|
| 1243 |
+}; |
|
| 1244 |
+ |
|
| 1230 | 1245 |
#if CONFIG_MPEG1SYSTEM_MUXER |
| 1246 |
+MPEGENC_CLASS(mpeg) |
|
| 1231 | 1247 |
AVOutputFormat ff_mpeg1system_muxer = {
|
| 1232 | 1248 |
.name = "mpeg", |
| 1233 | 1249 |
.long_name = NULL_IF_CONFIG_SMALL("MPEG-1 System format"),
|
| ... | ... |
@@ -1239,9 +1261,11 @@ AVOutputFormat ff_mpeg1system_muxer = {
|
| 1239 | 1239 |
.write_header = mpeg_mux_init, |
| 1240 | 1240 |
.write_packet = mpeg_mux_write_packet, |
| 1241 | 1241 |
.write_trailer = mpeg_mux_end, |
| 1242 |
+ .priv_class = &mpeg_class, |
|
| 1242 | 1243 |
}; |
| 1243 | 1244 |
#endif |
| 1244 | 1245 |
#if CONFIG_MPEG1VCD_MUXER |
| 1246 |
+MPEGENC_CLASS(vcd) |
|
| 1245 | 1247 |
AVOutputFormat ff_mpeg1vcd_muxer = {
|
| 1246 | 1248 |
.name = "vcd", |
| 1247 | 1249 |
.long_name = NULL_IF_CONFIG_SMALL("MPEG-1 System format (VCD)"),
|
| ... | ... |
@@ -1252,9 +1276,11 @@ AVOutputFormat ff_mpeg1vcd_muxer = {
|
| 1252 | 1252 |
.write_header = mpeg_mux_init, |
| 1253 | 1253 |
.write_packet = mpeg_mux_write_packet, |
| 1254 | 1254 |
.write_trailer = mpeg_mux_end, |
| 1255 |
+ .priv_class = &vcd_class, |
|
| 1255 | 1256 |
}; |
| 1256 | 1257 |
#endif |
| 1257 | 1258 |
#if CONFIG_MPEG2VOB_MUXER |
| 1259 |
+MPEGENC_CLASS(vob) |
|
| 1258 | 1260 |
AVOutputFormat ff_mpeg2vob_muxer = {
|
| 1259 | 1261 |
.name = "vob", |
| 1260 | 1262 |
.long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"),
|
| ... | ... |
@@ -1266,11 +1292,13 @@ AVOutputFormat ff_mpeg2vob_muxer = {
|
| 1266 | 1266 |
.write_header = mpeg_mux_init, |
| 1267 | 1267 |
.write_packet = mpeg_mux_write_packet, |
| 1268 | 1268 |
.write_trailer = mpeg_mux_end, |
| 1269 |
+ .priv_class = &vob_class, |
|
| 1269 | 1270 |
}; |
| 1270 | 1271 |
#endif |
| 1271 | 1272 |
|
| 1272 | 1273 |
/* Same as mpeg2vob_mux except that the pack size is 2324 */ |
| 1273 | 1274 |
#if CONFIG_MPEG2SVCD_MUXER |
| 1275 |
+MPEGENC_CLASS(svcd) |
|
| 1274 | 1276 |
AVOutputFormat ff_mpeg2svcd_muxer = {
|
| 1275 | 1277 |
.name = "svcd", |
| 1276 | 1278 |
.long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"),
|
| ... | ... |
@@ -1282,11 +1310,13 @@ AVOutputFormat ff_mpeg2svcd_muxer = {
|
| 1282 | 1282 |
.write_header = mpeg_mux_init, |
| 1283 | 1283 |
.write_packet = mpeg_mux_write_packet, |
| 1284 | 1284 |
.write_trailer = mpeg_mux_end, |
| 1285 |
+ .priv_class = &svcd_class, |
|
| 1285 | 1286 |
}; |
| 1286 | 1287 |
#endif |
| 1287 | 1288 |
|
| 1288 | 1289 |
/* Same as mpeg2vob_mux except the 'is_dvd' flag is set to produce NAV pkts */ |
| 1289 | 1290 |
#if CONFIG_MPEG2DVD_MUXER |
| 1291 |
+MPEGENC_CLASS(dvd) |
|
| 1290 | 1292 |
AVOutputFormat ff_mpeg2dvd_muxer = {
|
| 1291 | 1293 |
.name = "dvd", |
| 1292 | 1294 |
.long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (DVD VOB)"),
|
| ... | ... |
@@ -1298,5 +1328,6 @@ AVOutputFormat ff_mpeg2dvd_muxer = {
|
| 1298 | 1298 |
.write_header = mpeg_mux_init, |
| 1299 | 1299 |
.write_packet = mpeg_mux_write_packet, |
| 1300 | 1300 |
.write_trailer = mpeg_mux_end, |
| 1301 |
+ .priv_class = &dvd_class, |
|
| 1301 | 1302 |
}; |
| 1302 | 1303 |
#endif |
| ... | ... |
@@ -92,6 +92,7 @@ static const AVOption options[] = {
|
| 92 | 92 |
{"mpegts_m2ts_mode", "Enable m2ts mode.",
|
| 93 | 93 |
offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_INT, {.dbl = -1 },
|
| 94 | 94 |
-1,1, AV_OPT_FLAG_ENCODING_PARAM}, |
| 95 |
+ { "muxrate", NULL, offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT, {1}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
|
|
| 95 | 96 |
{ NULL },
|
| 96 | 97 |
}; |
| 97 | 98 |
|
| ... | ... |
@@ -562,7 +563,10 @@ static int mpegts_write_header(AVFormatContext *s) |
| 562 | 562 |
service->pcr_pid = ts_st->pid; |
| 563 | 563 |
} |
| 564 | 564 |
|
| 565 |
- ts->mux_rate = s->mux_rate ? s->mux_rate : 1; |
|
| 565 |
+#if FF_API_MUXRATE |
|
| 566 |
+ if (s->mux_rate) |
|
| 567 |
+ ts->mux_rate = s->mux_rate; |
|
| 568 |
+#endif |
|
| 566 | 569 |
|
| 567 | 570 |
if (ts->mux_rate > 1) {
|
| 568 | 571 |
service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) / |
| ... | ... |
@@ -74,7 +74,9 @@ static const AVClass *format_child_class_next(const AVClass *prev) |
| 74 | 74 |
|
| 75 | 75 |
static const AVOption options[]={
|
| 76 | 76 |
{"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT, {.dbl = 5000000 }, 32, INT_MAX, D},
|
| 77 |
+#if FF_API_MUXRATE |
|
| 77 | 78 |
{"muxrate", "set mux rate", OFFSET(mux_rate), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E},
|
| 79 |
+#endif |
|
| 78 | 80 |
{"packetsize", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E},
|
| 79 | 81 |
{"fflags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, INT_MIN, INT_MAX, D|E, "fflags"},
|
| 80 | 82 |
{"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) |
| 92 | 92 |
return AVERROR(ENOMEM); |
| 93 | 93 |
|
| 94 | 94 |
avio_rb32(pb); // "RIFF" |
| 95 |
- s->file_size = avio_rl32(pb) + 8; |
|
| 96 |
- avio_skip(pb, 8 + 4 + 1 + 1); // "QLCMfmt " + chunk-size + major-version + minor-version |
|
| 95 |
+ avio_skip(pb, 4 + 8 + 4 + 1 + 1); // filesize + "QLCMfmt " + chunk-size + major-version + minor-version |
|
| 97 | 96 |
|
| 98 | 97 |
st->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
| 99 | 98 |
st->codec->channels = 1; |
| ... | ... |
@@ -98,7 +98,8 @@ int ff_rtp_get_payload_type(AVFormatContext *fmt, AVCodecContext *codec) |
| 98 | 98 |
/* Was the payload type already specified for the RTP muxer? */ |
| 99 | 99 |
if (ofmt && ofmt->priv_class) {
|
| 100 | 100 |
int64_t payload_type; |
| 101 |
- if (av_opt_get_int(fmt->priv_data, "payload_type", 0, &payload_type) >= 0) |
|
| 101 |
+ if (av_opt_get_int(fmt->priv_data, "payload_type", 0, &payload_type) >= 0 && |
|
| 102 |
+ payload_type >= 0) |
|
| 102 | 103 |
return (int)payload_type; |
| 103 | 104 |
} |
| 104 | 105 |
|
| ... | ... |
@@ -465,7 +465,7 @@ AVOutputFormat ff_rtp_muxer = {
|
| 465 | 465 |
.long_name = NULL_IF_CONFIG_SMALL("RTP output format"),
|
| 466 | 466 |
.priv_data_size = sizeof(RTPMuxContext), |
| 467 | 467 |
.audio_codec = CODEC_ID_PCM_MULAW, |
| 468 |
- .video_codec = CODEC_ID_NONE, |
|
| 468 |
+ .video_codec = CODEC_ID_MPEG4, |
|
| 469 | 469 |
.write_header = rtp_write_header, |
| 470 | 470 |
.write_packet = rtp_write_packet, |
| 471 | 471 |
.write_trailer = rtp_write_trailer, |
| ... | ... |
@@ -45,6 +45,7 @@ |
| 45 | 45 |
#include "rtpdec_formats.h" |
| 46 | 46 |
#include "rtpenc_chain.h" |
| 47 | 47 |
#include "url.h" |
| 48 |
+#include "rtpenc.h" |
|
| 48 | 49 |
|
| 49 | 50 |
//#define DEBUG |
| 50 | 51 |
|
| ... | ... |
@@ -56,6 +57,36 @@ |
| 56 | 56 |
#define SDP_MAX_SIZE 16384 |
| 57 | 57 |
#define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH |
| 58 | 58 |
|
| 59 |
+#define OFFSET(x) offsetof(RTSPState, x) |
|
| 60 |
+#define DEC AV_OPT_FLAG_DECODING_PARAM |
|
| 61 |
+#define ENC AV_OPT_FLAG_ENCODING_PARAM |
|
| 62 |
+ |
|
| 63 |
+#define RTSP_FLAG_OPTS(name, longname) \ |
|
| 64 |
+ { name, longname, OFFSET(rtsp_flags), AV_OPT_TYPE_FLAGS, {0}, INT_MIN, INT_MAX, DEC, "rtsp_flags" }, \
|
|
| 65 |
+ { "filter_src", "Only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, "rtsp_flags" }
|
|
| 66 |
+ |
|
| 67 |
+const AVOption ff_rtsp_options[] = {
|
|
| 68 |
+ { "initial_pause", "Don't start playing the stream immediately", OFFSET(initial_pause), AV_OPT_TYPE_INT, {0}, 0, 1, DEC },
|
|
| 69 |
+ FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags), |
|
| 70 |
+ { "rtsp_transport", "RTSP transport protocols", OFFSET(lower_transport_mask), AV_OPT_TYPE_FLAGS, {0}, INT_MIN, INT_MAX, DEC|ENC, "rtsp_transport" }, \
|
|
| 71 |
+ { "udp", "UDP", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_UDP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
|
|
| 72 |
+ { "tcp", "TCP", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_TCP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
|
|
| 73 |
+ { "udp_multicast", "UDP multicast", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_UDP_MULTICAST}, 0, 0, DEC, "rtsp_transport" },
|
|
| 74 |
+ { "http", "HTTP tunneling", 0, AV_OPT_TYPE_CONST, {(1 << RTSP_LOWER_TRANSPORT_HTTP)}, 0, 0, DEC, "rtsp_transport" },
|
|
| 75 |
+ RTSP_FLAG_OPTS("rtsp_flags", "RTSP flags"),
|
|
| 76 |
+ { NULL },
|
|
| 77 |
+}; |
|
| 78 |
+ |
|
| 79 |
+static const AVOption sdp_options[] = {
|
|
| 80 |
+ RTSP_FLAG_OPTS("sdp_flags", "SDP flags"),
|
|
| 81 |
+ { NULL },
|
|
| 82 |
+}; |
|
| 83 |
+ |
|
| 84 |
+static const AVOption rtp_options[] = {
|
|
| 85 |
+ RTSP_FLAG_OPTS("rtp_flags", "RTP flags"),
|
|
| 86 |
+ { NULL },
|
|
| 87 |
+}; |
|
| 88 |
+ |
|
| 59 | 89 |
static void get_word_until_chars(char *buf, int buf_size, |
| 60 | 90 |
const char *sep, const char **pp) |
| 61 | 91 |
{
|
| ... | ... |
@@ -1218,7 +1249,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, |
| 1218 | 1218 |
case RTSP_LOWER_TRANSPORT_UDP: {
|
| 1219 | 1219 |
char url[1024], options[30] = ""; |
| 1220 | 1220 |
|
| 1221 |
- if (rt->filter_source) |
|
| 1221 |
+ if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC) |
|
| 1222 | 1222 |
av_strlcpy(options, "?connect=1", sizeof(options)); |
| 1223 | 1223 |
/* Use source address if specified */ |
| 1224 | 1224 |
if (reply->transports[0].source[0]) {
|
| ... | ... |
@@ -1308,8 +1339,17 @@ int ff_rtsp_connect(AVFormatContext *s) |
| 1308 | 1308 |
|
| 1309 | 1309 |
if (!ff_network_init()) |
| 1310 | 1310 |
return AVERROR(EIO); |
| 1311 |
-redirect: |
|
| 1311 |
+ |
|
| 1312 | 1312 |
rt->control_transport = RTSP_MODE_PLAIN; |
| 1313 |
+ if (rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_HTTP)) {
|
|
| 1314 |
+ rt->lower_transport_mask = 1 << RTSP_LOWER_TRANSPORT_TCP; |
|
| 1315 |
+ rt->control_transport = RTSP_MODE_TUNNEL; |
|
| 1316 |
+ } |
|
| 1317 |
+ /* Only pass through valid flags from here */ |
|
| 1318 |
+ rt->lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_NB) - 1; |
|
| 1319 |
+ |
|
| 1320 |
+redirect: |
|
| 1321 |
+ lower_transport_mask = rt->lower_transport_mask; |
|
| 1313 | 1322 |
/* extract hostname and port */ |
| 1314 | 1323 |
av_url_split(NULL, 0, auth, sizeof(auth), |
| 1315 | 1324 |
host, sizeof(host), &port, path, sizeof(path), s->filename); |
| ... | ... |
@@ -1319,6 +1359,7 @@ redirect: |
| 1319 | 1319 |
if (port < 0) |
| 1320 | 1320 |
port = RTSP_DEFAULT_PORT; |
| 1321 | 1321 |
|
| 1322 |
+#if FF_API_RTSP_URL_OPTIONS |
|
| 1322 | 1323 |
/* search for options */ |
| 1323 | 1324 |
option_list = strrchr(path, '?'); |
| 1324 | 1325 |
if (option_list) {
|
| ... | ... |
@@ -1326,6 +1367,7 @@ redirect: |
| 1326 | 1326 |
* the options back into the same string. */ |
| 1327 | 1327 |
filename = option_list; |
| 1328 | 1328 |
while (option_list) {
|
| 1329 |
+ int handled = 1; |
|
| 1329 | 1330 |
/* move the option pointer */ |
| 1330 | 1331 |
option = ++option_list; |
| 1331 | 1332 |
option_list = strchr(option_list, '&'); |
| ... | ... |
@@ -1343,7 +1385,7 @@ redirect: |
| 1343 | 1343 |
lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_TCP); |
| 1344 | 1344 |
rt->control_transport = RTSP_MODE_TUNNEL; |
| 1345 | 1345 |
} else if (!strcmp(option, "filter_src")) {
|
| 1346 |
- rt->filter_source = 1; |
|
| 1346 |
+ rt->rtsp_flags |= RTSP_FLAG_FILTER_SRC; |
|
| 1347 | 1347 |
} else {
|
| 1348 | 1348 |
/* Write options back into the buffer, using memmove instead |
| 1349 | 1349 |
* of strcpy since the strings may overlap. */ |
| ... | ... |
@@ -1351,10 +1393,16 @@ redirect: |
| 1351 | 1351 |
memmove(++filename, option, len); |
| 1352 | 1352 |
filename += len; |
| 1353 | 1353 |
if (option_list) *filename = '&'; |
| 1354 |
+ handled = 0; |
|
| 1354 | 1355 |
} |
| 1356 |
+ if (handled) |
|
| 1357 |
+ av_log(s, AV_LOG_WARNING, "Options passed via URL are " |
|
| 1358 |
+ "deprecated, use -rtsp_transport " |
|
| 1359 |
+ "and -rtsp_flags instead.\n"); |
|
| 1355 | 1360 |
} |
| 1356 | 1361 |
*filename = 0; |
| 1357 | 1362 |
} |
| 1363 |
+#endif |
|
| 1358 | 1364 |
|
| 1359 | 1365 |
if (!lower_transport_mask) |
| 1360 | 1366 |
lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1; |
| ... | ... |
@@ -1797,8 +1845,9 @@ static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap) |
| 1797 | 1797 |
namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST); |
| 1798 | 1798 |
ff_url_join(url, sizeof(url), "rtp", NULL, |
| 1799 | 1799 |
namebuf, rtsp_st->sdp_port, |
| 1800 |
- "?localport=%d&ttl=%d", rtsp_st->sdp_port, |
|
| 1801 |
- rtsp_st->sdp_ttl); |
|
| 1800 |
+ "?localport=%d&ttl=%d&connect=%d", rtsp_st->sdp_port, |
|
| 1801 |
+ rtsp_st->sdp_ttl, |
|
| 1802 |
+ rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0); |
|
| 1802 | 1803 |
if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE) < 0) {
|
| 1803 | 1804 |
err = AVERROR_INVALIDDATA; |
| 1804 | 1805 |
goto fail; |
| ... | ... |
@@ -1820,6 +1869,13 @@ static int sdp_read_close(AVFormatContext *s) |
| 1820 | 1820 |
return 0; |
| 1821 | 1821 |
} |
| 1822 | 1822 |
|
| 1823 |
+static const AVClass sdp_demuxer_class = {
|
|
| 1824 |
+ .class_name = "SDP demuxer", |
|
| 1825 |
+ .item_name = av_default_item_name, |
|
| 1826 |
+ .option = sdp_options, |
|
| 1827 |
+ .version = LIBAVUTIL_VERSION_INT, |
|
| 1828 |
+}; |
|
| 1829 |
+ |
|
| 1823 | 1830 |
AVInputFormat ff_sdp_demuxer = {
|
| 1824 | 1831 |
.name = "sdp", |
| 1825 | 1832 |
.long_name = NULL_IF_CONFIG_SMALL("SDP"),
|
| ... | ... |
@@ -1828,6 +1884,7 @@ AVInputFormat ff_sdp_demuxer = {
|
| 1828 | 1828 |
.read_header = sdp_read_header, |
| 1829 | 1829 |
.read_packet = ff_rtsp_fetch_packet, |
| 1830 | 1830 |
.read_close = sdp_read_close, |
| 1831 |
+ .priv_class = &sdp_demuxer_class |
|
| 1831 | 1832 |
}; |
| 1832 | 1833 |
#endif /* CONFIG_SDP_DEMUXER */ |
| 1833 | 1834 |
|
| ... | ... |
@@ -1924,6 +1981,13 @@ fail: |
| 1924 | 1924 |
return ret; |
| 1925 | 1925 |
} |
| 1926 | 1926 |
|
| 1927 |
+static const AVClass rtp_demuxer_class = {
|
|
| 1928 |
+ .class_name = "RTP demuxer", |
|
| 1929 |
+ .item_name = av_default_item_name, |
|
| 1930 |
+ .option = rtp_options, |
|
| 1931 |
+ .version = LIBAVUTIL_VERSION_INT, |
|
| 1932 |
+}; |
|
| 1933 |
+ |
|
| 1927 | 1934 |
AVInputFormat ff_rtp_demuxer = {
|
| 1928 | 1935 |
.name = "rtp", |
| 1929 | 1936 |
.long_name = NULL_IF_CONFIG_SMALL("RTP input format"),
|
| ... | ... |
@@ -1933,6 +1997,7 @@ AVInputFormat ff_rtp_demuxer = {
|
| 1933 | 1933 |
.read_packet = ff_rtsp_fetch_packet, |
| 1934 | 1934 |
.read_close = sdp_read_close, |
| 1935 | 1935 |
.flags = AVFMT_NOFILE, |
| 1936 |
+ .priv_class = &rtp_demuxer_class |
|
| 1936 | 1937 |
}; |
| 1937 | 1938 |
#endif /* CONFIG_RTP_DEMUXER */ |
| 1938 | 1939 |
|
| ... | ... |
@@ -29,6 +29,7 @@ |
| 29 | 29 |
#include "httpauth.h" |
| 30 | 30 |
|
| 31 | 31 |
#include "libavutil/log.h" |
| 32 |
+#include "libavutil/opt.h" |
|
| 32 | 33 |
|
| 33 | 34 |
/** |
| 34 | 35 |
* Network layer over which RTP/etc packet data will be transported. |
| ... | ... |
@@ -37,7 +38,10 @@ enum RTSPLowerTransport {
|
| 37 | 37 |
RTSP_LOWER_TRANSPORT_UDP = 0, /**< UDP/unicast */ |
| 38 | 38 |
RTSP_LOWER_TRANSPORT_TCP = 1, /**< TCP; interleaved in RTSP */ |
| 39 | 39 |
RTSP_LOWER_TRANSPORT_UDP_MULTICAST = 2, /**< UDP/multicast */ |
| 40 |
- RTSP_LOWER_TRANSPORT_NB |
|
| 40 |
+ RTSP_LOWER_TRANSPORT_NB, |
|
| 41 |
+ RTSP_LOWER_TRANSPORT_HTTP = 8, /**< HTTP tunneled - not a proper |
|
| 42 |
+ transport mode as such, |
|
| 43 |
+ only for use via AVOptions */ |
|
| 41 | 44 |
}; |
| 42 | 45 |
|
| 43 | 46 |
/** |
| ... | ... |
@@ -313,10 +317,6 @@ typedef struct RTSPState {
|
| 313 | 313 |
/** Reusable buffer for receiving packets */ |
| 314 | 314 |
uint8_t* recvbuf; |
| 315 | 315 |
|
| 316 |
- /** Filter incoming UDP packets - receive packets only from the right |
|
| 317 |
- * source address and port. */ |
|
| 318 |
- int filter_source; |
|
| 319 |
- |
|
| 320 | 316 |
/** |
| 321 | 317 |
* A mask with all requested transport methods |
| 322 | 318 |
*/ |
| ... | ... |
@@ -349,8 +349,17 @@ typedef struct RTSPState {
|
| 349 | 349 |
|
| 350 | 350 |
/** Whether the server accepts the x-Dynamic-Rate header */ |
| 351 | 351 |
int accept_dynamic_rate; |
| 352 |
+ |
|
| 353 |
+ /** |
|
| 354 |
+ * Various option flags for the RTSP muxer/demuxer. |
|
| 355 |
+ */ |
|
| 356 |
+ int rtsp_flags; |
|
| 352 | 357 |
} RTSPState; |
| 353 | 358 |
|
| 359 |
+#define RTSP_FLAG_FILTER_SRC 0x1 /**< Filter incoming UDP packets - |
|
| 360 |
+ receive packets only from the right |
|
| 361 |
+ source address and port. */ |
|
| 362 |
+ |
|
| 354 | 363 |
/** |
| 355 | 364 |
* Describes a single stream, as identified by a single m= line block in the |
| 356 | 365 |
* 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, |
| 537 | 537 |
*/ |
| 538 | 538 |
void ff_rtsp_undo_setup(AVFormatContext *s); |
| 539 | 539 |
|
| 540 |
+extern const AVOption ff_rtsp_options[]; |
|
| 541 |
+ |
|
| 540 | 542 |
#endif /* AVFORMAT_RTSP_H */ |
| ... | ... |
@@ -22,7 +22,6 @@ |
| 22 | 22 |
#include "libavutil/avstring.h" |
| 23 | 23 |
#include "libavutil/intreadwrite.h" |
| 24 | 24 |
#include "libavutil/mathematics.h" |
| 25 |
-#include "libavutil/opt.h" |
|
| 26 | 25 |
#include "avformat.h" |
| 27 | 26 |
|
| 28 | 27 |
#include "internal.h" |
| ... | ... |
@@ -388,15 +387,10 @@ static int rtsp_read_close(AVFormatContext *s) |
| 388 | 388 |
return 0; |
| 389 | 389 |
} |
| 390 | 390 |
|
| 391 |
-static const AVOption options[] = {
|
|
| 392 |
- { "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 },
|
|
| 393 |
- { NULL },
|
|
| 394 |
-}; |
|
| 395 |
- |
|
| 396 | 391 |
const AVClass rtsp_demuxer_class = {
|
| 397 | 392 |
.class_name = "RTSP demuxer", |
| 398 | 393 |
.item_name = av_default_item_name, |
| 399 |
- .option = options, |
|
| 394 |
+ .option = ff_rtsp_options, |
|
| 400 | 395 |
.version = LIBAVUTIL_VERSION_INT, |
| 401 | 396 |
}; |
| 402 | 397 |
|
| ... | ... |
@@ -33,20 +33,13 @@ |
| 33 | 33 |
#include "libavutil/intreadwrite.h" |
| 34 | 34 |
#include "libavutil/avstring.h" |
| 35 | 35 |
#include "url.h" |
| 36 |
-#include "libavutil/opt.h" |
|
| 37 |
-#include "rtpenc.h" |
|
| 38 | 36 |
|
| 39 | 37 |
#define SDP_MAX_SIZE 16384 |
| 40 | 38 |
|
| 41 |
-static const AVOption options[] = {
|
|
| 42 |
- FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags), |
|
| 43 |
- { NULL },
|
|
| 44 |
-}; |
|
| 45 |
- |
|
| 46 | 39 |
static const AVClass rtsp_muxer_class = {
|
| 47 | 40 |
.class_name = "RTSP muxer", |
| 48 | 41 |
.item_name = av_default_item_name, |
| 49 |
- .option = options, |
|
| 42 |
+ .option = ff_rtsp_options, |
|
| 50 | 43 |
.version = LIBAVUTIL_VERSION_INT, |
| 51 | 44 |
}; |
| 52 | 45 |
|
| ... | ... |
@@ -1902,7 +1902,7 @@ static int has_duration(AVFormatContext *ic) |
| 1902 | 1902 |
static void update_stream_timings(AVFormatContext *ic) |
| 1903 | 1903 |
{
|
| 1904 | 1904 |
int64_t start_time, start_time1, start_time_text, end_time, end_time1; |
| 1905 |
- int64_t duration, duration1; |
|
| 1905 |
+ int64_t duration, duration1, filesize; |
|
| 1906 | 1906 |
int i; |
| 1907 | 1907 |
AVStream *st; |
| 1908 | 1908 |
|
| ... | ... |
@@ -1945,9 +1945,9 @@ static void update_stream_timings(AVFormatContext *ic) |
| 1945 | 1945 |
if (duration != INT64_MIN && ic->duration == AV_NOPTS_VALUE) {
|
| 1946 | 1946 |
ic->duration = duration; |
| 1947 | 1947 |
} |
| 1948 |
- if (ic->file_size > 0 && ic->duration != AV_NOPTS_VALUE) {
|
|
| 1948 |
+ if (ic->pb && (filesize = avio_size(ic->pb)) > 0 && ic->duration != AV_NOPTS_VALUE) {
|
|
| 1949 | 1949 |
/* compute the bitrate */ |
| 1950 |
- ic->bit_rate = (double)ic->file_size * 8.0 * AV_TIME_BASE / |
|
| 1950 |
+ ic->bit_rate = (double)filesize * 8.0 * AV_TIME_BASE / |
|
| 1951 | 1951 |
(double)ic->duration; |
| 1952 | 1952 |
} |
| 1953 | 1953 |
} |
| ... | ... |
@@ -1988,9 +1988,8 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic) |
| 1988 | 1988 |
|
| 1989 | 1989 |
/* if duration is already set, we believe it */ |
| 1990 | 1990 |
if (ic->duration == AV_NOPTS_VALUE && |
| 1991 |
- ic->bit_rate != 0 && |
|
| 1992 |
- ic->file_size != 0) {
|
|
| 1993 |
- filesize = ic->file_size; |
|
| 1991 |
+ ic->bit_rate != 0) {
|
|
| 1992 |
+ filesize = ic->pb ? avio_size(ic->pb) : 0; |
|
| 1994 | 1993 |
if (filesize > 0) {
|
| 1995 | 1994 |
for(i = 0; i < ic->nb_streams; i++) {
|
| 1996 | 1995 |
st = ic->streams[i]; |
| ... | ... |
@@ -2034,7 +2033,7 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) |
| 2034 | 2034 |
|
| 2035 | 2035 |
/* estimate the end time (duration) */ |
| 2036 | 2036 |
/* XXX: may need to support wrapping */ |
| 2037 |
- filesize = ic->file_size; |
|
| 2037 |
+ filesize = ic->pb ? avio_size(ic->pb) : 0; |
|
| 2038 | 2038 |
end_time = AV_NOPTS_VALUE; |
| 2039 | 2039 |
do{
|
| 2040 | 2040 |
offset = filesize - (DURATION_MAX_READ_SIZE<<retry); |
| ... | ... |
@@ -2098,7 +2097,6 @@ static void estimate_timings(AVFormatContext *ic, int64_t old_offset) |
| 2098 | 2098 |
if (file_size < 0) |
| 2099 | 2099 |
file_size = 0; |
| 2100 | 2100 |
} |
| 2101 |
- ic->file_size = file_size; |
|
| 2102 | 2101 |
|
| 2103 | 2102 |
if ((!strcmp(ic->iformat->name, "mpeg") || |
| 2104 | 2103 |
!strcmp(ic->iformat->name, "mpegts")) && |
| ... | ... |
@@ -25,7 +25,7 @@ |
| 25 | 25 |
|
| 26 | 26 |
#define LIBAVFORMAT_VERSION_MAJOR 53 |
| 27 | 27 |
#define LIBAVFORMAT_VERSION_MINOR 16 |
| 28 |
-#define LIBAVFORMAT_VERSION_MICRO 0 |
|
| 28 |
+#define LIBAVFORMAT_VERSION_MICRO 1 |
|
| 29 | 29 |
|
| 30 | 30 |
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |
| 31 | 31 |
LIBAVFORMAT_VERSION_MINOR, \ |
| ... | ... |
@@ -89,5 +89,14 @@ |
| 89 | 89 |
#ifndef FF_API_TIMESTAMP |
| 90 | 90 |
#define FF_API_TIMESTAMP (LIBAVFORMAT_VERSION_MAJOR < 54) |
| 91 | 91 |
#endif |
| 92 |
+#ifndef FF_API_FILESIZE |
|
| 93 |
+#define FF_API_FILESIZE (LIBAVFORMAT_VERSION_MAJOR < 54) |
|
| 94 |
+#endif |
|
| 95 |
+#ifndef FF_API_MUXRATE |
|
| 96 |
+#define FF_API_MUXRATE (LIBAVFORMAT_VERSION_MAJOR < 54) |
|
| 97 |
+#endif |
|
| 98 |
+#ifndef FF_API_RTSP_URL_OPTIONS |
|
| 99 |
+#define FF_API_RTSP_URL_OPTIONS (LIBAVFORMAT_VERSION_MAJOR < 54) |
|
| 100 |
+#endif |
|
| 92 | 101 |
|
| 93 | 102 |
#endif /* AVFORMAT_VERSION_H */ |
| ... | ... |
@@ -503,7 +503,8 @@ int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_ |
| 503 | 503 |
int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) |
| 504 | 504 |
{
|
| 505 | 505 |
const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0); |
| 506 |
- const AVOption *flag = av_opt_find(obj, flag_name, NULL, 0, 0); |
|
| 506 |
+ const AVOption *flag = av_opt_find(obj, flag_name, |
|
| 507 |
+ field ? field->unit : NULL, 0, 0); |
|
| 507 | 508 |
int64_t res; |
| 508 | 509 |
|
| 509 | 510 |
if (!field || !flag || flag->type != AV_OPT_TYPE_CONST || |
| ... | ... |
@@ -700,6 +701,7 @@ int av_set_options_string(void *ctx, const char *opts, |
| 700 | 700 |
|
| 701 | 701 |
if (!opts) |
| 702 | 702 |
return 0; |
| 703 |
+ |
|
| 703 | 704 |
while (*opts) {
|
| 704 | 705 |
if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0) |
| 705 | 706 |
return ret; |