无法拉取的是因为没有RTP关于PCM的解包器,新建一个自定义解包器即可。PCM为裸数据,在RTP封装中无需额外处理,只需要在数据处理接口中做好大小端转换即可。
新建一个自定义解封装代码ffmpeg-3.0/libavformat/rtpdec_pcm.c
c
#include "libavutil/attributes.h"
#include "libavutil/base64.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
#include "avformat.h"
#include "rtpdec.h"
#include "rtpdec_formats.h"
// return 0 on packet, no more left, 1 on packet, 1 on partial packet
static int pcm_handle_packet(AVFormatContext *ctx, PayloadContext *data,
AVStream *st, AVPacket *pkt, uint32_t *timestamp,
const uint8_t *buf, int len, uint16_t seq,
int flags)
{
int result = 0;
int i = 0;
int width = 0;
int chan = 0;
switch (st->codec->sample_fmt) {
case AV_SAMPLE_FMT_U8:
width = 1;
break;
case AV_SAMPLE_FMT_S16:
width = 2;
break;
case AV_SAMPLE_FMT_S32:
width = 4;
break;
default:
width = 2;
break;
}
chan = st->codec->channels;
// printf("width:%d chan:%d\n", width, chan);
if ((result = av_new_packet(pkt, len)) < 0)
return result;
for (i = 0; i < len / width; i++) {
pkt->data[width * i] = buf[width * i + 1];
pkt->data[width * i + 1] = buf[width * i];
}
// memcpy(pkt->data, buf, len);
pkt->stream_index = st->index;
return 0;
}
static void pcm_close_context(PayloadContext *data)
{
#ifdef DEBUG
int ii;
for (ii = 0; ii < 32; ii++) {
if (data->packet_types_received[ii])
av_log(NULL, AV_LOG_DEBUG, "Received %d packets of type %d\n",
data->packet_types_received[ii], ii);
}
#endif
}
static int parse_pcm_sdp_line(AVFormatContext *s, int st_index,
PayloadContext *h264_data, const char *line)
{
return 0;
}
RTPDynamicProtocolHandler ff_pcmS16le_dynamic_handler = {
.enc_name = "L16",
.codec_type = AVMEDIA_TYPE_AUDIO,
.codec_id = AV_CODEC_ID_PCM_S16LE,
.priv_data_size = 0,
.parse_sdp_a_line = parse_pcm_sdp_line,
.close = pcm_close_context,
.parse_packet = pcm_handle_packet,
};
修改makefile
c
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -39,6 +39,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \
rtpdec_h263.o \
rtpdec_h263_rfc2190.o \
rtpdec_h264.o \
+ rtpdec_pcm.o \
rtpdec_hevc.o \
rtpdec_ilbc.o \
rtpdec_jpeg.o \
注册封装器
c
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -113,6 +113,7 @@ void ff_register_rtp_dynamic_payload_handlers(void)
ff_register_dynamic_payload_handler(&realmedia_mp3_dynamic_handler);
ff_register_dynamic_payload_handler(&speex_dynamic_handler);
ff_register_dynamic_payload_handler(&t140_dynamic_handler);
+ ff_register_dynamic_payload_handler(&ff_pcmS16le_dynamic_handler);
}
头文件声明接口
c
--- a/libavformat/rtpdec_formats.h
+++ b/libavformat/rtpdec_formats.h
@@ -83,5 +83,6 @@ extern RTPDynamicProtocolHandler ff_theora_dynamic_handler;
extern RTPDynamicProtocolHandler ff_vorbis_dynamic_handler;
extern RTPDynamicProtocolHandler ff_vp8_dynamic_handler;
extern RTPDynamicProtocolHandler ff_vp9_dynamic_handler;
+extern RTPDynamicProtocolHandler ff_pcmS16le_dynamic_handler;