]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/sdp.c
movenc: remove uses of deprecated API.
[ffmpeg] / libavformat / sdp.c
index 7ba90aec1ce43153667ca59c60c4629560c7c622..2a8821815a2d462e8ed3b157025774ea7d0c1844 100644 (file)
@@ -21,6 +21,7 @@
 #include <string.h>
 #include "libavutil/avstring.h"
 #include "libavutil/base64.h"
+#include "libavutil/parseutils.h"
 #include "libavcodec/xiph.h"
 #include "avformat.h"
 #include "internal.h"
@@ -56,7 +57,9 @@ static void sdp_write_address(char *buff, int size, const char *dest_addr,
     if (dest_addr) {
         if (!dest_type)
             dest_type = "IP4";
-        if (ttl > 0) {
+        if (ttl > 0 && !strcmp(dest_type, "IP4")) {
+            /* The TTL should only be specified for IPv4 multicast addresses,
+             * not for IPv6. */
             av_strlcatf(buff, size, "c=IN %s %s/%d\r\n", dest_type, dest_addr, ttl);
         } else {
             av_strlcatf(buff, size, "c=IN %s %s\r\n", dest_type, dest_addr);
@@ -79,33 +82,37 @@ static void sdp_write_header(char *buff, int size, struct sdp_session_level *s)
 }
 
 #if CONFIG_NETWORK
-static void resolve_destination(char *dest_addr, int size, char *type,
-                                int type_size)
+static int resolve_destination(char *dest_addr, int size, char *type,
+                               int type_size)
 {
-    struct addrinfo hints, *ai, *cur;
+    struct addrinfo hints, *ai;
+    int is_multicast;
 
     av_strlcpy(type, "IP4", type_size);
     if (!dest_addr[0])
-        return;
+        return 0;
 
     /* Resolve the destination, since it must be written
      * as a numeric IP address in the SDP. */
 
     memset(&hints, 0, sizeof(hints));
     if (getaddrinfo(dest_addr, NULL, &hints, &ai))
-        return;
-    for (cur = ai; cur; cur = cur->ai_next) {
-            getnameinfo(cur->ai_addr, cur->ai_addrlen, dest_addr, size,
-                        NULL, 0, NI_NUMERICHOST);
-            if (cur->ai_family == AF_INET6)
-                av_strlcpy(type, "IP6", type_size);
-            break;
-    }
+        return 0;
+    getnameinfo(ai->ai_addr, ai->ai_addrlen, dest_addr, size,
+                NULL, 0, NI_NUMERICHOST);
+#ifdef AF_INET6
+    if (ai->ai_family == AF_INET6)
+        av_strlcpy(type, "IP6", type_size);
+#endif
+    is_multicast = ff_is_multicast_address(ai->ai_addr);
     freeaddrinfo(ai);
+    return is_multicast;
 }
 #else
-static void resolve_destination(char *dest_addr, int size)
+static int resolve_destination(char *dest_addr, int size, char *type,
+                               int type_size)
 {
+    return 0;
 }
 #endif
 
@@ -129,14 +136,11 @@ static int sdp_get_address(char *dest_addr, int size, int *ttl, const char *url)
     p = strchr(url, '?');
     if (p) {
         char buff[64];
-        int is_multicast = find_info_tag(buff, sizeof(buff), "multicast", p);
 
-        if (is_multicast) {
-            if (find_info_tag(buff, sizeof(buff), "ttl", p)) {
-                *ttl = strtol(buff, NULL, 10);
-            } else {
-                *ttl = 5;
-            }
+        if (av_find_info_tag(buff, sizeof(buff), "ttl", p)) {
+            *ttl = strtol(buff, NULL, 10);
+        } else {
+            *ttl = 5;
         }
     }
 
@@ -311,7 +315,14 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
             break;
         case CODEC_ID_H263:
         case CODEC_ID_H263P:
-            av_strlcatf(buff, size, "a=rtpmap:%d H263-2000/90000\r\n", payload_type);
+            /* a=framesize is required by 3GPP TS 26.234 (PSS). It
+             * actually specifies the maximum video size, but we only know
+             * the current size. This is required for playback on Android
+             * stagefright and on Samsung bada. */
+            av_strlcatf(buff, size, "a=rtpmap:%d H263-2000/90000\r\n"
+                                    "a=framesize:%d %d-%d\r\n",
+                                    payload_type,
+                                    payload_type, c->width, c->height);
             break;
         case CODEC_ID_MPEG4:
             if (c->extradata_size) {
@@ -421,6 +432,12 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
             av_strlcatf(buff, size, "a=rtpmap:%d VP8/90000\r\n",
                                      payload_type);
             break;
+        case CODEC_ID_ADPCM_G722:
+            if (payload_type >= RTP_PT_PRIVATE)
+                av_strlcatf(buff, size, "a=rtpmap:%d G722/%d/%d\r\n",
+                                         payload_type,
+                                         8000, c->channels);
+            break;
         default:
             /* Nothing special to do here... */
             break;
@@ -461,7 +478,7 @@ int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size)
 {
     AVMetadataTag *title = av_metadata_get(ac[0]->metadata, "title", NULL, 0);
     struct sdp_session_level s;
-    int i, j, port, ttl;
+    int i, j, port, ttl, is_multicast;
     char dst[32], dst_type[5];
 
     memset(buff, 0, size);
@@ -475,7 +492,10 @@ int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size)
     ttl = 0;
     if (n_files == 1) {
         port = sdp_get_address(dst, sizeof(dst), &ttl, ac[0]->filename);
-        resolve_destination(dst, sizeof(dst), dst_type, sizeof(dst_type));
+        is_multicast = resolve_destination(dst, sizeof(dst), dst_type,
+                                           sizeof(dst_type));
+        if (!is_multicast)
+            ttl = 0;
         if (dst[0]) {
             s.dst_addr = dst;
             s.dst_type = dst_type;
@@ -492,13 +512,15 @@ int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size)
     for (i = 0; i < n_files; i++) {
         if (n_files != 1) {
             port = sdp_get_address(dst, sizeof(dst), &ttl, ac[i]->filename);
-            resolve_destination(dst, sizeof(dst), dst_type, sizeof(dst_type));
+            is_multicast = resolve_destination(dst, sizeof(dst), dst_type,
+                                               sizeof(dst_type));
+            if (!is_multicast)
+                ttl = 0;
         }
         for (j = 0; j < ac[i]->nb_streams; j++) {
             ff_sdp_write_media(buff, size,
                                   ac[i]->streams[j]->codec, dst[0] ? dst : NULL,
-                                  dst_type,
-                                  (port > 0) ? port + j * 2 : 0, ttl);
+                                  dst_type, (port > 0) ? port + j * 2 : 0, ttl);
             if (port <= 0) {
                 av_strlcatf(buff, size,
                                    "a=control:streamid=%d\r\n", i + j);
@@ -514,8 +536,7 @@ int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size)
     return AVERROR(ENOSYS);
 }
 
-void ff_sdp_write_media(char *buff, int size, AVCodecContext *c,
-                        const char *dest_addr, int port, int ttl)
+void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, int port, int ttl)
 {
 }
 #endif