diff --git a/configure b/configure index 645010b81f..2a3eaa1e94 100755 --- a/configure +++ b/configure @@ -1673,7 +1673,7 @@ avconv_deps="avcodec avformat swscale" ffplay_deps="avcodec avformat swscale sdl" ffplay_select="buffersink_filter rdft" ffprobe_deps="avcodec avformat" -ffserver_deps="avformat ffm_muxer fork rtp_protocol rtsp_demuxer" +ffserver_deps="avformat ffm_muxer fork rtp_protocol rtsp_demuxer !shared" ffserver_extralibs='$ldl' ffmpeg_deps="avcodec avformat swscale swresample" ffmpeg_select="buffersink_filter" diff --git a/ffserver.c b/ffserver.c index c225a94e3b..79463c0e64 100644 --- a/ffserver.c +++ b/ffserver.c @@ -30,13 +30,16 @@ #include #include #include "libavformat/avformat.h" +// FIXME those are internal headers, avserver _really_ shouldn't use them #include "libavformat/ffm.h" #include "libavformat/network.h" #include "libavformat/os_support.h" #include "libavformat/rtpdec.h" #include "libavformat/rtsp.h" -// XXX for ffio_open_dyn_packet_buffer, to be removed #include "libavformat/avio_internal.h" +#include "libavformat/internal.h" +#include "libavformat/url.h" + #include "libavutil/avstring.h" #include "libavutil/lfg.h" #include "libavutil/dict.h" @@ -874,7 +877,7 @@ static void close_connection(HTTPContext *c) } h = c->rtp_handles[i]; if (h) - url_close(h); + ffurl_close(h); } ctx = &c->fmt_ctx; @@ -2255,7 +2258,6 @@ static int http_prepare_data(HTTPContext *c) * Default value from FFmpeg * Try to set it use configuration option */ - c->fmt_ctx.preload = (int)(0.5*AV_TIME_BASE); c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE); if (avformat_write_header(&c->fmt_ctx, NULL) < 0) { @@ -2374,7 +2376,7 @@ static int http_prepare_data(HTTPContext *c) if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) max_packet_size = RTSP_TCP_MAX_PACKET_SIZE; else - max_packet_size = url_get_max_packet_size(c->rtp_handles[c->packet_stream_index]); + max_packet_size = c->rtp_handles[c->packet_stream_index]->max_packet_size; ret = ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size); } else { ret = avio_open_dyn_buf(&ctx->pb); @@ -2527,8 +2529,8 @@ static int http_send_data(HTTPContext *c) } else { /* send RTP packet directly in UDP */ c->buffer_ptr += 4; - url_write(c->rtp_handles[c->packet_stream_index], - c->buffer_ptr, len); + ffurl_write(c->rtp_handles[c->packet_stream_index], + c->buffer_ptr, len); c->buffer_ptr += len; /* here we continue as we can send several packets per 10 ms slot */ } @@ -3411,10 +3413,10 @@ static int rtp_new_av_stream(HTTPContext *c, "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port)); } - if (url_open(&h, ctx->filename, AVIO_FLAG_WRITE) < 0) + if (ffurl_open(&h, ctx->filename, AVIO_FLAG_WRITE, NULL, NULL) < 0) goto fail; c->rtp_handles[stream_index] = h; - max_packet_size = url_get_max_packet_size(h); + max_packet_size = h->max_packet_size; break; case RTSP_LOWER_TRANSPORT_TCP: /* RTP/TCP case */ @@ -3437,7 +3439,7 @@ static int rtp_new_av_stream(HTTPContext *c, if (avformat_write_header(ctx, NULL) < 0) { fail: if (h) - url_close(h); + ffurl_close(h); av_free(ctx); return -1; } @@ -3474,7 +3476,7 @@ static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int cop } fst->priv_data = av_mallocz(sizeof(FeedData)); fst->index = stream->nb_streams; - av_set_pts_info(fst, 33, 1, 90000); + avpriv_set_pts_info(fst, 33, 1, 90000); fst->sample_aspect_ratio = codec->sample_aspect_ratio; stream->streams[stream->nb_streams++] = fst; return fst; diff --git a/libavcodec/pnm.c b/libavcodec/pnm.c index 67df8c23d6..103408cad6 100644 --- a/libavcodec/pnm.c +++ b/libavcodec/pnm.c @@ -94,7 +94,7 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) pnm_get(s, buf1, sizeof(buf1)); maxval = strtol(buf1, NULL, 10); } else if (!strcmp(buf1, "TUPLTYPE") || - // FFmpeg used to write invalid files + /* libavcodec used to write invalid files */ !strcmp(buf1, "TUPLETYPE")) { pnm_get(s, tuple_type, sizeof(tuple_type)); } else if (!strcmp(buf1, "ENDHDR")) { diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index e5574e2d18..036ea94bcd 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -80,7 +80,7 @@ typedef struct { int index_sid; int body_sid; int64_t this_partition; - int64_t essence_offset; /* absolute offset of essence */ + int64_t essence_offset; ///< absolute offset of essence int64_t essence_length; int32_t kag_size; int64_t header_byte_count; @@ -407,7 +407,7 @@ static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, U static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) { MXFContext *mxf = arg; - MXFPartition *partition; + MXFPartition *partition, *tmp_part; UID op; uint64_t footer_partition; uint32_t nb_essence_containers; @@ -415,9 +415,10 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size if (mxf->partitions_count+1 >= UINT_MAX / sizeof(*mxf->partitions)) return AVERROR(ENOMEM); - mxf->partitions = av_realloc(mxf->partitions, (mxf->partitions_count + 1) * sizeof(*mxf->partitions)); - if (!mxf->partitions) + tmp_part = av_realloc(mxf->partitions, (mxf->partitions_count + 1) * sizeof(*mxf->partitions)); + if (!tmp_part) return AVERROR(ENOMEM); + mxf->partitions = tmp_part; if (mxf->parsing_backward) { /* insert the new partition pack in the middle @@ -531,11 +532,13 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set) { + MXFMetadataSet **tmp; if (mxf->metadata_sets_count+1 >= UINT_MAX / sizeof(*mxf->metadata_sets)) return AVERROR(ENOMEM); - mxf->metadata_sets = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets)); - if (!mxf->metadata_sets) + tmp = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets)); + if (!tmp) return AVERROR(ENOMEM); + mxf->metadata_sets = tmp; mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set; mxf->metadata_sets_count++; return 0; @@ -888,6 +891,7 @@ static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segment if (!(unsorted_segments = av_calloc(nb_segments, sizeof(*unsorted_segments))) || !(*sorted_segments = av_calloc(nb_segments, sizeof(**sorted_segments)))) { + av_freep(sorted_segments); av_free(unsorted_segments); return AVERROR(ENOMEM); } @@ -1303,7 +1307,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) { av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n"); - ret = -1; + ret = AVERROR_INVALIDDATA; goto fail_and_free; } @@ -1971,8 +1975,9 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti if (sample_time < 0) sample_time = 0; seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den); - if (avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET) < 0) - return -1; + + if ((ret = avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET)) < 0) + return ret; ff_update_cur_dts(s, st, sample_time); } else { t = &mxf->index_tables[0]; @@ -1994,7 +1999,7 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti if ((ret = mxf_edit_unit_absolute_offset(mxf, t, sample_time, &sample_time, &seekpos, 1)) << 0) return ret; - av_update_cur_dts(s, st, sample_time); + ff_update_cur_dts(s, st, sample_time); mxf->current_edit_unit = sample_time; avio_seek(s->pb, seekpos, SEEK_SET); } diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 56e5de27f8..c2a0d26e5e 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -81,6 +81,8 @@ const AVOption ff_rtsp_options[] = { { "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"), RTSP_MEDIATYPE_OPTS("allowed_media_types", "Media types to accept from the server"), + { "min_port", "Minimum local UDP port", OFFSET(rtp_port_min), AV_OPT_TYPE_INT, {RTSP_RTP_PORT_MIN}, 0, 65535, DEC|ENC }, + { "max_port", "Maximum local UDP port", OFFSET(rtp_port_max), AV_OPT_TYPE_INT, {RTSP_RTP_PORT_MAX}, 0, 65535, DEC|ENC }, { NULL }, }; @@ -1117,14 +1119,14 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, /* default timeout: 1 minute */ rt->timeout = 60; - /* for each stream, make the setup request */ - /* XXX: we assume the same server is used for the control of each - * RTSP stream */ - port_off = av_get_random_seed() % (RTSP_RTP_PORT_MAX - RTSP_RTP_PORT_MIN); + /* Choose a random starting offset within the first half of the + * port range, to allow for a number of ports to try even if the offset + * happens to be at the end of the random range. */ + port_off = av_get_random_seed() % ((rt->rtp_port_max - rt->rtp_port_min)/2); /* even random offset */ port_off -= port_off & 0x01; - for (j = RTSP_RTP_PORT_MIN + port_off, i = 0; i < rt->nb_rtsp_streams; ++i) { + for (j = rt->rtp_port_min + port_off, i = 0; i < rt->nb_rtsp_streams; ++i) { char transport[2048]; /* @@ -1161,7 +1163,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, } /* first try in specified port range */ - while (j <= RTSP_RTP_PORT_MAX) { + while (j <= rt->rtp_port_max) { ff_url_join(buf, sizeof(buf), "rtp", NULL, host, -1, "?localport=%d", j); /* we will use two ports per rtp stream (rtp and rtcp) */ @@ -1358,6 +1360,13 @@ int ff_rtsp_connect(AVFormatContext *s) struct sockaddr_storage peer; socklen_t peer_len = sizeof(peer); + if (rt->rtp_port_max < rt->rtp_port_min) { + av_log(s, AV_LOG_ERROR, "Invalid UDP port range, max port %d less " + "than min port %d\n", rt->rtp_port_max, + rt->rtp_port_min); + return AVERROR(EINVAL); + } + if (!ff_network_init()) return AVERROR(EIO); diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h index dd96a41ba7..f67ceb89ca 100644 --- a/libavformat/rtsp.h +++ b/libavformat/rtsp.h @@ -359,6 +359,11 @@ typedef struct RTSPState { * Mask of all requested media types */ int media_type_mask; + + /** + * Minimum and maximum local UDP ports. + */ + int rtp_port_min, rtp_port_max; } RTSPState; #define RTSP_FLAG_FILTER_SRC 0x1 /**< Filter incoming UDP packets -