Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
BC
public
mediastreamer2
Commits
ad69d2c5
Commit
ad69d2c5
authored
Nov 16, 2015
by
Sylvain Berfini
🎩
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Started rtt rework (use 2 filters for sending/receiving characters)
parent
c04a7920
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
744 additions
and
472 deletions
+744
-472
include/mediastreamer2/allfilters.h
include/mediastreamer2/allfilters.h
+3
-1
include/mediastreamer2/mediastream.h
include/mediastreamer2/mediastream.h
+3
-45
include/mediastreamer2/msrtt4103.h
include/mediastreamer2/msrtt4103.h
+47
-0
src/Makefile.am
src/Makefile.am
+2
-0
src/otherfilters/rfc4103_sink.cpp
src/otherfilters/rfc4103_sink.cpp
+363
-0
src/otherfilters/rfc4103_source.cpp
src/otherfilters/rfc4103_source.cpp
+260
-0
src/voip/mediastream.c
src/voip/mediastream.c
+0
-4
src/voip/rfc4103_textstream.c
src/voip/rfc4103_textstream.c
+66
-422
No files found.
include/mediastreamer2/allfilters.h
View file @
ad69d2c5
...
...
@@ -146,7 +146,9 @@ typedef enum MSFilterId{
MS_MKV_PLAYER_ID
,
MS_VAD_DTX_ID
,
MS_BB10_DISPLAY_ID
,
MS_BB10_CAPTURE_ID
MS_BB10_CAPTURE_ID
,
MS_RTT_4103_SOURCE_ID
,
MS_RTT_4103_SINK_ID
}
MSFilterId
;
...
...
include/mediastreamer2/mediastream.h
View file @
ad69d2c5
...
...
@@ -1172,30 +1172,13 @@ MS2_PUBLIC void audio_stream_set_audio_route(AudioStream *stream, MSAudioRoute r
* @{
**/
#define TS_OUTBUF_SIZE 32
#define TS_REDGEN 2
#define TS_NUMBER_OF_OUTBUF TS_REDGEN + 1
#define TS_INBUF_SIZE TS_OUTBUF_SIZE * TS_NUMBER_OF_OUTBUF
#define TS_KEEP_ALIVE_INTERVAL 25000 //10000
#define TS_SEND_INTERVAL 299
#define TS_FLAG_NOTFIRST 0x01
#define TS_FLAG_NOCALLBACK 0x02
struct
_TextStream
{
MediaStream
ms
;
int
flags
;
MSFilter
*
rttsource
;
MSFilter
*
rttsink
;
int
pt_t140
;
int
pt_red
;
int
prevseqno
;
uint8_t
inbuf
[
TS_INBUF_SIZE
];
size_t
inbufsize
;
uint8_t
*
inbufpos
;
uint8_t
buf
[
TS_NUMBER_OF_OUTBUF
][
TS_OUTBUF_SIZE
];
int
pribuf
;
size_t
bufsize
[
TS_NUMBER_OF_OUTBUF
];
uint32_t
timestamp
[
TS_NUMBER_OF_OUTBUF
];
int
pt_red
;
};
typedef
struct
_TextStream
TextStream
;
...
...
@@ -1251,31 +1234,6 @@ MS2_PUBLIC void text_stream_stop (TextStream * stream);
*/
MS2_PUBLIC
void
text_stream_iterate
(
TextStream
*
stream
);
/**
* Reads a character from the stream.
*
* @param[in] stream TextStream object previously created with text_stream_new().
* @return the character read or '\0' if there are no more character to read in the steam.
**/
MS2_PUBLIC
char
text_stream_getchar
(
TextStream
*
stream
);
/**
* Writes a character to the stream.
* To write an utf8 character, just call it multiple times.
*
* @param[in] stream TextStream object previously created with text_stream_new().
* @param[in] c the Char to send.
**/
MS2_PUBLIC
void
text_stream_putchar
(
TextStream
*
stream
,
const
char
c
);
/**
* Reads a character from the stream in UTF-32 format.
*
* @param[in] stream TextStream object previously created with text_stream_new().
* @return the character in UTF-32 format.
**/
MS2_PUBLIC
uint32_t
text_stream_getchar32
(
TextStream
*
stream
);
/**
* Writes a character to stream in UTF-32 format.
*
...
...
include/mediastreamer2/msrtt4103.h
0 → 100644
View file @
ad69d2c5
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef msrtt4103_h
#define msrtt4103_h
#include <mediastreamer2/msfilter.h>
#define TS_FLAG_NOTFIRST 0x01
#define TS_FLAG_NOCALLBACK 0x02
#define TS_OUTBUF_SIZE 32
#define TS_REDGEN 2
#define TS_NUMBER_OF_OUTBUF TS_REDGEN + 1
#define TS_INBUF_SIZE TS_OUTBUF_SIZE * TS_NUMBER_OF_OUTBUF
#define TS_KEEP_ALIVE_INTERVAL 25000 //10000
#define TS_SEND_INTERVAL 299
#define MS_RTT_4103_SOURCE_SET_T140_PAYLOAD_TYPE_NUMBER MS_FILTER_METHOD(MS_RTT_4103_SOURCE_ID, 0, int)
#define MS_RTT_4103_SINK_SET_T140_PAYLOAD_TYPE_NUMBER MS_FILTER_METHOD(MS_RTT_4103_SINK_ID, 0, int)
#define MS_RTT_4103_SOURCE_SET_RED_PAYLOAD_TYPE_NUMBER MS_FILTER_METHOD(MS_RTT_4103_SOURCE_ID, 1, int)
#define MS_RTT_4103_SINK_SET_RED_PAYLOAD_TYPE_NUMBER MS_FILTER_METHOD(MS_RTT_4103_SINK_ID, 1, int)
#define MS_RTT_4103_SOURCE_PUT_CHAR32 MS_FILTER_METHOD(MS_RTT_4103_SOURCE_ID, 2, uint32_t)
typedef
struct
_RealtimeTextReceivedCharacter
{
uint32_t
character
;
}
RealtimeTextReceivedCharacter
;
#define MS_RTT_4103_RECEIVED_CHAR MS_FILTER_EVENT(MS_RTT_4103_SINK_ID, 0, RealtimeTextReceivedCharacter)
#endif
src/Makefile.am
View file @
ad69d2c5
...
...
@@ -94,6 +94,8 @@ libmediastreamer_voip_la_SOURCES+= voip/private.h \
voip/audiostream.c
\
voip/ringstream.c
\
voip/rfc4103_textstream.c
\
otherfilters/rfc4103_source.cpp
\
otherfilters/rfc4103_sink.cpp
\
voip/msmediaplayer.c
\
voip/ice.c
\
otherfilters/msrtp.c
\
...
...
src/otherfilters/rfc4103_sink.cpp
0 → 100644
View file @
ad69d2c5
/*
* rfc4103_sink.cpp - Real time text RFC 4103 sender.
*
* Copyright (C) 2015 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "mediastreamer2/mediastream.h"
#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/msticker.h"
#include "mediastreamer2/msrtt4103.h"
typedef
struct
_RealTimeTextSinkData
{
int
flags
;
int
prevseqno
;
uint8_t
inbuf
[
TS_INBUF_SIZE
];
size_t
inbufsize
;
uint8_t
*
inbufpos
;
int
pt_t140
;
int
pt_red
;
}
RealTimeTextSinkData
;
/**
* How many bytes makes up one character.
**/
static
int
utf8_test
(
const
uint8_t
c
)
{
if
(
!
(
c
&
0x80
))
{
return
1
;
}
else
if
(
!
(
c
&
0x40
))
{
return
0
;
}
else
if
(
!
(
c
&
0x20
))
{
return
2
;
}
else
if
(
!
(
c
&
0x10
))
{
return
3
;
}
else
if
(
!
(
c
&
0x08
))
{
return
4
;
}
else
{
return
-
1
;
}
}
static
bool_t
is_utf8_buf_ok
(
const
uint8_t
*
b
,
const
size_t
s
)
{
int
i
,
t
;
for
(
i
=
0
,
t
=
0
;
i
<
(
int
)
s
;
i
++
,
t
--
)
{
if
(
t
==
0
)
{
t
=
utf8_test
(
b
[
i
]);
if
(
t
<=
0
)
{
return
FALSE
;
}
}
else
{
if
(
utf8_test
(
b
[
i
])
!=
0
)
{
return
FALSE
;
}
}
}
if
(
t
)
{
return
FALSE
;
}
return
TRUE
;
/* SUCCESS */
}
static
int
red_needed
(
int
cur
,
int
prev
)
{
int
t
=
cur
-
prev
;
if
(
t
>
0
)
{
return
t
-
1
;
}
else
if
(
t
<
-
100
)
{
return
t
+
0xFFFF
;
}
return
-
1
;
}
static
void
text_stream_hexdump
(
const
uint8_t
*
data
,
const
size_t
s
)
{
char
buf
[
1000
];
const
uint8_t
*
c
=
data
;
int
pos
=
0
;
int
i
=
0
;
buf
[
0
]
=
'\0'
;
while
(
c
<
data
+
s
)
{
pos
+=
snprintf
(
&
buf
[
pos
],
1000
-
pos
,
" ['%c']0x%X"
,
*
c
>
20
?
*
c
:
'X'
,
*
c
);
c
++
;
i
++
;
}
buf
[
pos
]
=
'\0'
;
ms_debug
(
"%s"
,
buf
);
}
static
void
insert_lost_char
(
uint8_t
*
p
){
p
[
0
]
=
0xEF
;
p
[
1
]
=
0xBF
;
p
[
2
]
=
0xBD
;
}
static
int
read_t140_data
(
RealTimeTextSinkData
*
stream
,
uint8_t
*
data
,
int
readsize
)
{
int
buf_size
=
(
int
)
TS_INBUF_SIZE
-
stream
->
inbufsize
;
if
(
readsize
<
0
)
{
ms_warning
(
"corrupt packet (readsize<0)"
);
return
-
1
;
}
else
if
(
readsize
>
buf_size
)
{
readsize
=
buf_size
;
ms_warning
(
"reading less characters than in buffer"
);
/*POTENTIAL BUG... if last char is a multi char but just parts of it get
in, next function fails and whole buf is ignored. */
}
if
(
readsize
>
0
)
{
ms_debug
(
"Reading %i bytes
\n
"
,
readsize
);
if
(
!
is_utf8_buf_ok
(
data
,
readsize
))
{
text_stream_hexdump
(
data
,
readsize
);
ms_warning
(
"not a valid utf8 payload"
);
stream
->
inbufsize
=
0
;
return
-
1
;
}
memcpy
(
&
stream
->
inbuf
[
stream
->
inbufsize
],
data
,
readsize
);
stream
->
inbufsize
+=
readsize
;
}
return
0
;
/* 0 on success */
}
static
void
process_t140_packet
(
RealTimeTextSinkData
*
stream
,
mblk_t
*
packet
)
{
int
seqno
=
rtp_get_seqnumber
(
packet
);
uint8_t
*
payload
;
int
payloadsize
=
rtp_get_payload
(
packet
,
&
payload
);
ms_debug
(
"t140 seqno:%i"
,
seqno
);
if
(
stream
->
flags
&
TS_FLAG_NOTFIRST
)
{
int
t
=
red_needed
(
seqno
,
stream
->
prevseqno
);
if
(
t
<
0
)
{
ms_warning
(
"packet arrived out of order"
);
return
;
}
else
if
(
t
>
0
)
{
stream
->
inbufsize
=
3
;
insert_lost_char
(
stream
->
inbuf
);
}
}
if
(
read_t140_data
(
stream
,
payload
,
payloadsize
))
{
return
;
/* return without updatting seqno */
}
stream
->
prevseqno
=
seqno
;
}
static
void
process_red_packet
(
RealTimeTextSinkData
*
stream
,
mblk_t
*
packet
)
{
int
seqno
=
rtp_get_seqnumber
(
packet
);
uint8_t
*
payload
;
int
redgen
=
0
;
int
pos
=
0
;
int
redneeded
;
int
readstart
;
int
payloadsize
=
rtp_get_payload
(
packet
,
&
payload
);
/* check how many is red, also check if its the right payload for the red */
ms_debug
(
"red seqno:%i"
,
seqno
);
while
((
pos
<
payloadsize
)
&&
(
payload
[
pos
]
&
(
1
<<
7
)))
{
redgen
++
;
if
(((
int
)
payload
[
pos
]
&
0x7F
)
!=
stream
->
pt_t140
)
{
ms_warning
(
"invalid red packet"
);
return
;
}
pos
+=
4
;
}
ms_debug
(
"red redgen:%i"
,
redgen
);
if
((
int
)
payload
[
pos
]
!=
stream
->
pt_t140
)
{
ms_warning
(
"invalid red packet"
);
return
;
}
if
(
stream
->
flags
&
TS_FLAG_NOTFIRST
)
{
redneeded
=
red_needed
(
seqno
,
stream
->
prevseqno
);
}
else
{
redneeded
=
0
;
}
if
(
redneeded
<
0
)
{
ms_warning
(
"packet arrived out of order"
);
return
;
}
ms_debug
(
"red redneeded:%i"
,
redneeded
);
if
(
redneeded
>
redgen
)
{
/* we need more red than we got */
stream
->
inbufsize
=
3
;
insert_lost_char
(
stream
->
inbuf
);
redneeded
=
redgen
;
}
/* loop over unneeded red */
readstart
=
redgen
*
4
+
1
;
for
(
pos
=
0
;
pos
<
(
redgen
-
redneeded
)
*
4
;
pos
+=
4
)
{
readstart
+=
(((
uint32_t
)
payload
[
pos
+
2
]
<<
8
)
|
(
uint32_t
)
payload
[
pos
+
3
])
&
0x3FF
;
}
if
(
read_t140_data
(
stream
,
&
payload
[
readstart
],
payloadsize
-
readstart
))
{
ms_debug
(
"error reading"
);
return
;
/* return without updating seqno */
}
stream
->
prevseqno
=
seqno
;
}
static
bool_t
read_text_packet
(
RealTimeTextSinkData
*
stream
,
mblk_t
*
packet
)
{
int
pt
;
stream
->
inbufpos
=
stream
->
inbuf
;
stream
->
inbufsize
=
0
;
if
(
packet
==
NULL
)
{
return
FALSE
;
}
pt
=
rtp_get_payload_type
(
packet
);
if
(
pt
==
stream
->
pt_t140
)
{
process_t140_packet
(
stream
,
packet
);
}
else
if
(
stream
->
pt_red
&&
pt
==
stream
->
pt_red
)
{
process_red_packet
(
stream
,
packet
);
}
else
{
ms_warning
(
"unkown pt for text packet (pt:%i t140:%i red:%i)"
,
pt
,
stream
->
pt_t140
,
stream
->
pt_red
);
}
if
(
!
(
stream
->
flags
&
TS_FLAG_NOTFIRST
))
{
stream
->
flags
|=
TS_FLAG_NOTFIRST
;
}
freemsg
(
packet
);
return
TRUE
;
}
static
bool_t
text_stream_ischar
(
RealTimeTextSinkData
*
stream
)
{
if
(
stream
->
inbufsize
)
{
return
TRUE
;
}
return
FALSE
;
}
static
char
text_stream_getchar
(
RealTimeTextSinkData
*
stream
)
{
uint8_t
*
p
=
stream
->
inbufpos
;
uint8_t
*
end
=
&
stream
->
inbuf
[
stream
->
inbufsize
];
while
(
end
>
p
)
{
if
(
p
[
0
]
!=
'\0'
)
{
if
(
end
-
p
>=
3
)
{
if
(
p
[
0
]
==
0xEF
&&
p
[
1
]
==
0xBB
&&
p
[
2
]
==
0xBF
)
{
/* BOM */
p
+=
3
;
continue
;
}
}
stream
->
inbufpos
=
p
+
1
;
return
*
p
;
}
p
++
;
}
return
'\0'
;
}
static
uint32_t
text_stream_getchar32
(
RealTimeTextSinkData
*
stream
)
{
uint32_t
c
=
text_stream_getchar
(
stream
);
int
t
=
utf8_test
(
c
);
switch
(
t
)
{
case
1
:
return
c
;
case
2
:
c
=
(
c
&
0x1F
)
<<
6
;
c
+=
((
uint32_t
)
text_stream_getchar
(
stream
)
&
0x3F
);
return
c
;
case
3
:
c
=
(
c
&
0x0F
)
<<
12
;
c
+=
(((
uint32_t
)
text_stream_getchar
(
stream
)
&
0x3F
)
<<
6
);
c
+=
((
uint32_t
)
text_stream_getchar
(
stream
)
&
0x3F
);
return
c
;
case
4
:
c
=
(
c
&
0x7
)
<<
19
;
c
+=
(((
uint32_t
)
text_stream_getchar
(
stream
)
&
0x3F
)
<<
12
);
c
+=
(((
uint32_t
)
text_stream_getchar
(
stream
)
&
0x3F
)
<<
6
);
c
+=
((
uint32_t
)
text_stream_getchar
(
stream
)
&
0x3F
);
return
c
;
default:
return
0
;
}
}
static
void
ms_rtt_4103_sink_init
(
MSFilter
*
f
)
{
RealTimeTextSinkData
*
s
=
ms_new0
(
RealTimeTextSinkData
,
1
);
s
->
pt_red
=
0
;
s
->
pt_t140
=
0
;
f
->
data
=
s
;
}
static
void
ms_rtt_4103_sink_preprocess
(
MSFilter
*
f
)
{
}
static
void
ms_rtt_4103_sink_process
(
MSFilter
*
f
)
{
RealTimeTextSinkData
*
s
=
(
RealTimeTextSinkData
*
)
f
->
data
;
mblk_t
*
im
;
ms_filter_lock
(
f
);
while
((
im
=
ms_queue_get
(
f
->
inputs
[
0
]))
!=
NULL
)
{
read_text_packet
(
s
,
im
);
if
(
text_stream_ischar
(
s
))
{
uint32_t
character
=
text_stream_getchar32
(
s
);
RealtimeTextReceivedCharacter
*
data
=
ms_new0
(
RealtimeTextReceivedCharacter
,
1
);
data
->
character
=
character
;
if
(
character
!=
0
)
{
ms_debug
(
"Received char 32: %lu"
,
(
long
unsigned
)
character
);
ms_filter_notify
(
f
,
MS_RTT_4103_RECEIVED_CHAR
,
data
);
}
}
}
ms_filter_unlock
(
f
);
}
static
void
ms_rtt_4103_sink_postprocess
(
MSFilter
*
f
)
{
}
static
void
ms_rtt_4103_sink_uninit
(
MSFilter
*
f
)
{
ms_free
(
f
->
data
);
}
static
int
ms_rtt_4103_sink_set_t140_payload
(
MSFilter
*
f
,
void
*
t140
)
{
RealTimeTextSinkData
*
s
=
(
RealTimeTextSinkData
*
)
f
->
data
;
ms_filter_lock
(
f
);
s
->
pt_t140
=
*
(
int
*
)
t140
;
ms_debug
(
"T140 payload number is %i"
,
s
->
pt_t140
);
ms_filter_unlock
(
f
);
return
0
;
}
static
int
ms_rtt_4103_sink_set_red_payload
(
MSFilter
*
f
,
void
*
red
)
{
RealTimeTextSinkData
*
s
=
(
RealTimeTextSinkData
*
)
f
->
data
;
ms_filter_lock
(
f
);
s
->
pt_red
=
*
(
int
*
)
red
;
ms_debug
(
"RED payload number is %i"
,
s
->
pt_red
);
ms_filter_unlock
(
f
);
return
0
;
}
static
MSFilterMethod
ms_rtt_4103_sink_methods
[]
=
{
{
MS_RTT_4103_SINK_SET_T140_PAYLOAD_TYPE_NUMBER
,
ms_rtt_4103_sink_set_t140_payload
},
{
MS_RTT_4103_SINK_SET_RED_PAYLOAD_TYPE_NUMBER
,
ms_rtt_4103_sink_set_red_payload
},
{
0
,
NULL
}
};
MSFilterDesc
ms_rtt_4103_sink_desc
=
{
MS_RTT_4103_SINK_ID
,
"MSRTT4103Sink"
,
"A filter to receive real time text"
,
MS_FILTER_OTHER
,
NULL
,
1
,
0
,
ms_rtt_4103_sink_init
,
ms_rtt_4103_sink_preprocess
,
ms_rtt_4103_sink_process
,
ms_rtt_4103_sink_postprocess
,
ms_rtt_4103_sink_uninit
,
ms_rtt_4103_sink_methods
};
MS_FILTER_DESC_EXPORT
(
ms_rtt_4103_sink_desc
)
\ No newline at end of file
src/otherfilters/rfc4103_source.cpp
0 → 100644
View file @
ad69d2c5
/*
* rfc4103_source.cpp - Real time text RFC 4103 sender.
*
* Copyright (C) 2015 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "mediastreamer2/mediastream.h"
#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/msticker.h"
#include "mediastreamer2/msrtt4103.h"
typedef
struct
_RealTimeTextSourceData
{
uint8_t
buf
[
TS_NUMBER_OF_OUTBUF
][
TS_OUTBUF_SIZE
];
size_t
bufsize
[
TS_NUMBER_OF_OUTBUF
];
int
pribuf
;
uint32_t
timestamp
[
TS_NUMBER_OF_OUTBUF
];
int
pt_t140
;
int
pt_red
;
}
RealTimeTextSourceData
;
static
uint32_t
get_prev_time
(
const
RealTimeTextSourceData
*
stream
)
{
return
stream
->
timestamp
[
stream
->
pribuf
?
stream
->
pribuf
-
1
:
TS_REDGEN
];
}
static
int
get_last_buf
(
const
RealTimeTextSourceData
*
stream
)
{
return
stream
->
pribuf
==
TS_REDGEN
?
0
:
stream
->
pribuf
+
1
;
}
static
void
use_next_buf
(
RealTimeTextSourceData
*
stream
)
{
stream
->
pribuf
=
get_last_buf
(
stream
);
stream
->
bufsize
[
stream
->
pribuf
]
=
0
;
stream
->
timestamp
[
stream
->
pribuf
]
=
0
;
}
static
int
get_next_buf
(
const
RealTimeTextSourceData
*
stream
,
const
int
cur
)
{
if
(
cur
==
stream
->
pribuf
){
return
-
1
;
}
return
cur
==
TS_REDGEN
?
0
:
cur
+
1
;
}
static
uint32_t
get_red_subheader
(
int
pt
,
int
offset
,
size_t
length
)
{
return
(
1
<<
31
)
|
((
0x7F
&
pt
)
<<
24
)
|
((
0x3FFF
&
offset
)
<<
10
)
|
(
0x3FF
&
(
int
)
length
);
}
static
mblk_t
*
realtime_text_stream_generate_red_packet
(
RealTimeTextSourceData
*
stream
)
{
int
cur
=
get_last_buf
(
stream
);
uint8_t
t140
=
(
stream
->
pt_t140
&
0x7F
);
int
pri
=
stream
->
pribuf
;
mblk_t
*
packet
;
uint8_t
payload
[
TS_OUTBUF_SIZE
*
TS_NUMBER_OF_OUTBUF
+
4
*
TS_REDGEN
+
1
];
size_t
payloadsize
=
0
;
int
mark
=
1
;
/* this makes it possible to generate t140 with same function... */
if
(
stream
->
pt_red
>
0
)
{
while
(
cur
!=
pri
)
{
uint32_t
diff
=
stream
->
timestamp
[
pri
]
-
stream
->
timestamp
[
cur
];
size_t
size
=
stream
->
bufsize
[
cur
];
uint32_t
sub
=
htonl
(
get_red_subheader
(
t140
,
diff
,
size
));
memcpy
(
&
payload
[
payloadsize
],
&
sub
,
4
);
payloadsize
+=
4
;
cur
=
get_next_buf
(
stream
,
cur
);
}
memcpy
(
&
payload
[
payloadsize
],
&
t140
,
1
);
payloadsize
+=
1
;
cur
=
get_last_buf
(
stream
);
while
(
cur
!=
pri
)
{
if
(
stream
->
bufsize
[
cur
])
{
mark
=
0
;
memcpy
(
&
payload
[
payloadsize
],
&
stream
->
buf
[
cur
][
0
],
stream
->
bufsize
[
cur
]);
payloadsize
+=
stream
->
bufsize
[
cur
];
}
cur
=
get_next_buf
(
stream
,
cur
);
}
}
if
(
stream
->
bufsize
[
pri
])
{
memcpy
(
&
payload
[
payloadsize
],
&
stream
->
buf
[
pri
][
0
],
stream
->
bufsize
[
pri
]);
payloadsize
+=
stream
->
bufsize
[
pri
];
}
packet
=
allocb
(
payloadsize
,
0
);
memcpy
(
packet
->
b_wptr
,
&
payload
[
payloadsize
],
payloadsize
);
packet
->
b_wptr
+=
payloadsize
;
mblk_set_marker_info
(
packet
,
mark
);
return
packet
;
}