[Libav-user] FFmpeg RTP payload 96 instead of 97
Yu Ang Tan
yuang86 at gmail.com
Tue Nov 1 02:02:37 EET 2016
On Sun, Oct 30, 2016 at 11:06 PM NITIN GOYAL <nitinkumgoyal at gmail.com>
wrote:
> As its a dynamic payload profile, you have to assign it somewhere..
> ffplay won't be able to decode the sdp untill its specifically defined
> about the profile type...
>
> On Sunday, October 30, 2016, Yu Ang Tan <yuang86 at gmail.com> wrote:
>
> On Sun, 30 Oct 2016 18:33 NITIN GOYAL <nitinkumgoyal at gmail.com> wrote:
>
> RTP payload 96,97 are dynamic payloads and can be assigned as needed. RFC
> 2833
>
> in general when we have both video and audio, Video goes for 96 while
> audio goes for 97.
>
>
>
>
> On Wed, Oct 26, 2016 at 7:08 AM, Yu Ang Tan <yuang86 at gmail.com> wrote:
>
> On Thu, Sep 22, 2016 at 11:46 AM Yu Ang Tan <yuang86 at gmail.com> wrote:
>
> 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;
> }
>
>
>
> Interestingly, the same code when compiled in Linux Ubuntu gives the
> following:
>
> Output #0, rtp, to 'rtp://127.0.0.1:8554':
> Stream #0:0: Unknown: none (pcm_s16be)
> 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.48.100
> m=application 8554 RTP/AVP 3
>
> I noticed that the Output stream is now labeled as "Unknown". And in the
> SDP dump, the media name is switched from audio to application. RTP/AVP is
> now 3 instead of 96/97. What's going on?
>
> Would really appreciate it if any of you could shine some light on this.
>
>
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
>
>
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
>
>
> Fair enough. But how do I assign the payload ID? In Ubuntu, the RTP/AVP is
> 3 instead of 96/97 and using ffplay didn't work. Should I be manually
> specifying the SDP file, differently from the SDP dump?
> Thanks,
> Ang
>
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
Hi Nitin,
I tried using the following:
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 97
b=AS:256
a=rtpmap:97 L16/8000/1
and it worked.
I cannot help but feel that `av_sdp_create` has led me on a wild goose
chase by giving me an SDP file that does not work.
Thanks once again for helping me with this.
Ang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20161101/c9a118fb/attachment.html>
More information about the Libav-user
mailing list