/*
 * copyright (c) 2007 Luca Abeni
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg 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,
 * 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
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <string.h>
#include "libavutil/avstring.h"
#include "libavutil/base64.h"
#include "libavutil/dict.h"
#include "libavutil/parseutils.h"
#include "libavutil/opt.h"
#include "libavcodec/xiph.h"
#include "libavcodec/mpeg4audio.h"
#include "avformat.h"
#include "internal.h"
#include "avc.h"
#include "rtp.h"
#if CONFIG_NETWORK
#include "network.h"
#endif

#if CONFIG_RTP_MUXER
#define MAX_EXTRADATA_SIZE ((INT_MAX - 10) / 2)

struct sdp_session_level {
    int sdp_version;      /**< protocol version (currently 0) */
    int id;               /**< session ID */
    int version;          /**< session version */
    int start_time;       /**< session start time (NTP time, in seconds),
                               or 0 in case of permanent session */
    int end_time;         /**< session end time (NTP time, in seconds),
                               or 0 if the session is not bounded */
    int ttl;              /**< TTL, in case of multicast stream */
    const char *user;     /**< username of the session's creator */
    const char *src_addr; /**< IP address of the machine from which the session was created */
    const char *src_type; /**< address type of src_addr */
    const char *dst_addr; /**< destination IP address (can be multicast) */
    const char *dst_type; /**< destination IP address type */
    const char *name;     /**< session name (can be an empty string) */
};

static void sdp_write_address(char *buff, int size, const char *dest_addr,
                              const char *dest_type, int ttl)
{
    if (dest_addr) {
        if (!dest_type)
            dest_type = "IP4";
        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);
        }
    }
}

static void sdp_write_header(char *buff, int size, struct sdp_session_level *s)
{
    av_strlcatf(buff, size, "v=%d\r\n"
                            "o=- %d %d IN %s %s\r\n"
                            "s=%s\r\n",
                            s->sdp_version,
                            s->id, s->version, s->src_type, s->src_addr,
                            s->name);
    sdp_write_address(buff, size, s->dst_addr, s->dst_type, s->ttl);
    av_strlcatf(buff, size, "t=%d %d\r\n"
                            "a=tool:libavformat " AV_STRINGIFY(LIBAVFORMAT_VERSION) "\r\n",
                            s->start_time, s->end_time);
}

