summaryrefslogtreecommitdiff
path: root/src/repacketizer.c
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2013-11-18 16:46:38 -0500
committerJean-Marc Valin <jmvalin@jmvalin.ca>2013-11-18 16:46:38 -0500
commitf18356675295587d41bc7cf2aa173af8c1619e0d (patch)
treeb16f33adb81a3824b71d3a0824903537bb1da04c /src/repacketizer.c
parent7a0b68233f61b48e1980ca3aa1268f91955806e8 (diff)
downloadopus-f18356675295587d41bc7cf2aa173af8c1619e0d.tar.gz
Adds functions for multistream padding/unpadding and single-stream unpadding
These are all completely untested.
Diffstat (limited to 'src/repacketizer.c')
-rw-r--r--src/repacketizer.c92
1 files changed, 91 insertions, 1 deletions
diff --git a/src/repacketizer.c b/src/repacketizer.c
index 45bb3848..5bf0b5ab 100644
--- a/src/repacketizer.c
+++ b/src/repacketizer.c
@@ -207,7 +207,7 @@ opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int
for (i=0;i<count;i++)
{
/* Using OPUS_MOVE() instead of OPUS_COPY() in case we're doing in-place
- padding from opus_packet_pad */
+ padding from opus_packet_pad or opus_packet_strip(). */
OPUS_MOVE(ptr, frames[i], len[i]);
ptr += len[i];
}
@@ -233,6 +233,8 @@ int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len)
{
OpusRepacketizer rp;
opus_int32 ret;
+ if (len < 1)
+ return OPUS_BAD_ARG;
if (len==new_len)
return OPUS_OK;
else if (len > new_len)
@@ -247,3 +249,91 @@ int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len)
else
return ret;
}
+
+opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len)
+{
+ OpusRepacketizer rp;
+ opus_int32 ret;
+ if (len < 1)
+ return OPUS_BAD_ARG;
+ opus_repacketizer_init(&rp);
+ ret = opus_repacketizer_cat(&rp, data, len);
+ if (ret < 0)
+ return ret;
+ ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, len, 0, 0);
+ celt_assert(ret > 0);
+ return ret;
+}
+
+int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams)
+{
+ int s;
+ int count;
+ unsigned char toc;
+ opus_int16 size[48];
+ opus_int32 packet_offset;
+ opus_int32 amount;
+
+ if (len < 1)
+ return OPUS_BAD_ARG;
+ if (len==new_len)
+ return OPUS_OK;
+ else if (len > new_len)
+ return OPUS_BAD_ARG;
+ amount = new_len - len;
+ /* Seek to last stream */
+ for (s=0;s<nb_streams-1;s++)
+ {
+ if (len<=0)
+ return OPUS_INVALID_PACKET;
+ count = opus_packet_parse_impl(data, len, 0, &toc, NULL,
+ size, NULL, &packet_offset);
+ if (count<0)
+ return count;
+ data += packet_offset;
+ len -= packet_offset;
+ }
+ return opus_packet_pad(data, len, len+amount);
+}
+
+opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, int nb_streams)
+{
+ int s;
+ unsigned char toc;
+ opus_int16 size[48];
+ opus_int32 packet_offset;
+ OpusRepacketizer rp;
+ unsigned char *dst;
+ opus_int32 dst_len;
+
+ if (len < 1)
+ return OPUS_BAD_ARG;
+ dst = data;
+ dst_len = 0;
+ /* Seek to last stream */
+ for (s=0;s<nb_streams;s++)
+ {
+ opus_int32 ret;
+ int self_delimited = s!=nb_streams-1;
+ if (len<=0)
+ return OPUS_INVALID_PACKET;
+ opus_repacketizer_init(&rp);
+ ret = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,
+ size, NULL, &packet_offset);
+ if (ret<0)
+ return ret;
+ ret = opus_repacketizer_cat(&rp, data, packet_offset);
+ if (ret < 0)
+ return ret;
+ ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, dst, len, self_delimited, 0);
+ if (ret < 0)
+ return ret;
+ else
+ dst_len += ret;
+ dst += ret;
+ data += packet_offset;
+ len -= packet_offset;
+ }
+ return dst_len;
+}
+