[Libav-user] FFmpeg RTP payload 96 instead of 97

Yu Ang Tan yuang86 at gmail.com
Thu Sep 22 04:46:39 EEST 2016


I want to create an rtp audio stream with ffmpeg. When I run my application
I get the following SDP file configuration:

    Output #0, rtp, to 'rtp://127.0.0.1:8554':
        Stream #0:0: Audio: pcm_s16be, 8000 Hz, stereo, s16, 256 kb/s

    SDP:
    v=0
    o=- 0 0 IN IP4 127.0.0.1
    s=No Name
    c=IN IP4 127.0.0.1
    t=0 0
    a=tool:libavformat 57.25.101
    m=audio 8554 RTP/AVP 96
    b=AS:256
    a=rtpmap:96 L16/8000/2

However, when I try to read it with `ffplay -i test.sdp -protocol_whitelist
file,udp,rtp`, it fails,shows the following:

    ffplay version N-78598-g98a0053 Copyright (c) 2003-2016 the FFmpeg
developers
      built with gcc 5.3.0 (GCC)
      configuration: --disable-static --enable-shared --enable-gpl
--enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib
--enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv
--enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca
--enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm
--enable-libilbc --enable-libmodplug --enable-libmp3lame
--enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg
--enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr
--enable-libspeex --enable-libtheora --enable-libtwolame
--enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis
--enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264
--enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg
--enable-lzma --enable-decklink --enable-zlib
      libavutil      55. 18.100 / 55. 18.100
      libavcodec     57. 24.103 / 57. 24.103
      libavformat    57. 25.101 / 57. 25.101
      libavdevice    57.  0.101 / 57.  0.101
      libavfilter     6. 34.100 /  6. 34.100
      libswscale      4.  0.100 /  4.  0.100
      libswresample   2.  0.101 /  2.  0.101
      libpostproc    54.  0.100 / 54.  0.100
        nan    :  0.000 fd=   0 aq=    0KB vq=    0KB sq=    0B f=0/0
        (...waits indefinitely.)

The only way to make it work again is to modify the payload type in the SDP
file from 96 to 97. Can someone tell me why? Where and how is this number
defined?