#if CONFIG_NETWORK
static int resolve_destination(char *dest_addr, int size, char *type,
                               int type_size)
{
    struct addrinfo hints = { 0 }, *ai;
    int is_multicast;

    av_strlcpy(type, "IP4", type_size);
    if (!dest_addr[0])
        return 0;

    /* Resolve the destination, since it must be written
     * as a numeric IP address in the SDP. */

    if (getaddrinfo(dest_addr, NULL, &hints, &ai))
        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 int resolve_destination(char *dest_addr, int size, char *type,
                               int type_size)
{
    return 0;
}
#endif

static int sdp_get_address(char *dest_addr, int size, int *ttl, const char *url)
{
    int port;
    const char *p;
    char proto[32];

    av_url_split(proto, sizeof(proto), NULL, 0, dest_addr, size, &port, NULL, 0, url);

    *ttl = 0;

    if (strcmp(proto, "rtp") && strcmp(proto, "srtp")) {
        /* The url isn't for the actual rtp sessions,
         * don't parse out anything else than the destination.
         */
        return 0;
    }

    p = strchr(url, '?');
    if (p) {
        char buff[64];

        if (av_find_info_tag(buff, sizeof(buff), "ttl", p)) {
            *ttl = strtol(buff, NULL, 10);
        } else {
            *ttl = 5;
        }
    }

    return port;
}

#define MAX_PSET_SIZE 1024
static char *extradata2psets(AVCodecContext *c)
{
    char *psets, *p;
    const uint8_t *r;
    static const char pset_string[] = "; sprop-parameter-sets=";
    static const char profile_string[] = "; profile-level-id=";
    uint8_t *orig_extradata = NULL;
    int orig_extradata_size = 0;
    const uint8_t *sps = NULL, *sps_end;

    if (c->extradata_size > MAX_EXTRADATA_SIZE) {
        av_log(c, AV_LOG_ERROR, "Too much extradata!\n");

        return NULL;
    }
    if (c->extradata[0] == 1) {
        uint8_t *dummy_p;
        int dummy_int;
        AVBitStreamFilterContext *bsfc= av_bitstream_filter_init("h264_mp4toannexb");

        if (!bsfc) {
            av_log(c, AV_LOG_ERROR, "Cannot open the h264_mp4toannexb BSF!\n");

            return NULL;
        }

        orig_extradata_size = c->extradata_size;
        orig_extradata = av_mallocz(orig_extradata_size +
                                    FF_INPUT_BUFFER_PADDING_SIZE);
        if (!orig_extradata) {
            av_bitstream_filter_close(bsfc);
            return NULL;
        }
        memcpy(orig_extradata, c->extradata, orig_extradata_size);
        av_bitstream_filter_filter(bsfc, c, NULL, &dummy_p, &dummy_int, NULL, 0, 0);
        av_bitstream_filter_close(bsfc);
    }

    psets = av_mallocz(MAX_PSET_SIZE);
    if (psets == NULL) {
        av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the parameter sets.\n");
        av_free(orig_extradata);
        return NULL;
    }
    memcpy(psets, pset_string, strlen(pset_string));
    p = psets + strlen(pset_string);
    r = ff_avc_find_startcode(c->extradata, c->extradata + c->extradata_size);
    while (r < c->extradata + c->extradata_size) {
        const uint8_t *r1;
        uint8_t nal_type;

        while (!*(r++));
        nal_type = *r & 0x1f;
        r1 = ff_avc_find_startcode(r, c->extradata + c->extradata_size);
        if (nal_type != 7 && nal_type != 8) { /* Only output SPS and PPS */
            r = r1;
            continue;
        }
        if (p != (psets + strlen(pset_string))) {
            *p = ',';
            p++;
        }
        if (!sps) {
            sps = r;
            sps_end = r1;
        }
        if (av_base64_encode(p, MAX_PSET_SIZE - (p - psets), r, r1 - r) == NULL) {
            av_log(c, AV_LOG_ERROR, "Cannot Base64-encode %td %td!\n", MAX_PSET_SIZE - (p - psets), r1 - r);
            av_free(psets);

            return NULL;
        }
        p += strlen(p);
        r = r1;
    }
    if (sps && sps_end - sps >= 4) {
        memcpy(p, profile_string, strlen(profile_string));
        p += strlen(p);
        ff_data_to_hex(p, sps + 1, 3, 0);
        p[6] = '\0';
    }
    if (orig_extradata) {
        av_free(c->extradata);
        c->extradata      = orig_extradata;
        c->extradata_size = orig_extradata_size;
    }

    return psets;
}

static char *extradata2config(AVCodecContext *c)
{
    char *config;

    if (c->extradata_size > MAX_EXTRADATA_SIZE) {
        av_log(c, AV_LOG_ERROR, "Too much extradata!\n");

        return NULL;
    }
    config = av_malloc(10 + c->extradata_size * 2);
    if (config == NULL) {
        av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the config info.\n");
        return NULL;
    }
    memcpy(config, "; config=", 9);
    ff_data_to_hex(config + 9, c->extradata, c->extradata_size, 0);
    config[9 + c->extradata_size * 2] = 0;

    return config;
}

static char *xiph_extradata2config(AVCodecContext *c)
{
    char *config, *encoded_config;
    uint8_t *header_start[3];
    int headers_len, header_len[3], config_len;
    int first_header_size;

    switch (c->codec_id) {
    case AV_CODEC_ID_THEORA:
        first_header_size = 42;
        break;
    case AV_CODEC_ID_VORBIS:
        first_header_size = 30;
        break;
    default:
        av_log(c, AV_LOG_ERROR, "Unsupported Xiph codec ID\n");
        return NULL;
    }

    if (avpriv_split_xiph_headers(c->extradata, c->extradata_size,
                              first_header_size, header_start,
                              header_len) < 0) {
        av_log(c, AV_LOG_ERROR, "Extradata corrupt.\n");
        return NULL;
    }

    headers_len = header_len[0] + header_len[2];
    config_len = 4 +          // count
                 3 +          // ident
                 2 +          // packet size
                 1 +          // header count
                 2 +          // header size
                 headers_len; // and the rest

    config = av_malloc(config_len);
    if (!config)
        goto xiph_fail;

    encoded_config = av_malloc(AV_BASE64_SIZE(config_len));
    if (!encoded_config) {
        av_free(config);
        goto xiph_fail;
    }

    config[0] = config[1] = config[2] = 0;
    config[3] = 1;
    config[4] = (RTP_XIPH_IDENT >> 16) & 0xff;
    config[5] = (RTP_XIPH_IDENT >>  8) & 0xff;
    config[6] = (RTP_XIPH_IDENT      ) & 0xff;
    config[7] = (headers_len >> 8) & 0xff;
    config[8] = headers_len & 0xff;
    config[9] = 2;
    config[10] = header_len[0];
    config[11] = 0; // size of comment header; nonexistent
    memcpy(config + 12, header_start[0], header_len[0]);
    memcpy(config + 12 + header_len[0], header_start[2], header_len[2]);

    av_base64_encode(encoded_config, AV_BASE64_SIZE(config_len),
                     config, config_len);
    av_free(config);

    return encoded_config;

xiph_fail:
    av_log(c, AV_LOG_ERROR,
           "Not enough memory for configuration string\n");
    return NULL;
}

static int latm_context2profilelevel(AVCodecContext *c)
{
    /* MP4A-LATM
     * The RTP payload format specification is described in RFC 3016
     * The encoding specifications are provided in ISO/IEC 14496-3 */

    int profile_level = 0x2B;

    /* TODO: AAC Profile only supports AAC LC Object Type.
     * Different Object Types should implement different Profile Levels */

    if (c->sample_rate <= 24000) {
        if (c->channels <= 2)
            profile_level = 0x28; // AAC Profile, Level 1
    } else if (c->sample_rate <= 48000) {
        if (c->channels <= 2) {
            profile_level = 0x29; // AAC Profile, Level 2
        } else if (c->channels <= 5) {
            profile_level = 0x2A; // AAC Profile, Level 4
        }
    } else if (c->sample_rate <= 96000) {
        if (c->channels <= 5) {
            profile_level = 0x2B; // AAC Profile, Level 5
        }
    }

    return profile_level;
}

static char *latm_context2config(AVCodecContext *c)
{
    /* MP4A-LATM
     * The RTP payload format specification is described in RFC 3016
     * The encoding specifications are provided in ISO/IEC 14496-3 */

    uint8_t config_byte[6];
    int rate_index;
    char *config;

    for (rate_index = 0; rate_index < 16; rate_index++)
        if (avpriv_mpeg4audio_sample_rates[rate_index] == c->sample_rate)
            break;
    if (rate_index == 16) {
        av_log(c, AV_LOG_ERROR, "Unsupported sample rate\n");
        return NULL;
    }

    config_byte[0] = 0x40;
    config_byte[1] = 0;
    config_byte[2] = 0x20 | rate_index;
    config_byte[3] = c->channels << 4;
    config_byte[4] = 0x3f;
    config_byte[5] = 0xc0;

    config = av_malloc(6*2+1);
    if (!config) {
        av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the config info.\n");
        return NULL;
    }
    ff_data_to_hex(config, config_byte, 6, 1);
    config[12] = 0;

    return config;
}

static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type, AVFormatContext *fmt)
{
    char *config = NULL;

    switch (c->codec_id) {
        case AV_CODEC_ID_H264: {
            int mode = 1;
            if (fmt && fmt->oformat && fmt->oformat->priv_class &&
                av_opt_flag_is_set(fmt->priv_data, "rtpflags", "h264_mode0"))
                mode = 0;
            if (c->extradata_size) {
                config = extradata2psets(c);
            }
            av_strlcatf(buff, size, "a=rtpmap:%d H264/90000\r\n"
                                    "a=fmtp:%d packetization-mode=%d%s\r\n",
                                     payload_type,
                                     payload_type, mode, config ? config : "");
            break;
        }
        case AV_CODEC_ID_H263:
        case AV_CODEC_ID_H263P:
            /* 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. */
            if (!fmt || !fmt->oformat->priv_class ||
                !av_opt_flag_is_set(fmt->priv_data, "rtpflags", "rfc2190") ||
                c->codec_id == AV_CODEC_ID_H263P)
            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 AV_CODEC_ID_MPEG4:
            if (c->extradata_size) {
                config = extradata2config(c);
            }
            av_strlcatf(buff, size, "a=rtpmap:%d MP4V-ES/90000\r\n"
                                    "a=fmtp:%d profile-level-id=1%s\r\n",
                                     payload_type,
                                     payload_type, config ? config : "");
            break;
        case AV_CODEC_ID_AAC:
            if (fmt && fmt->oformat && fmt->oformat->priv_class &&
                av_opt_flag_is_set(fmt->priv_data, "rtpflags", "latm")) {
                config = latm_context2config(c);
                if (!config)
                    return NULL;
                av_strlcatf(buff, size, "a=rtpmap:%d MP4A-LATM/%d/%d\r\n"
                                        "a=fmtp:%d profile-level-id=%d;cpresent=0;config=%s\r\n",
                                         payload_type, c->sample_rate, c->channels,
                                         payload_type, latm_context2profilelevel(c), config);
            } else {
                if (c->extradata_size) {
                    config = extradata2config(c);
                } else {
                    /* FIXME: maybe we can forge config information based on the
                     *        codec parameters...
                     */
                    av_log(c, AV_LOG_ERROR, "AAC with no global headers is currently not supported.\n");
                    return NULL;
                }
                if (config == NULL) {
                    return NULL;
                }
                av_strlcatf(buff, size, "a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n"
                                        "a=fmtp:%d profile-level-id=1;"
                                        "mode=AAC-hbr;sizelength=13;indexlength=3;"
                                        "indexdeltalength=3%s\r\n",
                                         payload_type, c->sample_rate, c->channels,
                                         payload_type, config);
            }
            break;
        case AV_CODEC_ID_PCM_S16BE:
            if (payload_type >= RTP_PT_PRIVATE)
                av_strlcatf(buff, size, "a=rtpmap:%d L16/%d/%d\r\n",
                                         payload_type,
                                         c->sample_rate, c->channels);
            break;
        case AV_CODEC_ID_PCM_MULAW:
            if (payload_type >= RTP_PT_PRIVATE)
                av_strlcatf(buff, size, "a=rtpmap:%d PCMU/%d/%d\r\n",
                                         payload_type,
                                         c->sample_rate, c->channels);
            break;
        case AV_CODEC_ID_PCM_ALAW:
            if (payload_type >= RTP_PT_PRIVATE)
                av_strlcatf(buff, size, "a=rtpmap:%d PCMA/%d/%d\r\n",
                                         payload_type,
                                         c->sample_rate, c->channels);
            break;
        case AV_CODEC_ID_AMR_NB:
            av_strlcatf(buff, size, "a=rtpmap:%d AMR/%d/%d\r\n"
                                    "a=fmtp:%d octet-align=1\r\n",
                                     payload_type, c->sample_rate, c->channels,
                                     payload_type);
            break;
        case AV_CODEC_ID_AMR_WB:
            av_strlcatf(buff, size, "a=rtpmap:%d AMR-WB/%d/%d\r\n"
                                    "a=fmtp:%d octet-align=1\r\n",
                                     payload_type, c->sample_rate, c->channels,
                                     payload_type);
            break;
        case AV_CODEC_ID_VORBIS:
            if (c->extradata_size)
                config = xiph_extradata2config(c);
            else
                av_log(c, AV_LOG_ERROR, "Vorbis configuration info missing\n");
            if (!config)
                return NULL;

            av_strlcatf(buff, size, "a=rtpmap:%d vorbis/%d/%d\r\n"
                                    "a=fmtp:%d configuration=%s\r\n",
                                    payload_type, c->sample_rate, c->channels,
                                    payload_type, config);
            break;
        case AV_CODEC_ID_THEORA: {
            const char *pix_fmt;
            switch (c->pix_fmt) {
            case AV_PIX_FMT_YUV420P:
                pix_fmt = "YCbCr-4:2:0";
                break;
            case AV_PIX_FMT_YUV422P:
                pix_fmt = "YCbCr-4:2:2";
                break;
            case AV_PIX_FMT_YUV444P:
                pix_fmt = "YCbCr-4:4:4";
                break;
            default:
                av_log(c, AV_LOG_ERROR, "Unsupported pixel format.\n");
                return NULL;
            }

            if (c->extradata_size)
                config = xiph_extradata2config(c);
            else
                av_log(c, AV_LOG_ERROR, "Theora configuation info missing\n");
            if (!config)
                return NULL;

            av_strlcatf(buff, size, "a=rtpmap:%d theora/90000\r\n"
                                    "a=fmtp:%d delivery-method=inline; "
                                    "width=%d; height=%d; sampling=%s; "
                                    "configuration=%s\r\n",
                                    payload_type, payload_type,
                                    c->width, c->height, pix_fmt, config);
            break;
        }
        case AV_CODEC_ID_VP8:
            av_strlcatf(buff, size, "a=rtpmap:%d VP8/90000\r\n",
                                     payload_type);
            break;
        case AV_CODEC_ID_MJPEG:
            if (payload_type >= RTP_PT_PRIVATE)
                av_strlcatf(buff, size, "a=rtpmap:%d JPEG/90000\r\n",
                                         payload_type);
            break;
        case AV_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;
        case AV_CODEC_ID_ADPCM_G726: {
            if (payload_type >= RTP_PT_PRIVATE)
                av_strlcatf(buff, size, "a=rtpmap:%d G726-%d/%d\r\n",
                                         payload_type,
                                         c->bits_per_coded_sample*8,
                                         c->sample_rate);
            break;
        }
        case AV_CODEC_ID_ILBC:
            av_strlcatf(buff, size, "a=rtpmap:%d iLBC/%d\r\n"
                                    "a=fmtp:%d mode=%d\r\n",
                                     payload_type, c->sample_rate,
                                     payload_type, c->block_align == 38 ? 20 : 30);
            break;
        case AV_CODEC_ID_SPEEX:
            av_strlcatf(buff, size, "a=rtpmap:%d speex/%d\r\n",
                                     payload_type, c->sample_rate);
            if (c->codec) {
                const char *mode;
                uint64_t vad_option;

                if (c->flags & CODEC_FLAG_QSCALE)
                      mode = "on";
                else if (!av_opt_get_int(c, "vad", AV_OPT_FLAG_ENCODING_PARAM, &vad_option) && vad_option)
                      mode = "vad";
                else
                      mode = "off";

                av_strlcatf(buff, size, "a=fmtp:%d vbr=%s\r\n",
                                        payload_type, mode);
            }
            break;
        case AV_CODEC_ID_OPUS:
            av_strlcatf(buff, size, "a=rtpmap:%d opus/48000\r\n",
                                     payload_type);
            break;
        default:
            /* Nothing special to do here... */
            break;
    }

    av_free(config);

    return buff;
}

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, idx);

    switch (c->codec_type) {
        case AVMEDIA_TYPE_VIDEO   : type = "video"      ; break;
        case AVMEDIA_TYPE_AUDIO   : type = "audio"      ; break;
        case AVMEDIA_TYPE_SUBTITLE: type = "text"       ; break;
        default                 : type = "application"; break;
    }

    av_strlcatf(buff, size, "m=%s %d RTP/AVP %d\r\n", type, port, payload_type);
    sdp_write_address(buff, size, dest_addr, dest_type, ttl);
    if (c->bit_rate) {
        av_strlcatf(buff, size, "b=AS:%d\r\n", c->bit_rate / 1000);
    }

    sdp_write_media_attributes(buff, size, c, payload_type, fmt);
}

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, index = 0;
    char dst[32], dst_type[5];

    memset(buf, 0, size);
    s.user = "-";
    s.src_addr = "127.0.0.1";    /* FIXME: Properly set this */
    s.src_type = "IP4";
    s.name = title ? title->value : "No Name";

    port = 0;
    ttl = 0;
    if (n_files == 1) {
        port = sdp_get_address(dst, sizeof(dst), &ttl, ac[0]->filename);
        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;
            s.ttl = ttl;
            if (!strcmp(dst_type, "IP6")) {
                s.src_addr = "::1";
                s.src_type = "IP6";
            }
        }
    }
    sdp_write_header(buf, size, &s);

    dst[0] = 0;
    for (i = 0; i < n_files; i++) {
        if (n_files != 1) {
            port = sdp_get_address(dst, sizeof(dst), &ttl, ac[i]->filename);
            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(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);
            }
            if (ac[i]->pb && ac[i]->pb->av_class) {
                uint8_t *crypto_suite = NULL, *crypto_params = NULL;
                av_opt_get(ac[i]->pb, "srtp_out_suite",  AV_OPT_SEARCH_CHILDREN,
                           &crypto_suite);
                av_opt_get(ac[i]->pb, "srtp_out_params", AV_OPT_SEARCH_CHILDREN,
                           &crypto_params);
                if (crypto_suite && crypto_suite[0])
                    av_strlcatf(buf, size,
                                "a=crypto:1 %s inline:%s\r\n",
                                crypto_suite, crypto_params);
                av_free(crypto_suite);
                av_free(crypto_params);
            }
        }
    }

    return 0;
}
#else
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, AVStream *st, int idx,
                        const char *dest_addr, const char *dest_type,
                        int port, int ttl, AVFormatContext *fmt)
{
}
#endif
