diff options
author | Bent Bisballe Nyeng <deva@aasimon.org> | 2013-11-20 12:57:17 +0100 |
---|---|---|
committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2013-11-20 12:57:17 +0100 |
commit | 60f60cc76e43197a0825ffac9aff0b7007a94175 (patch) | |
tree | 9a35ef295e84dc8555eb7e361062d0aedeae8edd /src/rtp_profile_opus.cc | |
parent | 6a9ad0e4234b47982b82b30e8774dcc311f43cd2 (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.cc | 188 |
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; +} |