Here is my source.

    #include <math.h>
    extern "C"
    {
    #include <libavutil/opt.h>
    #include <libavcodec/avcodec.h>
    #include <libavutil/channel_layout.h>
    #include <libavutil/common.h>
    #include <libavutil/imgutils.h>
    #include <libavutil/mathematics.h>
    #include <libavutil/samplefmt.h>
    #include <libavformat/avformat.h>
    }


    static int write_frame(AVFormatContext *fmt_ctx, const AVRational
*time_base, AVStream *st, AVPacket *pkt)
    {
        /* rescale output packet timestamp values from codec to stream
timebase */
        av_packet_rescale_ts(pkt, *time_base, st->time_base);

        /* Write the compressed frame to the media file. */
        return av_interleaved_write_frame(fmt_ctx, pkt);
    }

    /*
    * Audio encoding example
    */
    static void audio_encode_example(const char *filename)
    {
        AVPacket pkt;
        int i, j, k, ret, got_output;
        int buffer_size;

        uint16_t *samples;
        float t, tincr;

        AVCodec *outCodec = NULL;
        AVCodecContext *outCodecCtx = NULL;
        AVFormatContext *outFormatCtx = NULL;
        AVStream * outAudioStream = NULL;
        AVFrame *outFrame = NULL;

        ret = avformat_alloc_output_context2(&outFormatCtx, NULL, "rtp",
filename);
        if (!outFormatCtx || ret < 0)
        {
            fprintf(stderr, "Could not allocate output context");
        }

        outFormatCtx->flags |= AVFMT_FLAG_NOBUFFER |
AVFMT_FLAG_FLUSH_PACKETS;
        outFormatCtx->oformat->audio_codec = AV_CODEC_ID_PCM_S16BE;

        /* find the encoder */
        outCodec = avcodec_find_encoder(outFormatCtx->oformat->audio_codec);
        if (!outCodec) {
            fprintf(stderr, "Codec not found\n");
            exit(1);
        }

        outAudioStream = avformat_new_stream(outFormatCtx, outCodec);
        if (!outAudioStream)
        {
            fprintf(stderr, "Cannot add new audio stream\n");
            exit(1);
        }

        outAudioStream->id = outFormatCtx->nb_streams - 1;
        outCodecCtx = outAudioStream->codec;
        outCodecCtx->sample_fmt = AV_SAMPLE_FMT_S16;

        /* select other audio parameters supported by the encoder */
        outCodecCtx->sample_rate = 8000;
        outCodecCtx->channel_layout = AV_CH_LAYOUT_STEREO;
        outCodecCtx->channels = 2;

        /* open it */
        if (avcodec_open2(outCodecCtx, outCodec, NULL) < 0) {
            fprintf(stderr, "Could not open codec\n");
            exit(1);
        }

        // PCM has no frame, so we have to explicitly specify
        outCodecCtx->frame_size = 1152;

        av_dump_format(outFormatCtx, 0, filename, 1);

        char buff[10000] = { 0 };
        ret = av_sdp_create(&outFormatCtx, 1, buff, sizeof(buff));
        printf("%s", buff);

        ret = avio_open2(&outFormatCtx->pb, filename, AVIO_FLAG_WRITE,
NULL, NULL);
        ret = avformat_write_header(outFormatCtx, NULL);
        printf("ret = %d\n", ret);
        if (ret <0) {
            exit(1);
        }

        /* frame containing input audio */
        outFrame = av_frame_alloc();
        if (!outFrame) {
            fprintf(stderr, "Could not allocate audio frame\n");
            exit(1);
        }

        outFrame->nb_samples = outCodecCtx->frame_size;
        outFrame->format = outCodecCtx->sample_fmt;
        outFrame->channel_layout = outCodecCtx->channel_layout;

        /* we calculate the size of the samples buffer in bytes */
        buffer_size = av_samples_get_buffer_size(NULL,
outCodecCtx->channels, outCodecCtx->frame_size,
            outCodecCtx->sample_fmt, 0);
        if (buffer_size < 0) {
            fprintf(stderr, "Could not get sample buffer size\n");
            exit(1);
        }
        samples = (uint16_t*)av_malloc(buffer_size);
        if (!samples) {
            fprintf(stderr, "Could not allocate %d bytes for samples
buffer\n",
                buffer_size);
            exit(1);
        }
        /* setup the data pointers in the AVFrame */
        ret = avcodec_fill_audio_frame(outFrame, outCodecCtx->channels,
outCodecCtx->sample_fmt,
            (const uint8_t*)samples, buffer_size, 0);
        if (ret < 0) {
            fprintf(stderr, "Could not setup audio frame\n");
            exit(1);
        }

        /* encode a single tone sound */
        t = 0;
        int next_pts = 0;
        tincr = 2 * M_PI * 440.0 / outCodecCtx->sample_rate;
        for (i = 0; i < 400000; i++) {
            av_init_packet(&pkt);
            pkt.data = NULL; // packet data will be allocated by the encoder
            pkt.size = 0;

            for (j = 0; j < outCodecCtx->frame_size; j++) {
                samples[2 * j] = (uint16_t)(sin(t) * 10000);

                for (k = 1; k < outCodecCtx->channels; k++)
                    samples[2 * j + k] = samples[2 * j];
                t += tincr;
            }
            t = (t > 50000) ? 0 : t;

            // Sets time stamp
            next_pts += outFrame->nb_samples;
            outFrame->pts = next_pts;

            /* encode the samples */
            ret = avcodec_encode_audio2(outCodecCtx, &pkt, outFrame,
&got_output);
            if (ret < 0) {
                fprintf(stderr, "Error encoding audio frame\n");
                exit(1);
            }
            if (got_output) {
                write_frame(outFormatCtx, &outCodecCtx->time_base,
outAudioStream, &pkt);
                av_packet_unref(&pkt);
            }

            printf("i:%d\n", i); // waste some time to avoid over-filling
jitter buffer
            printf("Audio: %d\t%d\n", samples[0], samples[1]); // waste
some time to avoid over-filling jitter buffer
            printf("t: %f\n", t); // waste some time to avoid over-filling
jitter buffer
        }

        /* get the delayed frames */
        for (got_output = 1; got_output; i++) {
            ret = avcodec_encode_audio2(outCodecCtx, &pkt, NULL,
&got_output);
            if (ret < 0) {
                fprintf(stderr, "Error encoding frame\n");
                exit(1);
            }

            if (got_output) {
                pkt.pts = AV_NOPTS_VALUE;
                write_frame(outFormatCtx, &outCodecCtx->time_base,
outAudioStream, &pkt);
                av_packet_unref(&pkt);
            }
        }

        av_freep(&samples);
        av_frame_free(&outFrame);
        avcodec_close(outCodecCtx);
        av_free(outCodecCtx);
    }


    int main(int argc, char **argv)
    {
        const char *output;

        av_register_all();
        avformat_network_init(); // for network streaming

        audio_encode_example("rtp://127.0.0.1:8554");

        return 0;
    }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20160922/3241c384/attachment.html>


More information about the Libav-user mailing list