Commit fae714a9 authored by Michael Niedermayer's avatar Michael Niedermayer

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: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents 9be937d3 3ec34462
......@@ -347,6 +347,8 @@ typedef struct OptionsContext {
int nb_inter_matrices;
SpecifierOpt *top_field_first;
int nb_top_field_first;
SpecifierOpt *presets;
int nb_presets;
#if CONFIG_AVFILTER
SpecifierOpt *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)
{
OutputStream *ost;
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;
char *bsf = NULL, *next, *codec_tag = NULL;
AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
double qscale = -1;
char *buf = NULL, *arg = NULL, *preset = NULL;
AVIOContext *s = NULL;
if (!st) {
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);
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);
ost->max_frames = max_frames;
......@@ -4027,6 +4101,7 @@ static const OptionDef options[] = {
{ "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
{ "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" },
{ "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_metadata", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_metadata}, "set metadata information of outfile from infile",
"outfile[,metadata]:infile[,metadata]" },
......
......@@ -186,6 +186,8 @@ codec-dependent.
@var{filter_graph} is a description of the filter graph to apply to
the stream. Use @code{-filters} to show all the available filters
(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})
Print encoding progress/statistics. On by default.
......@@ -770,6 +772,21 @@ quality).
@chapter 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
If you specify the input format and device then avconv can grab video
......
......@@ -432,7 +432,7 @@ horizontal and vertical chroma subsample values. For example for the
pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
@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,
and of @code{min(cw,ch)/2} for the chroma planes.
......
......@@ -246,12 +246,15 @@ supporting it (currently Darwin Streaming Server and Mischa Spiegelmock's
The required syntax for a RTSP url is:
@example
rtsp://@var{hostname}[:@var{port}]/@var{path}[?@var{options}]
rtsp://@var{hostname}[:@var{port}]/@var{path}
@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:
Flags for @code{rtsp_transport}:
@table @option
@item udp
......@@ -261,21 +264,25 @@ Use UDP as lower transport protocol.
Use TCP (interleaving within the RTSP control channel) as lower
transport protocol.
@item multicast
@item udp_multicast
Use UDP multicast as lower transport protocol.
@item http
Use HTTP tunneling as lower transport protocol, which is useful for
passing proxies.
@item filter_src
Accept packets only from negotiated peer address and port.
@end table
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).
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
(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
......@@ -291,13 +298,13 @@ Example command lines:
To watch a stream over UDP, with a max reordering delay of 0.5 seconds:
@example
ffplay -max_delay 500000 rtsp://server/video.mp4?udp
ffplay -max_delay 500000 -rtsp_transport udp rtsp://server/video.mp4
@end example
To watch a stream tunneled over HTTP:
@example
ffplay rtsp://server/video.mp4?http
ffplay -rtsp_transport http rtsp://server/video.mp4
@end example
To send a stream in realtime to a RTSP server, for others to watch:
......
......@@ -355,6 +355,8 @@ typedef struct OptionsContext {
int nb_inter_matrices;
SpecifierOpt *top_field_first;
int nb_top_field_first;
SpecifierOpt *presets;
int nb_presets;
#if CONFIG_AVFILTER
SpecifierOpt *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)
{
OutputStream *ost;
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;
char *bsf = NULL, *next, *codec_tag = NULL;
AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
double qscale = -1;
char *buf = NULL, *arg = NULL, *preset = NULL;
AVIOContext *s = NULL;
if (!st) {
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);
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);
ost->max_frames = max_frames;
......@@ -4209,6 +4283,7 @@ static const OptionDef options[] = {
{ "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
{ "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" },
{ "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_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]" },
......
......@@ -30,7 +30,7 @@
#define LIBAVFILTER_VERSION_MAJOR 2
#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, \
LIBAVFILTER_VERSION_MINOR, \
......
......@@ -81,7 +81,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
if (!args) {
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);
}
......@@ -342,4 +342,4 @@ AVFilter avfilter_vf_boxblur = {
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO, },
{ .name = NULL}},
};
};
\ No newline at end of file
......@@ -154,9 +154,9 @@ static const char *delogo_get_name(void *ctx)
}
static const AVClass delogo_class = {
"DelogoContext",
delogo_get_name,
delogo_options
.class_name = "DelogoContext",
.item_name = delogo_get_name,
.option = delogo_options,
};
static int query_formats(AVFilterContext *ctx)
......@@ -285,4 +285,4 @@ AVFilter avfilter_vf_delogo = {
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO, },
{ .name = NULL}},
};
};
\ No newline at end of file
......@@ -350,21 +350,27 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{ .name = NULL}}, \
}
#if CONFIG_LUT_FILTER
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);
#endif
#if CONFIG_LUTRGB_FILTER
DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video.", init);
#endif
#if CONFIG_NEGATE_FILTER
static int negate_init(AVFilterContext *ctx, const char *args, void *opaque)
{
LutContext *lut = ctx->priv;
char lut_params[1024];
char lut_params[64];
if (args)
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",
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);
#endif
#endif
\ No newline at end of file
......@@ -275,9 +275,6 @@ static int aiff_read_header(AVFormatContext *s,
got_sound:
/* 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);
st->start_time = 0;
st->duration = st->codec->frame_size ?
......
......@@ -745,10 +745,12 @@ typedef struct AVFormatContext {
*/
int64_t duration;
#if FF_API_FILESIZE
/**
* 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
......@@ -763,7 +765,12 @@ typedef struct AVFormatContext {
/* av_seek_frame() support */
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;
int preload;
int max_delay;
......
......@@ -778,13 +778,14 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
{
int i;
if (buflen <= 0)
return AVERROR(EINVAL);
// reserve 1 byte for terminating 0
buflen = FFMIN(buflen - 1, maxlen);
for (i = 0; i < buflen; i++)
if (!(buf[i] = avio_r8(s)))
return i + 1;
if (buflen)
buf[i] = 0;
buf[i] = 0;
for (; i < maxlen; i++)
if (!avio_r8(s))
return i + 1;
......@@ -796,6 +797,8 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
{\
char* q = buf;\
int ret = 0;\
if (buflen <= 0) \
return AVERROR(EINVAL); \
while (ret + 1 < maxlen) {\
uint8_t tmp;\
uint32_t ch;\
......
......@@ -292,8 +292,6 @@ static int read_header(AVFormatContext *s,
"block size or frame size are variable.\n");
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);
st->start_time = 0;
......
......@@ -99,6 +99,33 @@ static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
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] = {
0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
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;
case MKTAG( 'd','i','s','k'): key = "disc";
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) {
......
......@@ -20,7 +20,9 @@
*/
#include "libavutil/fifo.h"
#include "libavutil/log.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavcodec/put_bits.h"
#include "avformat.h"
#include "mpeg.h"
......@@ -56,6 +58,7 @@ typedef struct {
} StreamInfo;
typedef struct {
const AVClass *class;
int packet_size; /* required packet size */
int packet_number;
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;
}
#if FF_API_MUXRATE
if(ctx->mux_rate){
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
headers. XXX: compute it exactly */
bitrate += bitrate*5/100;
......@@ -1227,7 +1233,23 @@ static int mpeg_mux_end(AVFormatContext *ctx)
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
MPEGENC_CLASS(mpeg)
AVOutputFormat ff_mpeg1system_muxer = {
.name = "mpeg",
.long_name = NULL_IF_CONFIG_SMALL("MPEG-1 System format"),
......@@ -1239,9 +1261,11 @@ AVOutputFormat ff_mpeg1system_muxer = {
.write_header = mpeg_mux_init,
.write_packet = mpeg_mux_write_packet,
.write_trailer = mpeg_mux_end,
.priv_class = &mpeg_class,
};
#endif
#if CONFIG_MPEG1VCD_MUXER
MPEGENC_CLASS(vcd)
AVOutputFormat ff_mpeg1vcd_muxer = {
.name = "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_packet = mpeg_mux_write_packet,
.write_trailer = mpeg_mux_end,
.priv_class = &vcd_class,
};
#endif
#if CONFIG_MPEG2VOB_MUXER
MPEGENC_CLASS(vob)
AVOutputFormat ff_mpeg2vob_muxer = {
.name = "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_packet = mpeg_mux_write_packet,
.write_trailer = mpeg_mux_end,
.priv_class = &vob_class,
};
#endif
/* Same as mpeg2vob_mux except that the pack size is 2324 */
#if CONFIG_MPEG2SVCD_MUXER
MPEGENC_CLASS(svcd)
AVOutputFormat ff_mpeg2svcd_muxer = {
.name = "svcd",
.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_packet = mpeg_mux_write_packet,
.write_trailer = mpeg_mux_end,
.priv_class = &svcd_class,
};
#endif
/* Same as mpeg2vob_mux except the 'is_dvd' flag is set to produce NAV pkts */
#if CONFIG_MPEG2DVD_MUXER
MPEGENC_CLASS(dvd)
AVOutputFormat ff_mpeg2dvd_muxer = {
.name = "dvd",
.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_packet = mpeg_mux_write_packet,
.write_trailer = mpeg_mux_end,
.priv_class = &dvd_class,
};
#endif
......@@ -92,6 +92,7 @@ static const AVOption options[] = {
{"mpegts_m2ts_mode", "Enable m2ts mode.",
offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_INT, {.dbl = -1 },
-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 },
};
......@@ -562,7 +563,10 @@ static int mpegts_write_header(AVFormatContext *s)
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) {
service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) /
......
......@@ -74,7 +74,9 @@ static const AVClass *format_child_class_next(const AVClass *prev)
static const AVOption options[]={
{"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},
#endif
{"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"},
{"ignidx", "ignore index", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_IGNIDX }, INT_MIN, INT_MAX, D, "fflags"},
......
......@@ -92,8 +92,7 @@ static int qcp_read_header(AVFormatContext *s, AVFormatParameters *ap)
return AVERROR(ENOMEM);
avio_rb32(pb); // "RIFF"
s->file_size = avio_rl32(pb) + 8;
avio_skip(pb, 8 + 4 + 1 + 1); // "QLCMfmt " + chunk-size + major-version + minor-version
avio_skip(pb, 4 + 8 + 4 + 1 + 1); // filesize + "QLCMfmt " + chunk-size + major-version + minor-version
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->channels = 1;
......
......@@ -98,7 +98,8 @@ int ff_rtp_get_payload_type(AVFormatContext *fmt, AVCodecContext *codec)
/* Was the payload type already specified for the RTP muxer? */
if (ofmt && ofmt->priv_class) {
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;
}
......
......@@ -465,7 +465,7 @@ AVOutputFormat ff_rtp_muxer = {
.long_name = NULL_IF_CONFIG_SMALL("RTP output format"),
.priv_data_size = sizeof(RTPMuxContext),
.audio_codec = CODEC_ID_PCM_MULAW,
.video_codec = CODEC_ID_NONE,
.video_codec = CODEC_ID_MPEG4,
.write_header = rtp_write_header,
.write_packet = rtp_write_packet,
.write_trailer = rtp_write_trailer,
......
......@@ -45,6 +45,7 @@
#include "rtpdec_formats.h"
#include "rtpenc_chain.h"
#include "url.h"
#include "rtpenc.h"
//#define DEBUG
......@@ -56,6 +57,36 @@
#define SDP_MAX_SIZE 16384
#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,
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: {
char url[1024], options[30] = "";
if (rt->filter_source)
if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)
av_strlcpy(options, "?connect=1", sizeof(options));
/* Use source address if specified */
if (reply->transports[0].source[0]) {
......@@ -1308,8 +1339,17 @@ int ff_rtsp_connect(AVFormatContext *s)
if (!ff_network_init())
return AVERROR(EIO);
redirect:
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 */
av_url_split(NULL, 0, auth, sizeof(auth),
host, sizeof(host), &port, path, sizeof(path), s->filename);
......@@ -1319,6 +1359,7 @@ redirect:
if (port < 0)
port = RTSP_DEFAULT_PORT;
#if FF_API_RTSP_URL_OPTIONS
/* search for options */
option_list = strrchr(path, '?');
if (option_list) {
......@@ -1326,6 +1367,7 @@ redirect:
* the options back into the same string. */
filename = option_list;
while (option_list) {
int handled = 1;
/* move the option pointer */
option = ++option_list;
option_list = strchr(option_list, '&');
......@@ -1343,7 +1385,7 @@ redirect:
lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_TCP);
rt->control_transport = RTSP_MODE_TUNNEL;
} else if (!strcmp(option, "filter_src")) {
rt->filter_source = 1;
rt->rtsp_flags |= RTSP_FLAG_FILTER_SRC;
} else {
/* Write options back into the buffer, using memmove instead
* of strcpy since the strings may overlap. */
......@@ -1351,10 +1393,16 @@ redirect:
memmove(++filename, option, len);
filename += len;
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;
}
#endif
if (!lower_transport_mask)
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);
ff_url_join(url, sizeof(url), "rtp", NULL,
namebuf, rtsp_st->sdp_port,
"?localport=%d&ttl=%d", rtsp_st->sdp_port,
rtsp_st->sdp_ttl);
"?localport=%d&ttl=%d&connect=%d", rtsp_st->sdp_port,
rtsp_st->sdp_ttl,
rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0);
if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE) < 0) {
err = AVERROR_INVALIDDATA;
goto fail;
......@@ -1820,6 +1869,13 @@ static int sdp_read_close(AVFormatContext *s)
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 = {
.name = "sdp",
.long_name = NULL_IF_CONFIG_SMALL("SDP"),
......@@ -1828,6 +1884,7 @@ AVInputFormat ff_sdp_demuxer = {
.read_header = sdp_read_header,
.read_packet = ff_rtsp_fetch_packet,
.read_close = sdp_read_close,
.priv_class = &sdp_demuxer_class
};
#endif /* CONFIG_SDP_DEMUXER */
......@@ -1924,6 +1981,13 @@ fail:
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 = {
.name = "rtp",
.long_name = NULL_IF_CONFIG_SMALL("RTP input format"),
......@@ -1933,6 +1997,7 @@ AVInputFormat ff_rtp_demuxer = {
.read_packet = ff_rtsp_fetch_packet,
.read_close = sdp_read_close,
.flags = AVFMT_NOFILE,
.priv_class = &rtp_demuxer_class
};
#endif /* CONFIG_RTP_DEMUXER */
......@@ -29,6 +29,7 @@
#include "httpauth.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
/**
* 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_TCP = 1, /**< TCP; interleaved in RTSP */
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 */
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
*/
......@@ -349,8 +349,17 @@ typedef struct RTSPState {
/** Whether the server accepts the x-Dynamic-Rate header */
int accept_dynamic_rate;
/**
* Various option flags for the RTSP muxer/demuxer.
*/
int rtsp_flags;
} 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
* 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);
extern const AVOption ff_rtsp_options[];
#endif /* AVFORMAT_RTSP_H */
......@@ -22,7 +22,6 @@
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "avformat.h"
#include "internal.h"
......@@ -388,15 +387,10 @@ static int rtsp_read_close(AVFormatContext *s)
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 = {
.class_name = "RTSP demuxer",
.item_name = av_default_item_name,
.option = options,
.option = ff_rtsp_options,
.version = LIBAVUTIL_VERSION_INT,
};
......
......@@ -33,20 +33,13 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
#include "url.h"
#include "libavutil/opt.h"
#include "rtpenc.h"
#define SDP_MAX_SIZE 16384
static const AVOption options[] = {
FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags),
{ NULL },
};
static const AVClass rtsp_muxer_class = {
.class_name = "RTSP muxer",
.item_name = av_default_item_name,
.option = options,
.option = ff_rtsp_options,
.version = LIBAVUTIL_VERSION_INT,
};
......
......@@ -1902,7 +1902,7 @@ static int has_duration(AVFormatContext *ic)
static void update_stream_timings(AVFormatContext *ic)
{
int64_t start_time, start_time1, start_time_text, end_time, end_time1;
int64_t duration, duration1;
int64_t duration, duration1, filesize;
int i;
AVStream *st;
......@@ -1945,9 +1945,9 @@ static void update_stream_timings(AVFormatContext *ic)
if (duration != INT64_MIN && ic->duration == AV_NOPTS_VALUE) {
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 */
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;
}
}
......@@ -1988,9 +1988,8 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic)
/* if duration is already set, we believe it */
if (ic->duration == AV_NOPTS_VALUE &&
ic->bit_rate != 0 &&
ic->file_size != 0) {
filesize = ic->file_size;
ic->bit_rate != 0) {
filesize = ic->pb ? avio_size(ic->pb) : 0;
if (filesize > 0) {
for(i = 0; i < ic->nb_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) */
/* XXX: may need to support wrapping */
filesize = ic->file_size;
filesize = ic->pb ? avio_size(ic->pb) : 0;
end_time = AV_NOPTS_VALUE;
do{
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)
file_size = 0;
}
ic->file_size = file_size;
if ((!strcmp(ic->iformat->name, "mpeg") ||
!strcmp(ic->iformat->name, "mpegts")) &&
......
......@@ -25,7 +25,7 @@
#define LIBAVFORMAT_VERSION_MAJOR 53
#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, \
LIBAVFORMAT_VERSION_MINOR, \
......@@ -89,5 +89,14 @@
#ifndef FF_API_TIMESTAMP
#define FF_API_TIMESTAMP (LIBAVFORMAT_VERSION_MAJOR < 54)
#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 */
......@@ -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)
{
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;
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)
return 0;
while (*opts) {
if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
return ret;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment