summaryrefslogtreecommitdiff
path: root/src/rtp_profile_opus.cc
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2013-11-20 12:57:17 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2013-11-20 12:57:17 +0100
commit60f60cc76e43197a0825ffac9aff0b7007a94175 (patch)
tree9a35ef295e84dc8555eb7e361062d0aedeae8edd /src/rtp_profile_opus.cc
parent6a9ad0e4234b47982b82b30e8774dcc311f43cd2 (diff)
Framework API now complete in its first iteration. So far with support for raw, opus and amrwb.
Diffstat (limited to 'src/rtp_profile_opus.cc')
-rw-r--r--src/rtp_profile_opus.cc188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/rtp_profile_opus.cc b/src/rtp_profile_opus.cc
new file mode 100644
index 0000000..102d175
--- /dev/null
+++ b/src/rtp_profile_opus.cc
@@ -0,0 +1,188 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * rtp_profile_opus.cc
+ *
+ * Tue Sep 10 13:53:24 CEST 2013
+ * Copyright 2013 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of lrtp.
+ *
+ * lrtp is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * lrtp is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with lrtp; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Part of this code is an adaptation of the GStreamer RTP profile code for Celt
+ * by Wim Taymans <wim.taymans@gmail.com>
+ * The original code can be found in the gst-plugins-good package version 1.1.3:
+ * http://gstreamer.freedesktop.org/src/gst-plugins-good
+ */
+#include "rtp_profile_opus.h"
+
+/*
+ +--------------+----------------+-----------+----------+
+ | Abbreviation | Name | Bandwidth | Sampling |
+ +--------------+----------------+-----------+----------+
+ | nb | Narrowband | 0 - 4000 | 8000 |
+ | | | | |
+ | mb | Mediumband | 0 - 6000 | 12000 |
+ | | | | |
+ | wb | Wideband | 0 - 8000 | 16000 |
+ | | | | |
+ | swb | Super-wideband | 0 - 12000 | 24000 |
+ | | | | |
+ | fb | Fullband | 0 - 20000 | 48000 |
+ +--------------+----------------+-----------+----------+
+
+ Audio bandwidth naming
+
+ Table 1
+*/
+/*
+Recommended Bitrate
+
+ For a frame size of 20 ms, these are the bitrate "sweet spots" for
+ Opus in various configurations:
+ o 8-12 kb/s for NB speech,
+ o 16-20 kb/s for WB speech,
+ o 28-40 kb/s for FB speech,
+ o 48-64 kb/s for FB mono music, and
+ o 64-128 kb/s for FB stereo music.
+*/
+
+/*
+Forward Error Correction (FEC)
+
+ The voice mode of Opus allows for "in-band" forward error correction
+ (FEC) data to be embedded into the bit stream of Opus.
+*/
+
+/*
+RTP Header Usage
+
+ The format of the RTP header is specified in [RFC3550]. The Opus
+ payload format uses the fields of the RTP header consistent with this
+ specification.
+
+ The payload length of Opus is a multiple number of octets and
+ therefore no padding is required. The payload MAY be padded by an
+ integer number of octets according to [RFC3550].
+
+ The marker bit (M) of the RTP header is used in accordance with
+ Section 4.1 of [RFC3551].
+
+ The RTP payload type for Opus has not been assigned statically and is
+ expected to be assigned dynamically.
+
+ The receiving side MUST be prepared to receive duplicates of RTP
+ packets. Only one of those payloads MUST be provided to the Opus
+ decoder for decoding and others MUST be discarded.
+
+ Opus supports 5 different audio bandwidths which may be adjusted
+ during the duration of a call. The RTP timestamp clock frequency is
+ defined as the highest supported sampling frequency of Opus, i.e.
+ 48000 Hz, for all modes and sampling rates of Opus. The unit for the
+ timestamp is samples per single (mono) channel. The RTP timestamp
+ corresponds to the sample time of the first encoded sample in the
+ encoded frame. For sampling rates lower than 48000 Hz the number of
+ samples has to be multiplied with a multiplier according to Table 2
+ to determine the RTP timestamp.
+
+ +---------+------------+
+ | fs (Hz) | Multiplier |
+ +---------+------------+
+ | 8000 | 6 |
+ | | |
+ | 12000 | 4 |
+ | | |
+ | 16000 | 3 |
+ | | |
+ | 24000 | 2 |
+ | | |
+ | 48000 | 1 |
+ +---------+------------+
+
+ Table 2: Timestamp multiplier
+*/
+
+#include "rtp_profile.h"
+
+#include <stdio.h>
+#include <string.h>
+
+struct lrtp_profile_opus_t {
+ struct lrtp_profile_t profile; // 'Inherit' lrtp_profile_t
+};
+
+int profile_opus_pack(struct lrtp_profile_t *profile,
+ const char *frame, size_t framesize,
+ RTP &rtp)
+{
+ //struct lrtp_profile_opus_t *p = (struct lrtp_profile_opus_t *)profile;
+ (void)profile;
+
+ rtp.setPayload(frame, framesize);
+ rtp.setValid(true);
+
+ return framesize;
+}
+
+int profile_opus_unpack(struct lrtp_profile_t *profile,
+ const RTP &rtp,
+ std::list<outputframe_t *> &framelist)
+{
+ struct lrtp_profile_opus_t *p = (struct lrtp_profile_opus_t *)profile;
+
+ outputframe_t *of = new outputframe_t();
+ of->size = rtp.payloadSize();
+ char *buf = (char*)malloc(of->size);
+ of->size = rtp.payload(buf, of->size);
+ of->data = buf;
+
+ framelist.push_back(of);
+
+ return 0;
+}
+
+void profile_opus_destroy(struct lrtp_profile_t *profile)
+{
+ struct lrtp_profile_opus_t *p = (struct lrtp_profile_opus_t *)profile;
+ delete p;
+}
+
+struct lrtp_profile_t *profile_opus_create(struct lrtp_t *lrtp,
+ unsigned int csrc,
+ va_list vp)
+{
+ struct lrtp_profile_opus_t *p = new struct lrtp_profile_opus_t;
+
+ p->profile.pack = profile_opus_pack;
+ p->profile.unpack = profile_opus_unpack;
+ p->profile.destroy = profile_opus_destroy;
+
+ while(true) {
+ int type = va_arg(vp, int);
+ if(type == OPTION_END) break;
+
+ switch(type) {
+ default:
+ // TODO: Unknown arg type
+ break;
+ }
+ }
+
+ return &p->profile;
+}