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_HEVC:

            if (c->extradata_size)

                av_log(NULL, AV_LOG_WARNING, "HEVC extradata not currently "

                                             "passed properly through SDP\n");

            av_strlcatf(buff, size, "a=rtpmap:%d H265/90000\r\n", payload_type);

            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->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) {

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

            break;

        case AV_CODEC_ID_OPUS:

            /* The opus RTP draft says that all opus streams MUST be declared

               as stereo, to avoid negotiation failures. The actual number of

               channels can change on a packet-by-packet basis. The number of

               channels a receiver prefers to receive or a sender plans to send

               can be declared via fmtp parameters (both default to mono), but

               receivers MUST be able to receive and process stereo packets. */

            av_strlcatf(buff, size, "a=rtpmap:%d opus/48000/2\r\n",

                                     payload_type);

            if (c->channels == 2) {

                av_strlcatf(buff, size, "a=fmtp:%d sprop-stereo:1\r\n",

                                         payload_type);

            }

            break;

        default:

            /* Nothing special to do here... */

            break;

    }



    av_free(config);



    return buff;

}
