summaryrefslogtreecommitdiff
path: root/src/rtp_profile_l16.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rtp_profile_l16.cc')
-rw-r--r--src/rtp_profile_l16.cc148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/rtp_profile_l16.cc b/src/rtp_profile_l16.cc
new file mode 100644
index 0000000..379df1c
--- /dev/null
+++ b/src/rtp_profile_l16.cc
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * rtp_profile_l16.cc
+ *
+ * Mon Dec 23 14:36:50 CET 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
+ */
+#include "rtp_profile_l16.h"
+
+#include "rtp_profile.h"
+
+#include <stdio.h>
+#include <string.h>
+
+// For ntoh et al.
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <arpa/inet.h>
+#endif
+
+struct lrtp_profile_l16_t {
+ struct lrtp_profile_t profile; // 'Inherit' lrtp_profile_t
+
+ unsigned short int pkg_size;
+ unsigned int num_channels;
+ bool little_endian;
+};
+
+int profile_l16_pack(struct lrtp_profile_t *profile,
+ const char *frame, size_t framesize,
+ RTP &rtp)
+{
+ struct lrtp_profile_l16_t *p = (struct lrtp_profile_l16_t *)profile;
+
+ size_t cpsamples = p->pkg_size;
+
+ // Calculate complete sample-channel tuples in frame.
+ size_t num_samples = framesize / (sizeof(short) * p->num_channels);
+
+ if(cpsamples > num_samples) cpsamples = num_samples;
+
+ // Convert to bytes
+ size_t cpsz = cpsamples * sizeof(short) * p->num_channels;
+
+ if(p->little_endian) {
+ short *buf = (short*)malloc(cpsz / sizeof(short));
+ for(size_t i = 0; i < cpsz / sizeof(short); i++) {
+ buf[i] = htons(((const short*)frame)[i]);
+ }
+ rtp.setPayload((char*)buf, cpsz);
+ free(buf);
+ } else {
+ rtp.setPayload(frame, cpsz);
+ }
+
+ return cpsz;
+}
+
+int profile_l16_unpack(struct lrtp_profile_t *profile,
+ const RTP &rtp,
+ std::list<outputframe_t *> &framelist)
+{
+ struct lrtp_profile_l16_t *p = (struct lrtp_profile_l16_t *)profile;
+
+ outputframe_t *of = new outputframe_t();
+ of->size = rtp.payloadSize();
+ char *buf = (char*)malloc(of->size);
+
+ if(p->little_endian) {
+ const short *frame = (const short *)rtp.payloadData();
+ for(size_t i = 0; i < of->size / sizeof(short); i++) {
+ ((short*)buf)[i] = ntohs(frame[i]);
+ }
+ } else {
+ of->size = rtp.payload(buf, of->size);
+ }
+
+ of->data = buf;
+
+ framelist.push_back(of);
+
+ return 0;
+}
+
+void profile_l16_destroy(struct lrtp_profile_t *profile)
+{
+ struct lrtp_profile_l16_t *p = (struct lrtp_profile_l16_t *)profile;
+ delete p;
+}
+
+struct lrtp_profile_t *profile_l16_create(struct lrtp_t *lrtp,
+ unsigned int csrc,
+ va_list vp)
+{
+ struct lrtp_profile_l16_t *p = new struct lrtp_profile_l16_t;
+
+ p->profile.pack = profile_l16_pack;
+ p->profile.unpack = profile_l16_unpack;
+ p->profile.destroy = profile_l16_destroy;
+
+ p->pkg_size = 1024;
+ p->little_endian = false;
+ p->num_channels = 1;
+
+ while(true) {
+ int type = va_arg(vp, int);
+ if(type == OPTION_END) break;
+
+ switch(type) {
+ case OPTION_L16_SAMPLES_PER_CHANNEL_PER_PACKET:
+ p->pkg_size = va_arg(vp, int);
+ break;
+ case OPTION_L16_CHANNELS:
+ p->num_channels = va_arg(vp, int);
+ break;
+ case OPTION_L16_LITTLE_ENDIAN:
+ p->little_endian = va_arg(vp, int);
+ break;
+ default:
+ // TODO: Unknown arg type
+ break;
+ }
+ }
+
+ return &p->profile;
+}
+