X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fsapenc.c;h=7e2bba7a286fa036593f8229f2ce62b450e0768a;hb=b845f5e97b655de0a191f736594777fec9754cf5;hp=088f7bda01c2c1cfd4adb28ccd14e61706677a2c;hpb=1f56f5ed6d68f6492e213944e145e04e4d4dca13;p=ffmpeg diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c index 088f7bda01c..7e2bba7a286 100644 --- a/libavformat/sapenc.c +++ b/libavformat/sapenc.c @@ -2,31 +2,35 @@ * Session Announcement Protocol (RFC 2974) muxer * Copyright (c) 2010 Martin Storsjo * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avformat.h" +#include "libavutil/parseutils.h" #include "libavutil/random_seed.h" #include "libavutil/avstring.h" +#include "libavutil/dict.h" #include "libavutil/intreadwrite.h" +#include "libavutil/time.h" #include "internal.h" #include "network.h" #include "os_support.h" #include "rtpenc_chain.h" +#include "url.h" struct SAPState { uint8_t *ann; @@ -45,23 +49,19 @@ static int sap_write_close(AVFormatContext *s) if (!rtpctx) continue; av_write_trailer(rtpctx); - url_fclose(rtpctx->pb); - av_metadata_free(&rtpctx->streams[0]->metadata); - av_metadata_free(&rtpctx->metadata); - av_free(rtpctx->streams[0]->info); - av_free(rtpctx->streams[0]); - av_free(rtpctx); + avio_close(rtpctx->pb); + avformat_free_context(rtpctx); s->streams[i]->priv_data = NULL; } if (sap->last_time && sap->ann && sap->ann_fd) { sap->ann[0] |= 4; /* Session deletion*/ - url_write(sap->ann_fd, sap->ann, sap->ann_size); + ffurl_write(sap->ann_fd, sap->ann, sap->ann_size); } av_freep(&sap->ann); if (sap->ann_fd) - url_close(sap->ann_fd); + ffurl_close(sap->ann_fd); ff_network_close(); return 0; } @@ -77,6 +77,7 @@ static int sap_write_header(AVFormatContext *s) struct sockaddr_storage localaddr; socklen_t addrlen = sizeof(localaddr); int udp_fd; + AVDictionaryEntry* title = av_dict_get(s->metadata, "title", NULL, 0); if (!ff_network_init()) return AVERROR(EIO); @@ -91,23 +92,22 @@ static int sap_write_header(AVFormatContext *s) option_list = strrchr(path, '?'); if (option_list) { char buf[50]; - if (find_info_tag(buf, sizeof(buf), "announce_port", option_list)) { + if (av_find_info_tag(buf, sizeof(buf), "announce_port", option_list)) { port = strtol(buf, NULL, 10); } - if (find_info_tag(buf, sizeof(buf), "same_port", option_list)) { + if (av_find_info_tag(buf, sizeof(buf), "same_port", option_list)) { same_port = strtol(buf, NULL, 10); } - if (find_info_tag(buf, sizeof(buf), "ttl", option_list)) { + if (av_find_info_tag(buf, sizeof(buf), "ttl", option_list)) { ttl = strtol(buf, NULL, 10); } - if (find_info_tag(buf, sizeof(buf), "announce_addr", option_list)) { + if (av_find_info_tag(buf, sizeof(buf), "announce_addr", option_list)) { av_strlcpy(announce_addr, buf, sizeof(announce_addr)); } } if (!announce_addr[0]) { - struct addrinfo hints, *ai = NULL; - memset(&hints, 0, sizeof(hints)); + struct addrinfo hints = { 0 }, *ai = NULL; hints.ai_family = AF_UNSPEC; if (getaddrinfo(host, NULL, &hints, &ai)) { av_log(s, AV_LOG_ERROR, "Unable to resolve %s\n", host); @@ -148,25 +148,31 @@ static int sap_write_header(AVFormatContext *s) "?ttl=%d", ttl); if (!same_port) base_port += 2; - ret = url_open(&fd, url, URL_WRONLY); + ret = ffurl_open(&fd, url, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL); if (ret) { ret = AVERROR(EIO); goto fail; } - s->streams[i]->priv_data = contexts[i] = - ff_rtp_chain_mux_open(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]; av_strlcpy(contexts[i]->filename, url, sizeof(contexts[i]->filename)); } + if (s->nb_streams > 0 && title) + av_dict_set(&contexts[0]->metadata, "title", title->value, 0); + ff_url_join(url, sizeof(url), "udp", NULL, announce_addr, port, "?ttl=%d&connect=1", ttl); - ret = url_open(&sap->ann_fd, url, URL_WRONLY); + ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL); if (ret) { ret = AVERROR(EIO); goto fail; } - udp_fd = url_get_file_handle(sap->ann_fd); + udp_fd = ffurl_get_file_handle(sap->ann_fd); if (getsockname(udp_fd, (struct sockaddr*) &localaddr, &addrlen)) { ret = AVERROR(EIO); goto fail; @@ -210,8 +216,8 @@ static int sap_write_header(AVFormatContext *s) av_strlcpy(&sap->ann[pos], "application/sdp", sap->ann_size - pos); pos += strlen(&sap->ann[pos]) + 1; - if (avf_sdp_create(contexts, s->nb_streams, &sap->ann[pos], - sap->ann_size - pos)) { + if (av_sdp_create(contexts, s->nb_streams, &sap->ann[pos], + sap->ann_size - pos)) { ret = AVERROR_INVALIDDATA; goto fail; } @@ -220,7 +226,7 @@ static int sap_write_header(AVFormatContext *s) pos += strlen(&sap->ann[pos]); sap->ann_size = pos; - if (sap->ann_size > url_get_max_packet_size(sap->ann_fd)) { + if (sap->ann_size > sap->ann_fd->max_packet_size) { av_log(s, AV_LOG_ERROR, "Announcement too large to send in one " "packet\n"); goto fail; @@ -241,9 +247,9 @@ static int sap_write_packet(AVFormatContext *s, AVPacket *pkt) int64_t now = av_gettime(); if (!sap->last_time || now - sap->last_time > 5000000) { - int ret = url_write(sap->ann_fd, sap->ann, sap->ann_size); + int ret = ffurl_write(sap->ann_fd, sap->ann, sap->ann_size); /* Don't abort even if we get "Destination unreachable" */ - if (ret < 0 && ret != FF_NETERROR(ECONNREFUSED)) + if (ret < 0 && ret != AVERROR(ECONNREFUSED)) return ret; sap->last_time = now; } @@ -252,16 +258,13 @@ static int sap_write_packet(AVFormatContext *s, AVPacket *pkt) } AVOutputFormat ff_sap_muxer = { - "sap", - NULL_IF_CONFIG_SMALL("SAP output format"), - NULL, - NULL, - sizeof(struct SAPState), - CODEC_ID_AAC, - CODEC_ID_MPEG4, - sap_write_header, - sap_write_packet, - sap_write_close, - .flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER, + .name = "sap", + .long_name = NULL_IF_CONFIG_SMALL("SAP output"), + .priv_data_size = sizeof(struct SAPState), + .audio_codec = AV_CODEC_ID_AAC, + .video_codec = AV_CODEC_ID_MPEG4, + .write_header = sap_write_header, + .write_packet = sap_write_packet, + .write_trailer = sap_write_close, + .flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER, }; -