aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2005-04-03 22:57:18 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2005-04-03 22:57:18 +0000
commit4ce1edc05cec917ad15513344d46fed1e35b6f58 (patch)
tree0377d7238fbc8640a0885f84f0b381aaef09d78c /channels
parentbbbb1d493dfcc49a639c0d6fda114322041a4f2b (diff)
handle AST_FORMAT_SLINEAR endianness properly on big-endian systems (bug #3865)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@5373 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rwxr-xr-xchannels/chan_iax2.c7
-rwxr-xr-xchannels/chan_phone.c21
-rwxr-xr-xchannels/iax2-parser.c9
3 files changed, 29 insertions, 8 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 6135ca4a1..6ea03392d 100755
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -7337,9 +7337,12 @@ retryowner2:
f.src = "IAX2";
f.mallocd = 0;
f.offset = 0;
- if (f.datalen && (f.frametype == AST_FRAME_VOICE))
+ if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
f.samples = get_samples(&f);
- else
+ /* We need to byteswap incoming slinear samples from network byte order */
+ if (f.subclass == AST_FORMAT_SLINEAR)
+ ast_frame_byteswap_be(&f);
+ } else
f.samples = 0;
iax_frame_wrap(&fr, &f);
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index 5cee02e6f..8e5bdb523 100755
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -544,10 +544,13 @@ static struct ast_frame *phone_read(struct ast_channel *ast)
: AST_FRAME_VIDEO;
p->fr.subclass = p->lastinput;
p->fr.offset = AST_FRIENDLY_OFFSET;
+ /* Byteswap from little-endian to native-endian */
+ if (p->fr.subclass == AST_FORMAT_SLINEAR)
+ ast_frame_byteswap_le(&p->fr);
return &p->fr;
}
-static int phone_write_buf(struct phone_pvt *p, const char *buf, int len, int frlen)
+static int phone_write_buf(struct phone_pvt *p, const char *buf, int len, int frlen, int swap)
{
int res;
/* Store as much of the buffer as we can, then write fixed frames */
@@ -555,7 +558,10 @@ static int phone_write_buf(struct phone_pvt *p, const char *buf, int len, int fr
/* Make sure we have enough buffer space to store the frame */
if (space < len)
len = space;
- memcpy(p->obuf + p->obuflen, buf, len);
+ if (swap)
+ ast_memcpy_byteswap(p->obuf+p->obuflen, buf, len/2);
+ else
+ memcpy(p->obuf + p->obuflen, buf, len);
p->obuflen += len;
while(p->obuflen > frlen) {
res = write(p->fd, p->obuf, frlen);
@@ -581,7 +587,7 @@ static int phone_write_buf(struct phone_pvt *p, const char *buf, int len, int fr
static int phone_send_text(struct ast_channel *ast, const char *text)
{
int length = strlen(text);
- return phone_write_buf(ast->tech_pvt, text, length, length) ==
+ return phone_write_buf(ast->tech_pvt, text, length, length, 0) ==
length ? 0 : -1;
}
@@ -729,12 +735,17 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
memset(tmpbuf + 4, 0, sizeof(tmpbuf) - 4);
memcpy(tmpbuf, frame->data, 4);
expected = 24;
- res = phone_write_buf(p, tmpbuf, expected, maxfr);
+ res = phone_write_buf(p, tmpbuf, expected, maxfr, 0);
}
res = 4;
expected=4;
} else {
- res = phone_write_buf(p, pos, expected, maxfr);
+ int swap = 0;
+#if __BYTE_ORDER == __BIG_ENDIAN
+ if (frame->subclass == AST_FORMAT_SLINEAR)
+ swap = 1; /* Swap big-endian samples to little-endian as we copy */
+#endif
+ res = phone_write_buf(p, pos, expected, maxfr, swap);
}
if (res != expected) {
if ((errno != EAGAIN) && (errno != EINTR)) {
diff --git a/channels/iax2-parser.c b/channels/iax2-parser.c
index 3472b5008..f83e7413f 100755
--- a/channels/iax2-parser.c
+++ b/channels/iax2-parser.c
@@ -855,8 +855,15 @@ void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
fr->af.delivery.tv_sec = 0;
fr->af.delivery.tv_usec = 0;
fr->af.data = fr->afdata;
- if (fr->af.datalen)
+ if (fr->af.datalen) {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ /* We need to byte-swap slinear samples from network byte order */
+ if (fr->af.subclass == AST_FORMAT_SLINEAR) {
+ ast_memcpy_byteswap(fr->af.data, f->data, fr->af.samples);
+ } else
+#endif
memcpy(fr->af.data, f->data, fr->af.datalen);
+ }
}
struct iax_frame *iax_frame_new(int direction, int datalen)