I use the `av_sdp_create()` to generate my SDP file but I think somethings is wrong. Here is the output:
Output #0, rtp, to 'rtp://127.0.0.1:8554': Stream #0:0: Audio: vorbis (libvorbis), 44100 Hz, stereo, fltp, 64 kb/s 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:64 a=rtpmap:96 vorbis/44100/2 a=fmtp:96 configuration=AAAAAf7Nug7RAh4AAXZvcmJpcwAAAAACRKwAAP////8A+gAA/////7gBBXZvcmJpcyFCQ1YBAAABABhjVClGmVLSSokZc5QxRplikkqJpYQWQkidcxRTqTnXnGusubUghBAaU1ApBZlSjlJpGWOQKQWZUhBLSSV0EjonnWMQW0nB1phri0G2HIQNmlJMKcSUUopCCBlTjCnFlFJKQgcldA465hxTjkooQbicc6u1lpZji6l0kkrnJGRMQkgphZJKB6VTTkJINZbWUikdc1JSakHoIIQQQrYghA2C0JBVAAABAMBAEBqyCgBQAAAQiqEYigKEhqwCADIAAASgKI7iKI4jOZJjSRYQGrIKAAACABAAAMBwFEmRFMmxJEvSLEvTRFFVfdU2VVX2dV3XdV3XdSA0ZBUAAAEAQEinmaUaIMIMZBgIDVkFACAAAABGKMIQA0JDVgEAAAEAAGIoOYgmtOZ8c46DZjloKsXmdHAi1eZJbirm5pxzzjknm3PGOOecc4pyZjFoJrTmnHMSg2YpaCa05pxznsTmQWuqtOacc8Y5p4NxRhjnnHOatOZBajbW5pxzFrSmOWouxeaccyLl5kltLtXmnHPOOeecc84555xzqhenc3BOOOecc6L25lpuQhfnnHM+Gad7c0I455xzzjnnnHPOOeecc4LQkFUAABAAAEEYNoZxpyBIn6OBGEWIacikB92jwyRoDHIKqUejo5FS6iCUVMZJKZ0gNGQVAAAIAAAhhBRSSCGFFFJIIYUUUoghhhhiyCmnnIIKKqmkoooyyiyzzDLLLLPMMuuws8467DDEEEMMrbQSS0211VhjrbnnnG If I try to use the SDP file anyway, I get the following message: >ffplay -i test2.sdp -protocol_whitelist file,udp,rtp 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 [NULL @ 05aea880] Bad packed header lengths (30,0,616,3793) f=0/0 [vorbis @ 05aea880] Extradata missing. [sdp @ 05ad7ec0] Failed to open codec in av_find_stream_info nan : 0.000 fd= 0 aq= 0KB vq= 0KB sq= 0B f=0/0 Am I overlooking something important? Am I going about this the wrong way? Any help would be much appreciated. Here is my source: #include "stdafx.h" #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> } /* check that a given sample format is supported by the encoder */ static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt) { const enum AVSampleFormat *p = codec->sample_fmts; while (*p != AV_SAMPLE_FMT_NONE) { if (*p == sample_fmt) return 1; p++; } return 0; } /* just pick the highest supported samplerate */ static int select_sample_rate(AVCodec *codec) { const int *p; int best_samplerate = 0; if (!codec->supported_samplerates) return 44100; p = codec->supported_samplerates; while (*p) { best_samplerate = FFMAX(*p, best_samplerate); p++; } return best_samplerate; } /* select layout with the highest channel count */ static int select_channel_layout(AVCodec *codec) { const uint64_t *p; uint64_t best_ch_layout = 0; int best_nb_channels = 0; if (!codec->channel_layouts) return AV_CH_LAYOUT_STEREO; p = codec->channel_layouts; while (*p) { int nb_channels = av_get_channel_layout_nb_channels(*p); if (nb_channels > best_nb_channels) { best_ch_layout = *p; best_nb_channels = nb_channels; } p++; } return best_ch_layout; } 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->max_interleave_delta = 1; outFormatCtx->oformat->audio_codec = AV_CODEC_ID_VORBIS; /* 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; outAudioStream->time_base.den = 44100; // 44.100 kHz outAudioStream->time_base.num = 1; outCodecCtx = outAudioStream->codec; outCodecCtx->bit_rate = 64000; outCodecCtx->time_base.den = outAudioStream->time_base.den; outCodecCtx->time_base.num = outAudioStream->time_base.num; /* check that the encoder supports input */ outCodecCtx->sample_fmt = AV_SAMPLE_FMT_FLTP; if (!check_sample_fmt(outCodec, outCodecCtx->sample_fmt)) { fprintf(stderr, "Encoder does not support sample format %s", av_get_sample_fmt_name(outCodecCtx->sample_fmt)); exit(1); } /* select other audio parameters supported by the encoder */ outCodecCtx->sample_rate = select_sample_rate(outCodec); outCodecCtx->channel_layout = select_channel_layout(outCodec); outCodecCtx->channels = av_get_channel_layout_nb_channels(outCodecCtx->channel_layout); /* open it */ if (avcodec_open2(outCodecCtx, outCodec, NULL) < 0) { fprintf(stderr, "Could not open codec\n"); exit(1); } av_dump_format(outFormatCtx, 0, filename, 1); char buff[2048] = { 0 }; av_sdp_create(&outFormatCtx, 1, buff, 1024); printf("%s", buff); (...SDP printed here...) 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; /* the codec gives us the frame size, in samples, * 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 < 44000; 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] = (int)(sin(t) * 10000); for (k = 1; k < outCodecCtx->channels; k++) samples[2 * j + k] = samples[2 * j]; t += tincr; } // 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) { //fwrite(pkt.data, 1, pkt.size, f); //pkt.stream_index = pktidx++; write_frame(outFormatCtx, &outCodecCtx->time_base, outAudioStream, &pkt); av_packet_unref(&pkt); } } /* 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) { //fwrite(pkt.data, 1, pkt.size, f); 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; /* register all the codecs */ //avcodec_register_all(); av_register_all(); avformat_network_init(); // for network streaming audio_encode_example("rtp://127.0.0.1:8554"); return 0; }
_______________________________________________ Libav-user mailing list Libav-user@ffmpeg.org http://ffmpeg.org/mailman/listinfo/libav-user