1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-01-08 13:22:53 +02:00

Merge remote-tracking branch 'qatar/master'

* 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>
This commit is contained in:
Michael Niedermayer 2011-10-18 01:33:09 +02:00
commit fae714a9fb
27 changed files with 398 additions and 71 deletions

View File

@ -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]" },

View File

@ -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

View File

@ -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.

View File

@ -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:

View File

@ -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]" },

View File

@ -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, \

View File

@ -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}},
}; };

View File

@ -154,9 +154,9 @@ static const char *delogo_get_name(void *ctx)
} }
static const AVClass delogo_class = { static const AVClass delogo_class = {
"DelogoContext", .class_name = "DelogoContext",
delogo_get_name, .item_name = delogo_get_name,
delogo_options .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}},
}; };

View File

@ -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

View File

@ -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 ?

View File

@ -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;

View File

@ -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;\

View File

@ -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;

View File

@ -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) {

View File

@ -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

View File

@ -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) /

View File

@ -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"},

View File

@ -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, 4 + 8 + 4 + 1 + 1); // filesize + "QLCMfmt " + chunk-size + major-version + minor-version
avio_skip(pb, 8 + 4 + 1 + 1); // "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;

View File

@ -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;
} }

View File

@ -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,

View File

@ -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, "?localport=%d&ttl=%d&connect=%d", rtsp_st->sdp_port,
rtsp_st->sdp_ttl); 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 */

View File

@ -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 */

View File

@ -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,
}; };

View File

@ -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,
}; };

View File

@ -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->bit_rate != 0) {
ic->file_size != 0) { filesize = ic->pb ? avio_size(ic->pb) : 0;
filesize = ic->file_size;
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")) &&

View File

@ -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 */

View File

@ -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;