diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-11-15 11:31:13 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-11-15 11:31:13 +0100 |
commit | a9b1536a018b867e3458a278c2992f7cd2fb707d (patch) | |
tree | 55556d53044f7e8854f59c9eb7fcab76f3ea19d1 | |
parent | 4d941eac1655b21af33c6e4d52b7bfd7f9e5b990 (diff) | |
parent | b74dbdd5e99aed7f3bf1ecb5da1b374e5ba35768 (diff) | |
download | ffmpeg-streaming-a9b1536a018b867e3458a278c2992f7cd2fb707d.zip ffmpeg-streaming-a9b1536a018b867e3458a278c2992f7cd2fb707d.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
bgmc: Fix av_malloc checks in ff_bgmc_init()
rtp: set the payload type as stream id
Conflicts:
libavformat/rtpenc_chain.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavformat/avformat.h | 3 | ||||
-rw-r--r-- | libavformat/internal.h | 5 | ||||
-rw-r--r-- | libavformat/movenc.c | 11 | ||||
-rw-r--r-- | libavformat/movenchint.c | 2 | ||||
-rw-r--r-- | libavformat/rtp.c | 8 | ||||
-rw-r--r-- | libavformat/rtp.h | 9 | ||||
-rw-r--r-- | libavformat/rtpenc.c | 13 | ||||
-rw-r--r-- | libavformat/rtpenc_chain.c | 14 | ||||
-rw-r--r-- | libavformat/rtpenc_chain.h | 3 | ||||
-rw-r--r-- | libavformat/rtsp.c | 3 | ||||
-rw-r--r-- | libavformat/sapenc.c | 2 | ||||
-rw-r--r-- | libavformat/sdp.c | 21 |
12 files changed, 68 insertions, 26 deletions
diff --git a/libavformat/avformat.h b/libavformat/avformat.h index dd9df4e..8f18604 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1970,6 +1970,9 @@ int av_filename_number_test(const char *filename); /** * Generate an SDP for an RTP session. * + * Note, this overwrites the id values of AVStreams in the muxer contexts + * for getting unique dynamic payload types. + * * @param ac array of AVFormatContexts describing the RTP streams. If the * array is composed by only one context, such context can contain * multiple AVStreams (one AVStream per RTP stream). Otherwise, diff --git a/libavformat/internal.h b/libavformat/internal.h index 2689b2f..16a2c96 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -123,7 +123,8 @@ int ff_url_join(char *str, int size, const char *proto, * * @param buff the buffer to append the SDP fragment to * @param size the size of the buff buffer - * @param c the AVCodecContext of the media to describe + * @param st the AVStream of the media to describe + * @param idx the global stream index * @param dest_addr the destination address of the media stream, may be NULL * @param dest_type the destination address type, may be NULL * @param port the destination port of the media stream, 0 if unknown @@ -131,7 +132,7 @@ int ff_url_join(char *str, int size, const char *proto, * @param fmt the AVFormatContext, which might contain options modifying * the generated SDP */ -void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, +void ff_sdp_write_media(char *buff, int size, AVStream *st, int idx, const char *dest_addr, const char *dest_type, int port, int ttl, AVFormatContext *fmt); diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 3f54009..f8ad73b 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1767,13 +1767,16 @@ static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov) return 0x34; } -static int mov_write_udta_sdp(AVIOContext *pb, AVFormatContext *ctx, int index) +static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track) { + + AVFormatContext *ctx = track->rtp_ctx; char buf[1000] = ""; int len; - ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0]->codec, NULL, NULL, 0, 0, ctx); - av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", index); + ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], track->src_track, + NULL, NULL, 0, 0, ctx); + av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id); len = strlen(buf); avio_wb32(pb, len + 24); @@ -1801,7 +1804,7 @@ static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov, if (track->mode == MODE_PSP) mov_write_uuid_tag_psp(pb,track); // PSP Movies require this uuid box if (track->tag == MKTAG('r','t','p',' ')) - mov_write_udta_sdp(pb, track->rtp_ctx, track->track_id); + mov_write_udta_sdp(pb, track); if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && track->mode == MODE_MOV) { double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio); if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c index 9c4ddeb..cc90f0b 100644 --- a/libavformat/movenchint.c +++ b/libavformat/movenchint.c @@ -44,7 +44,7 @@ int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index) track->enc->codec_tag = track->tag; ret = ff_rtp_chain_mux_open(&track->rtp_ctx, s, src_st, NULL, - RTP_MAX_PACKET_SIZE); + RTP_MAX_PACKET_SIZE, src_index); if (ret < 0) goto fail; diff --git a/libavformat/rtp.c b/libavformat/rtp.c index f9e4447..ae0fd58 100644 --- a/libavformat/rtp.c +++ b/libavformat/rtp.c @@ -90,7 +90,8 @@ int ff_rtp_get_codec_info(AVCodecContext *codec, int payload_type) return -1; } -int ff_rtp_get_payload_type(AVFormatContext *fmt, AVCodecContext *codec) +int ff_rtp_get_payload_type(AVFormatContext *fmt, + AVCodecContext *codec, int idx) { int i; AVOutputFormat *ofmt = fmt ? fmt->oformat : NULL; @@ -124,8 +125,11 @@ int ff_rtp_get_payload_type(AVFormatContext *fmt, AVCodecContext *codec) return AVRtpPayloadTypes[i].pt; } + if (idx < 0) + idx = codec->codec_type == AVMEDIA_TYPE_AUDIO; + /* dynamic payload type */ - return RTP_PT_PRIVATE + (codec->codec_type == AVMEDIA_TYPE_AUDIO); + return RTP_PT_PRIVATE + idx; } const char *ff_rtp_enc_name(int payload_type) diff --git a/libavformat/rtp.h b/libavformat/rtp.h index ab2de52..1732af8 100644 --- a/libavformat/rtp.h +++ b/libavformat/rtp.h @@ -25,13 +25,18 @@ #include "libavcodec/avcodec.h" /** - * Return the payload type for a given codec used in the given format context. + * Return the payload type for a given stream used in the given format context. + * Static payload types are derived from the codec. + * Dynamic payload type are derived from the id field in AVStream. + * The format context private option payload_type overrides both. * * @param fmt The context of the format * @param codec The context of the codec + * @param idx The stream index * @return The payload type (the 'PT' field in the RTP header). */ -int ff_rtp_get_payload_type(AVFormatContext *fmt, AVCodecContext *codec); +int ff_rtp_get_payload_type(AVFormatContext *fmt, AVCodecContext *codec, + int idx); /** * Initialize a codec context based on the payload type. diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 3a5bbeb..0010a92 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -101,8 +101,17 @@ static int rtp_write_header(AVFormatContext *s1) return -1; } - if (s->payload_type < 0) - s->payload_type = ff_rtp_get_payload_type(s1, st->codec); + if (s->payload_type < 0) { + /* Re-validate non-dynamic payload types */ + if (st->id < RTP_PT_PRIVATE) + st->id = ff_rtp_get_payload_type(s1, st->codec, -1); + + s->payload_type = st->id; + } else { + /* private option takes priority */ + st->id = s->payload_type; + } + s->base_timestamp = av_get_random_seed(); s->timestamp = s->base_timestamp; s->cur_timestamp = 0; diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c index c0f9530..25b0b8b 100644 --- a/libavformat/rtpenc_chain.c +++ b/libavformat/rtpenc_chain.c @@ -23,13 +23,15 @@ #include "avio_internal.h" #include "rtpenc_chain.h" #include "avio_internal.h" +#include "rtp.h" #include "libavutil/opt.h" int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s, - AVStream *st, URLContext *handle, int packet_size) + AVStream *st, URLContext *handle, int packet_size, + int idx) { AVFormatContext *rtpctx = NULL; - int ret; + int ret, pt; AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); uint8_t *rtpflags; AVDictionary *opts = NULL; @@ -59,6 +61,14 @@ int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s, rtpctx->streams[0]->sample_aspect_ratio = st->sample_aspect_ratio; rtpctx->flags |= s->flags & AVFMT_FLAG_MP4A_LATM; + /* Get the payload type from the codec */ + if (st->id < RTP_PT_PRIVATE) + rtpctx->streams[0]->id = + ff_rtp_get_payload_type(rtpctx, st->codec, idx); + else + rtpctx->streams[0]->id = st->id; + + if (av_opt_get(s, "rtpflags", AV_OPT_SEARCH_CHILDREN, &rtpflags) >= 0) av_dict_set(&opts, "rtpflags", rtpflags, AV_DICT_DONT_STRDUP_VAL); diff --git a/libavformat/rtpenc_chain.h b/libavformat/rtpenc_chain.h index 1ba3617..21c27c1 100644 --- a/libavformat/rtpenc_chain.h +++ b/libavformat/rtpenc_chain.h @@ -26,6 +26,7 @@ #include "url.h" int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s, - AVStream *st, URLContext *handle, int packet_size); + AVStream *st, URLContext *handle, int packet_size, + int id); #endif /* AVFORMAT_RTPENC_CHAIN_H */ diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 201938c..04ea47c 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -631,7 +631,8 @@ int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) if (s->oformat && CONFIG_RTSP_MUXER) { int ret = ff_rtp_chain_mux_open((AVFormatContext **)&rtsp_st->transport_priv, s, st, rtsp_st->rtp_handle, - RTSP_TCP_MAX_PACKET_SIZE); + RTSP_TCP_MAX_PACKET_SIZE, + rtsp_st->stream_index); /* Ownership of rtp_handle is passed to the rtp mux context */ rtsp_st->rtp_handle = NULL; if (ret < 0) diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c index 3de615d..7abfd50 100644 --- a/libavformat/sapenc.c +++ b/libavformat/sapenc.c @@ -151,7 +151,7 @@ static int sap_write_header(AVFormatContext *s) ret = AVERROR(EIO); goto fail; } - ret = ff_rtp_chain_mux_open(&contexts[i], s, s->streams[i], fd, 0); + ret = ff_rtp_chain_mux_open(&contexts[i], s, s->streams[i], fd, 0, i); if (ret < 0) goto fail; s->streams[i]->priv_data = contexts[i]; diff --git a/libavformat/sdp.c b/libavformat/sdp.c index c4edd78..cdc3e21 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -604,12 +604,15 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, return buff; } -void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, int port, int ttl, AVFormatContext *fmt) +void ff_sdp_write_media(char *buff, int size, AVStream *st, int idx, + const char *dest_addr, const char *dest_type, + int port, int ttl, AVFormatContext *fmt) { + AVCodecContext *c = st->codec; const char *type; int payload_type; - payload_type = ff_rtp_get_payload_type(fmt, c); + payload_type = ff_rtp_get_payload_type(fmt, c, idx); switch (c->codec_type) { case AVMEDIA_TYPE_VIDEO : type = "video" ; break; @@ -631,7 +634,7 @@ int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size) { AVDictionaryEntry *title = av_dict_get(ac[0]->metadata, "title", NULL, 0); struct sdp_session_level s = { 0 }; - int i, j, port, ttl, is_multicast; + int i, j, port, ttl, is_multicast, index = 0; char dst[32], dst_type[5]; memset(buf, 0, size); @@ -670,10 +673,10 @@ int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size) ttl = 0; } for (j = 0; j < ac[i]->nb_streams; j++) { - ff_sdp_write_media(buf, size, - ac[i]->streams[j]->codec, dst[0] ? dst : NULL, - dst_type, (port > 0) ? port + j * 2 : 0, ttl, - ac[i]); + ff_sdp_write_media(buf, size, ac[i]->streams[j], index++, + dst[0] ? dst : NULL, dst_type, + (port > 0) ? port + j * 2 : 0, + ttl, ac[i]); if (port <= 0) { av_strlcatf(buf, size, "a=control:streamid=%d\r\n", i + j); @@ -689,7 +692,9 @@ int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size) return AVERROR(ENOSYS); } -void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, int port, int ttl, AVFormatContext *fmt) +void ff_sdp_write_media(char *buff, int size, AVStream *st, int idx, + const char *dest_addr, const char *dest_type, + int port, int ttl, AVFormatContext *fmt) { } #endif |