avformat/rtpdec: export Opus extradata in ff_rtp_parse_open()

This commit is contained in:
Jonathan Baudanza 2020-12-29 10:07:11 -08:00 committed by James Almer
parent ddd6c5cdc0
commit 6c24f2bf41
1 changed files with 51 additions and 0 deletions

View File

@ -24,12 +24,15 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/time.h"
#include "libavcodec/bytestream.h"
#include "avformat.h"
#include "network.h"
#include "srtp.h"
#include "url.h"
#include "rtpdec.h"
#include "rtpdec_formats.h"
#include "internal.h"
#define MIN_FEEDBACK_INTERVAL 200000 /* 200 ms in us */
@ -529,6 +532,43 @@ int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd,
return 0;
}
static int opus_write_extradata(AVCodecParameters *codecpar)
{
uint8_t *bs;
int ret;
/* This function writes an extradata with a channel mapping family of 0.
* This mapping family only supports mono and stereo layouts. And RFC7587
* specifies that the number of channels in the SDP must be 2.
*/
if (codecpar->channels > 2) {
return AVERROR_INVALIDDATA;
}
ret = ff_alloc_extradata(codecpar, 19);
if (ret < 0)
return ret;
bs = (uint8_t *)codecpar->extradata;
/* Opus magic */
bytestream_put_buffer(&bs, "OpusHead", 8);
/* Version */
bytestream_put_byte (&bs, 0x1);
/* Channel count */
bytestream_put_byte (&bs, codecpar->channels);
/* Pre skip */
bytestream_put_le16 (&bs, 0);
/* Input sample rate */
bytestream_put_le32 (&bs, 48000);
/* Output gain */
bytestream_put_le16 (&bs, 0x0);
/* Mapping family */
bytestream_put_byte (&bs, 0x0);
return 0;
}
/**
* open a new RTP parse context for stream 'st'. 'st' can be NULL for
* MPEG-2 TS streams.
@ -537,6 +577,7 @@ RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st,
int payload_type, int queue_size)
{
RTPDemuxContext *s;
int ret;
s = av_mallocz(sizeof(RTPDemuxContext));
if (!s)
@ -560,6 +601,16 @@ RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st,
if (st->codecpar->sample_rate == 8000)
st->codecpar->sample_rate = 16000;
break;
case AV_CODEC_ID_OPUS:
ret = opus_write_extradata(st->codecpar);
if (ret < 0) {
av_log(s1, AV_LOG_ERROR,
"Error creating opus extradata: %s\n",
av_err2str(ret));
av_free(s);
return NULL;
}
break;
default:
break;
}