I am trying to read an audio RTP stream in my application, but I am getting this error:
[pcm_mulaw @ 03390580] PCM channels out of bounds
I can read the RTP stream fine with ffplay:
ffplay -i test.sdp -protocol_whitelist file,udp,rtp
I generate the RTP stream using this command:
ffmpeg -re -f lavfi -i aevalsrc="sin(400*2*PI*t)" -ar 8000 -f mulaw -f rtp rtp://127.0.0.1:8554
// 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 0
b=AS:64
And here is my source code:
#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>
}
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
#define ERRBUFFLEN 200
char errbuf[ERRBUFFLEN];
#define av_err2str(ret) av_strerror(ret, errbuf, ERRBUFFLEN)
/*
* Audio decoding.
*/
static void audio_decode_example(const char *outfilename, const char *filename)
{
AVCodec *inCodec;
AVCodecContext *inCodecCtx = NULL;
int len;
FILE *f, *outfile;
uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
AVPacket avpkt;
AVFrame *decoded_frame = NULL;
AVFormatContext *inFormatCtx = NULL;
AVFrame *inFrame = NULL;
AVFrame *outFrame = NULL;
int ret;
av_init_packet(&avpkt);
AVDictionary *d = NULL; // "create" an empty dictionary
int listen = false;
listen = true;
if (listen)
{
av_dict_set(&d, "protocol_whitelist", "file,udp,rtp", 0); // add an entry
printf("Listening mode.\n");
}
else {
printf("Connecting mode.\n");
}
// Open video file
ret = avformat_open_input(&inFormatCtx, filename, NULL, &d);
if (ret <0)
{
printf_s("Failed: cannot open input.\n");
av_strerror(ret, errbuf, ERRBUFFLEN);
fprintf(stderr, "avformat_open_input() fail: %s\n", errbuf);
exit(1);
}
printf_s("Retrieve stream information.\n");
ret = avformat_find_stream_info(inFormatCtx, NULL);
if (ret <0)
{
printf_s("Failed: cannot find stream.\n");
av_strerror(ret, errbuf, ERRBUFFLEN);
fprintf(stderr, "avformat_find_stream_info() fail: %s\n", errbuf);
exit(1);
}
av_dump_format(inFormatCtx, 0, filename, 0);
int stream_idx = -1;
for (int i = 0; i < inFormatCtx->nb_streams; i++)
if (inFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
stream_idx = i;
break;
}
if (stream_idx == -1)
{
fprintf(stderr, "Video stream not found\n");
exit(1);
}
inCodec = avcodec_find_decoder(inFormatCtx->streams[stream_idx]->codec->codec_id);
if (!inCodec) {
fprintf(stderr, "Codec not found\n");
exit(1);
}
inCodecCtx = avcodec_alloc_context3(inCodec);
if (!inCodecCtx) {
fprintf(stderr, "Could not allocate audio codec context\n");
exit(1);
}
/* Error here */
ret = avcodec_open2(inCodecCtx, inCodec, NULL);
if (ret < 0) {
fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
exit(1);
}
(...more code)
I know something is wrong, but what is it? Suggestions and tips are much appreciated.
I found out that the stream attributes were not set automatically, so I had to manually set them before calling avcodec_open2()
:
inCodecCtx->sample_rate = 8000;
inCodecCtx->sample_fmt = AV_SAMPLE_FMT_S16;
inCodecCtx->channels = 1;
inCodecCtx->channel_layout = AV_CH_LAYOUT_MONO;
Hope this helps someone who encountered the same issue as I do.