Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
F
freeswitch
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
张华
freeswitch
Commits
0c819da6
提交
0c819da6
authored
5月 26, 2015
作者:
Seven Du
提交者:
Michael Jerris
5月 28, 2015
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
FS-7585: add rtmp video support
上级
e1874797
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
2197 行增加
和
134 行删除
+2197
-134
freeswitch-h264.swf
clients/flex/freeswitch-h264.swf
+0
-0
freeswitch-video.html
clients/flex/freeswitch-video.html
+195
-0
jquery.min.js
clients/flex/jquery.min.js
+0
-0
Makefile.am
src/mod/endpoints/mod_rtmp/Makefile.am
+1
-1
handshake.h
src/mod/endpoints/mod_rtmp/handshake.h
+771
-0
mod_rtmp.c
src/mod/endpoints/mod_rtmp/mod_rtmp.c
+180
-57
mod_rtmp.h
src/mod/endpoints/mod_rtmp/mod_rtmp.h
+56
-4
rtmp.c
src/mod/endpoints/mod_rtmp/rtmp.c
+145
-12
rtmp_sig.c
src/mod/endpoints/mod_rtmp/rtmp_sig.c
+29
-2
rtmp_tcp.c
src/mod/endpoints/mod_rtmp/rtmp_tcp.c
+22
-58
rtmp_video.c
src/mod/endpoints/mod_rtmp/rtmp_video.c
+749
-0
rtmp_video.h
src/mod/endpoints/mod_rtmp/rtmp_video.h
+49
-0
没有找到文件。
clients/flex/freeswitch-h264.swf
0 → 100644
浏览文件 @
0c819da6
File added
clients/flex/freeswitch-video.html
0 → 100644
浏览文件 @
0c819da6
<html>
<head>
<META
http-equiv=
"Content-Type"
content=
"text/html;charset=utf-8"
></META>
<TITLE>
FreeSWITCH Video Flash Phone Demo
</TITLE>
<script
type=
"text/javascript"
src=
"swfobject.js"
></script>
<script
type=
"text/javascript"
src=
"jquery.min.js"
></script>
<script
type=
"text/javascript"
charset=
"utf-8"
>
var
flashvars
=
{
rtmp_url
:
'rtmp://'
+
document
.
location
.
hostname
+
'/phone'
,
local_loopback
:
2
,
// x pos if local video
buffer_time
:
0
};
var
params
=
{
allowScriptAccess
:
'always'
,
wmode
:
'window'
};
var
current_uuid
=
"uuid"
;
var
flash
;
function
log
(
msg
)
{
if
(
'console'
in
window
)
console
.
log
(
msg
);
}
function
login
()
{
flash
.
login
(
$
(
'#user'
).
val
(),
'1234'
);
}
function
register
()
{
flash
.
register
(
$
(
'#user'
).
val
(),
'Test'
);
}
function
unregister
()
{
flash
.
register
(
$
(
'#user'
).
val
(),
'Test'
);
}
function
makeCall
()
{
flash
.
makeCall
(
$
(
'#dest'
).
val
(),
''
,
{
want_video
:
"true"
});
}
function
hangup
()
{
flash
.
hangup
(
current_uuid
);
}
function
answer
()
{
flash
.
answer
(
current_uuid
);
}
function
settings
()
{
flash
.
showPrivacy
();
}
function
send_dtmf
(
digit
)
{
flash
.
sendDTMF
(
digit
,
2000
);
}
function
onDisplayUpdate
(
uuid
,
name
,
number
){
log
(
"DisplayUpdate -- uuid: "
+
uuid
+
" name: "
+
name
+
" number: "
+
number
);
}
function
onCallState
(
uuid
,
state
){
log
(
"CallState -- uuid: "
+
uuid
+
" state: "
+
state
);
$
(
'#status'
).
html
(
state
);
}
function
onIncomingCall
(
uuid
,
name
,
number
,
account
,
evt
){
log
(
"IncomingCall -- uuid: "
+
uuid
+
" name: "
+
name
+
" number: "
+
number
+
" account: "
+
account
);
log
(
evt
);
if
(
current_uuid
==
"uuid"
)
{
var
want_video
=
""
;
current_uuid
=
uuid
;
if
(
typeof
(
evt
)
===
"object"
&&
evt
.
want_video
==
"true"
)
{
want_video
=
" (Video)"
;
}
$
(
'#incoming_call'
).
html
(
"Incoming call "
+
uuid
+
" from '"
+
name
+
"' <"
+
number
+
">"
+
want_video
);
}
else
{
$
(
"#flash"
)[
0
].
hangup
(
uuid
);
}
}
function
onDisconnected
(){
log
(
"socket disconnected"
);
$
(
'#status'
).
html
(
'Disconnected'
);
$
(
'#reconnect'
).
show
();
}
function
onMakeCall
(
uuid
,
number
,
account
){
log
(
"MakeCall -- uuid: "
+
uuid
+
" account: "
+
account
+
" number: "
+
number
);
current_uuid
=
uuid
;
}
function
onHangup
(
uuid
,
cause
){
log
(
"Hangup -- uuid: "
+
uuid
+
" cause: "
+
cause
);
current_uuid
=
"uuid"
;
$
(
'#status'
).
html
(
"Hangup "
+
cause
);
}
function
onDebug
(
message
){
log
(
"debug -- "
+
message
);
}
function
onAttach
(
uuid
){
log
(
"Attach -- "
+
uuid
);
}
function
onConnected
(
session_id
){
log
(
"Connected -- sessionid: "
+
session_id
);
$
(
'#session_id'
).
html
(
session_id
);
$
(
'#status'
).
html
(
'Connected'
);
$
(
'#reconnect'
).
hide
();
}
function
onLogin
(
status
,
user
,
domain
){
log
(
"Login -- status: "
+
status
+
" user: "
+
user
+
" domain: "
+
domain
);
}
function
onLogout
(
user
,
domain
){
log
(
"Logout -- user: "
+
user
+
" domain: "
+
domain
);
}
function
onInit
(){
console
.
log
(
'initing...'
);}
</script>
</head>
<body>
<div
id=
"dialpad"
style=
"float:left;width:300px"
>
<table
border=
"1"
cellspacing=
"5"
cellpadding=
"5"
width=
"200"
>
<tr>
<th
colspan =
3
>
Flash Phone
</th>
</tr><tr>
<td
colspan =
3
>
<input
type=
"text"
name=
"x"
value=
"9196"
id=
"dest"
size =
"10"
>
</td>
</tr><tr>
<td><input
type=
"button"
name=
"k7"
value=
"7"
id=
"k7"
onclick=
"send_dtmf('7')"
></td>
<td><input
type=
"button"
name=
"k7"
value=
"8"
id=
"k7"
onclick=
"send_dtmf('8')"
></td>
<td><input
type=
"button"
name=
"k7"
value=
"9"
id=
"k7"
onclick=
"send_dtmf('9')"
></td>
</tr><tr>
<td><input
type=
"button"
name=
"k7"
value=
"4"
id=
"k7"
onclick=
"send_dtmf('4')"
></td>
<td><input
type=
"button"
name=
"k7"
value=
"5"
id=
"k7"
onclick=
"send_dtmf('5')"
></td>
<td><input
type=
"button"
name=
"k7"
value=
"6"
id=
"k7"
onclick=
"send_dtmf('6')"
></td>
</tr><tr>
<td><input
type=
"button"
name=
"k7"
value=
"1"
id=
"k7"
onclick=
"send_dtmf('1')"
></td>
<td><input
type=
"button"
name=
"k7"
value=
"2"
id=
"k7"
onclick=
"send_dtmf('2')"
></td>
<td><input
type=
"button"
name=
"k7"
value=
"3"
id=
"k7"
onclick=
"send_dtmf('3')"
></td>
</tr><tr>
<td><input
type=
"button"
name=
"k7"
value=
"*"
id=
"k7"
onclick=
"send_dtmf('*')"
></td>
<td><input
type=
"button"
name=
"k7"
value=
"0"
id=
"k7"
onclick=
"send_dtmf('0')"
></td>
<td><input
type=
"button"
name=
"k7"
value=
"#"
id=
"k7"
onclick=
"send_dtmf('#')"
></td>
</tr><tr>
<td
colspan=
"3"
>
<span
id=
"status"
>
Ready
</span>
<span
id=
"reconnect"
style=
"display:none"
>
<a
href=
'#'
onclick=
"flash.connect();return false;"
>
Reconnect
</a>
</span>
</td>
</tr>
</table>
</div>
<div>
SessionID:
<span
id =
"session_id"
></span><br>
Incoming:
<span
id =
"incoming_call"
></span>
<br>
<input
type=
"text"
name=
"user"
value=
"1019@192.168.7.4"
id=
"user"
>
<input
type=
"button"
name=
"Call"
value=
"Login"
onclick =
"login()"
id=
"Login"
>
<input
type=
"button"
name=
"Register"
value=
"Register"
onclick =
"register()"
id=
"Register"
>
<input
type=
"button"
name=
"Register"
value=
"UnRegister"
onclick =
"unregister()"
id=
"UnRegister"
>
<br>
<input
type=
"button"
name=
"Call"
value=
"Call"
onclick =
"makeCall()"
id=
"Call"
>
<input
type=
"button"
name=
"Call"
value=
"Hangup"
onclick =
"hangup()"
id=
"Hangup"
>
<input
type=
"button"
name=
"some_name"
value=
"Answer"
id=
"some_name"
onclick=
"answer()"
>
<input
type=
"button"
name=
"some_name"
value=
"Settings"
id=
"some_name"
onclick=
"settings()"
>
</div>
<div
style=
"border:2px solid blue;float:left;padding:5px"
>
<div
id=
"flash"
>
<h1>
Alternative content
</h1>
<p><a
href=
"http://www.adobe.com/go/getflashplayer"
><img
src=
"http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif"
alt=
"Get Adobe Flash player"
/></a></p>
</div>
</div>
<br
style=
"clear:both"
>
<script
type=
"text/javascript"
charset=
"utf-8"
>
$
(
document
).
ready
(
function
()
{
swfobject
.
embedSWF
(
"freeswitch-h264.swf"
,
"flash"
,
"360"
,
"296"
,
"11.2.202.229"
,
"expressInstall.swf"
,
flashvars
,
params
,
[]);
flash
=
$
(
'#flash'
)[
0
];
$
(
'#user'
).
val
(
"1000@"
+
window
.
location
.
hostname
);
});
</script>
</body>
</html>
clients/flex/jquery.min.js
0 → 100644
浏览文件 @
0c819da6
B
/*!
src/mod/endpoints/mod_rtmp/Makefile.am
浏览文件 @
0c819da6
include
$(top_srcdir)/build/modmake.rulesam
MODNAME
=
mod_rtmp
mod_LTLIBRARIES
=
mod_rtmp.la
mod_rtmp_la_SOURCES
=
mod_rtmp.c rtmp_sig.c rtmp.c rtmp_tcp.c
mod_rtmp_la_SOURCES
=
mod_rtmp.c rtmp_sig.c rtmp.c rtmp_tcp.c
rtmp_video.c
mod_rtmp_la_SOURCES
+=
libamf/src/amf0.c libamf/src/hash.c libamf/src/io.c libamf/src/ptrarray.c libamf/src/types.c
mod_rtmp_la_CFLAGS
=
$(AM_CFLAGS)
-Ilibamf
/src
-I
$(abs_srcdir)
/libamf/src
mod_rtmp_la_LIBADD
=
$(switch_builddir)
/libfreeswitch.la
...
...
src/mod/endpoints/mod_rtmp/handshake.h
0 → 100644
浏览文件 @
0c819da6
差异被折叠。
点击展开。
src/mod/endpoints/mod_rtmp/mod_rtmp.c
浏览文件 @
0c819da6
差异被折叠。
点击展开。
src/mod/endpoints/mod_rtmp/mod_rtmp.h
浏览文件 @
0c819da6
...
...
@@ -23,6 +23,7 @@
* Contributor(s):
*
* Mathieu Rene <mrene@avgs.ca>
* Seven Du <dujinfang@gmail.com>
*
* mod_rtmp.h -- RTMP Endpoint Module
*
...
...
@@ -45,8 +46,8 @@
#define RTMP_USER_VARIABLE_PREFIX "rtmp_u_"
#define RTMP_DEFAULT_PORT 1935
#define RTMP_TCP_READ_BUF 2048
#define AMF_MAX_SIZE
2048
#define RTMP_TCP_READ_BUF 2048
* 16
#define AMF_MAX_SIZE
2048 * 16
#define SUPPORT_SND_NONE 0x0000
#define SUPPORT_SND_ADPCM 0x0002
...
...
@@ -77,7 +78,7 @@
#define kAMF0 0
#define kAMF3 3
#define RTMP_DEFAULT_ACK_WINDOW 0x20000
#define RTMP_DEFAULT_ACK_WINDOW 0x20000
0
#define RTMP_TYPE_CHUNKSIZE 0x01
#define RTMP_TYPE_ABORT 0x2
...
...
@@ -130,6 +131,12 @@
#define INT32_MAX 0x7fffffffL
#endif
/* Media debug flags */
#define RTMP_MD_AUDIO_READ (1 << 0)
#define RTMP_MD_AUDIO_WRITE (1 << 1)
#define RTMP_MD_VIDEO_READ (1 << 2)
#define RTMP_MD_VIDEO_WRITE (1 << 3)
typedef
enum
{
RTMP_AUDIO_PCM
=
0
,
RTMP_AUDIO_ADPCM
=
1
,
...
...
@@ -412,6 +419,29 @@ struct rtmp_account {
rtmp_account_t
*
next
;
};
typedef
struct
rtmp2rtp_helper_s
{
amf0_data
*
sps
;
amf0_data
*
pps
;
amf0_data
*
nal_list
;
uint32_t
lenSize
;
}
rtmp2rtp_helper_t
;
typedef
struct
rtp2rtmp_helper_s
{
amf0_data
*
sps
;
amf0_data
*
pps
;
amf0_data
*
avc_conf
;
switch_bool_t
send
;
switch_bool_t
send_avc
;
switch_buffer_t
*
rtmp_buf
;
switch_buffer_t
*
fua_buf
;
//fu_a buf
uint32_t
last_recv_ts
;
uint8_t
last_mark
;
uint16_t
last_seq
;
switch_bool_t
sps_changed
;
}
rtp2rtmp_helper_t
;
struct
rtmp_session
{
switch_memory_pool_t
*
pool
;
rtmp_profile_t
*
profile
;
...
...
@@ -484,6 +514,9 @@ struct rtmp_session {
uint32_t
media_streamid
;
/* < The stream id that was used for the last "play" command,
where we should send media */
switch_size_t
dropped_video_frame
;
uint8_t
media_debug
;
};
struct
rtmp_private
{
...
...
@@ -509,6 +542,7 @@ struct rtmp_private {
uint8_t
video_codec
;
switch_time_t
stream_start_ts
;
switch_time_t
stream_last_ts
;
switch_timer_t
timer
;
switch_buffer_t
*
readbuf
;
switch_mutex_t
*
readbuf_mutex
;
...
...
@@ -522,6 +556,24 @@ struct rtmp_private {
uint16_t
maxlen
;
int
over_size
;
//video
int
has_video
;
switch_codec_t
video_read_codec
;
switch_codec_t
video_write_codec
;
rtp2rtmp_helper_t
video_write_helper
;
rtmp2rtp_helper_t
video_read_helper
;
switch_frame_t
video_read_frame
;
uint32_t
video_read_ts
;
uint16_t
seq
;
unsigned
char
video_databuf
[
SWITCH_RTP_MAX_BUF_LEN
];
/* < Buffer for read_frame */
switch_buffer_t
*
video_readbuf
;
switch_mutex_t
*
video_readbuf_mutex
;
uint16_t
video_maxlen
;
int
video_over_size
;
switch_core_media_params_t
mparams
;
switch_media_handle_t
*
media_handle
;
};
struct
rtmp_reg
;
...
...
@@ -540,7 +592,6 @@ typedef enum {
MSG_FULLHEADER
=
1
}
rtmp_message_send_flag_t
;
/* Invokable functions from flash */
RTMP_INVOKE_FUNCTION
(
rtmp_i_connect
);
RTMP_INVOKE_FUNCTION
(
rtmp_i_createStream
);
...
...
@@ -548,6 +599,7 @@ RTMP_INVOKE_FUNCTION(rtmp_i_noop);
RTMP_INVOKE_FUNCTION
(
rtmp_i_play
);
RTMP_INVOKE_FUNCTION
(
rtmp_i_publish
);
RTMP_INVOKE_FUNCTION
(
rtmp_i_makeCall
);
RTMP_INVOKE_FUNCTION
(
rtmp_i_fcSubscribe
);
RTMP_INVOKE_FUNCTION
(
rtmp_i_sendDTMF
);
RTMP_INVOKE_FUNCTION
(
rtmp_i_login
);
RTMP_INVOKE_FUNCTION
(
rtmp_i_logout
);
...
...
src/mod/endpoints/mod_rtmp/rtmp.c
浏览文件 @
0c819da6
差异被折叠。
点击展开。
src/mod/endpoints/mod_rtmp/rtmp_sig.c
浏览文件 @
0c819da6
...
...
@@ -23,6 +23,7 @@
* Contributor(s):
*
* Mathieu Rene <mrene@avgs.ca>
* Seven Du <dujinfang@gmail.com>
*
* rtmp.c -- RTMP Signalling functions
*
...
...
@@ -284,8 +285,7 @@ RTMP_INVOKE_FUNCTION(rtmp_i_makeCall)
if
((
number
=
amf0_get_string
(
argv
[
1
])))
{
switch_event_t
*
event
=
NULL
;
char
*
auth
,
*
user
=
NULL
,
*
domain
=
NULL
;
if
((
auth
=
amf0_get_string
(
argv
[
2
]))
&&
!
zstr
(
auth
))
{
if
(
argc
>=
3
&&
(
auth
=
amf0_get_string
(
argv
[
2
]))
&&
!
zstr
(
auth
))
{
switch_split_user_domain
(
auth
,
&
user
,
&
domain
);
if
(
rtmp_session_check_user
(
rsession
,
user
,
domain
)
!=
SWITCH_STATUS_SUCCESS
)
{
switch_log_printf
(
SWITCH_CHANNEL_UUID_LOG
(
rsession
->
uuid
),
SWITCH_LOG_WARNING
,
"Unauthorized call to %s, client is not logged in account [%s@%s]
\n
"
,
...
...
@@ -327,6 +327,33 @@ RTMP_INVOKE_FUNCTION(rtmp_i_makeCall)
return
SWITCH_STATUS_SUCCESS
;
}
RTMP_INVOKE_FUNCTION
(
rtmp_i_fcSubscribe
)
{
switch_status_t
status
;
int
ac
;
amf0_data
*
av
[
3
]
=
{
0
};
switch_log_printf
(
SWITCH_CHANNEL_UUID_LOG
(
rsession
->
uuid
),
SWITCH_LOG_DEBUG
,
"Got FCSubscribe for %s on stream %d
\n
"
,
switch_str_nil
(
amf0_get_string
(
argv
[
1
])),
state
->
stream_id
);
ac
=
3
;
av
[
0
]
=
argv
[
0
];
av
[
1
]
=
argv
[
1
];
av
[
2
]
=
amf0_boolean_new
(
1
);
switch_assert
(
av
[
2
]);
status
=
rtmp_i_receiveaudio
(
rsession
,
state
,
amfnumber
,
transaction_id
,
ac
,
av
);
if
(
status
!=
SWITCH_STATUS_SUCCESS
)
return
status
;
rtmp_i_receivevideo
(
rsession
,
state
,
amfnumber
,
transaction_id
,
ac
,
av
);
if
(
status
!=
SWITCH_STATUS_SUCCESS
)
return
status
;
amf0_data_free
(
av
[
2
]);
rtmp_i_makeCall
(
rsession
,
state
,
amfnumber
,
transaction_id
,
argc
,
argv
);
return
status
;
}
RTMP_INVOKE_FUNCTION
(
rtmp_i_sendDTMF
)
{
/* Send DTMFs on the active channel */
...
...
src/mod/endpoints/mod_rtmp/rtmp_tcp.c
浏览文件 @
0c819da6
...
...
@@ -49,34 +49,10 @@ typedef struct rtmp_io_tcp rtmp_io_tcp_t;
struct
rtmp_tcp_io_private
{
switch_pollfd_t
*
pollfd
;
switch_socket_t
*
socket
;
switch_buffer_t
*
sendq
;
switch_bool_t
poll_send
;
};
typedef
struct
rtmp_tcp_io_private
rtmp_tcp_io_private_t
;
static
void
rtmp_tcp_alter_pollfd
(
rtmp_session_t
*
rsession
,
switch_bool_t
pollout
)
{
rtmp_tcp_io_private_t
*
io_pvt
=
rsession
->
io_private
;
rtmp_io_tcp_t
*
io
=
(
rtmp_io_tcp_t
*
)
rsession
->
profile
->
io
;
if
(
pollout
&&
(
io_pvt
->
pollfd
->
reqevents
&
SWITCH_POLLOUT
))
{
return
;
}
else
if
(
!
pollout
&&
!
(
io_pvt
->
pollfd
->
reqevents
&
SWITCH_POLLOUT
))
{
return
;
}
switch_pollset_remove
(
io
->
pollset
,
io_pvt
->
pollfd
);
io_pvt
->
pollfd
->
reqevents
=
SWITCH_POLLIN
|
SWITCH_POLLERR
;
if
(
pollout
)
{
io_pvt
->
pollfd
->
reqevents
|=
SWITCH_POLLOUT
;
}
switch_log_printf
(
SWITCH_CHANNEL_UUID_LOG
(
rsession
->
uuid
),
SWITCH_LOG_NOTICE
,
"Pollout: %s
\n
"
,
pollout
?
"true"
:
"false"
);
switch_pollset_add
(
io
->
pollset
,
io_pvt
->
pollfd
);
}
static
switch_status_t
rtmp_tcp_read
(
rtmp_session_t
*
rsession
,
unsigned
char
*
buf
,
switch_size_t
*
len
)
{
//rtmp_io_tcp_t *io = (rtmp_io_tcp_t*)rsession->profile->io;
...
...
@@ -117,8 +93,10 @@ static switch_status_t rtmp_tcp_write(rtmp_session_t *rsession, const unsigned c
{
//rtmp_io_tcp_t *io = (rtmp_io_tcp_t*)rsession->profile->io;
rtmp_tcp_io_private_t
*
io_pvt
=
rsession
->
io_private
;
switch_status_t
status
;
switch_status_t
status
=
SWITCH_STATUS_SUCCESS
;
switch_size_t
orig_len
=
*
len
;
switch_size_t
remaining
=
*
len
;
int
sanity
=
100
;
#ifdef RTMP_DEBUG_IO
{
...
...
@@ -139,29 +117,32 @@ static switch_status_t rtmp_tcp_write(rtmp_session_t *rsession, const unsigned c
}
#endif
if
(
io_pvt
->
sendq
&&
switch_buffer_inuse
(
io_pvt
->
sendq
)
>
0
)
{
/* We already have queued data, append it to the sendq */
switch_buffer_write
(
io_pvt
->
sendq
,
buf
,
*
len
);
return
SWITCH_STATUS_SUCCESS
;
}
status
=
switch_socket_send_nonblock
(
io_pvt
->
socket
,
(
char
*
)
buf
,
len
);
if
(
*
len
>
0
&&
*
len
<
orig_len
)
{
while
(
remaining
>
0
)
{
if
(
rsession
->
state
>=
RS_DESTROY
)
{
return
SWITCH_STATUS_FALSE
;
}
/* We didnt send it all... add it to the sendq*/
s
witch_log_printf
(
SWITCH_CHANNEL_UUID_LOG
(
rsession
->
uuid
),
SWITCH_LOG_DEBUG
,
"%"
SWITCH_SIZE_T_FMT
" bytes added to sendq.
\n
"
,
(
orig_len
-
*
len
)
);
again:
s
tatus
=
switch_socket_send_nonblock
(
io_pvt
->
socket
,
(
char
*
)
buf
,
len
);
switch_buffer_write
(
io_pvt
->
sendq
,
(
buf
+
*
len
),
orig_len
-
*
len
);
if
((
status
==
32
||
SWITCH_STATUS_IS_BREAK
(
status
))
&&
sanity
--
>
0
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_WARNING
,
"sending too fast, retrying %d
\n
"
,
sanity
);
goto
again
;
}
if
(
status
!=
SWITCH_STATUS_SUCCESS
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"send error %d
\n
"
,
status
);
break
;
}
/* Make sure we poll-write */
rtmp_tcp_alter_pollfd
(
rsession
,
SWITCH_TRUE
);
if
(
*
len
!=
orig_len
)
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_INFO
,
"sent %ld of %ld
\n
"
,
*
len
,
orig_len
);
buf
+=
*
len
;
remaining
-=
*
len
;
*
len
=
remaining
;
}
*
len
=
orig_len
;
return
status
;
}
...
...
@@ -178,11 +159,6 @@ static switch_status_t rtmp_tcp_close(rtmp_session_t *rsession)
switch_socket_close
(
io_pvt
->
socket
);
io_pvt
->
socket
=
NULL
;
}
if
(
io_pvt
->
sendq
)
{
switch_buffer_destroy
(
&
(
io_pvt
->
sendq
));
}
return
SWITCH_STATUS_SUCCESS
;
}
...
...
@@ -246,7 +222,6 @@ void *SWITCH_THREAD_FUNC rtmp_io_tcp_thread(switch_thread_t *thread, void *obj)
pvt
->
socket
=
newsocket
;
switch_socket_create_pollfd
(
&
pvt
->
pollfd
,
newsocket
,
SWITCH_POLLIN
|
SWITCH_POLLERR
,
rsession
,
rsession
->
pool
);
switch_pollset_add
(
io
->
pollset
,
pvt
->
pollfd
);
switch_buffer_create_dynamic
(
&
pvt
->
sendq
,
512
,
1024
,
0
);
/* Get the remote address/port info */
switch_socket_addr_get
(
&
addr
,
SWITCH_TRUE
,
newsocket
);
...
...
@@ -261,18 +236,7 @@ void *SWITCH_THREAD_FUNC rtmp_io_tcp_thread(switch_thread_t *thread, void *obj)
rtmp_session_t
*
rsession
=
(
rtmp_session_t
*
)
fds
[
i
].
client_data
;
rtmp_tcp_io_private_t
*
io_pvt
=
(
rtmp_tcp_io_private_t
*
)
rsession
->
io_private
;
if
(
fds
[
i
].
rtnevents
&
SWITCH_POLLOUT
&&
switch_buffer_inuse
(
io_pvt
->
sendq
)
>
0
)
{
/* Send as much remaining data as possible */
switch_size_t
sendlen
;
const
void
*
ptr
;
sendlen
=
switch_buffer_peek_zerocopy
(
io_pvt
->
sendq
,
&
ptr
);
switch_socket_send_nonblock
(
io_pvt
->
socket
,
ptr
,
&
sendlen
);
switch_buffer_toss
(
io_pvt
->
sendq
,
sendlen
);
if
(
switch_buffer_inuse
(
io_pvt
->
sendq
)
==
0
)
{
/* Remove our fd from OUT polling */
rtmp_tcp_alter_pollfd
(
rsession
,
SWITCH_FALSE
);
}
}
else
if
(
fds
[
i
].
rtnevents
&
SWITCH_POLLIN
&&
rtmp_handle_data
(
rsession
)
!=
SWITCH_STATUS_SUCCESS
)
{
if
(
fds
[
i
].
rtnevents
&
SWITCH_POLLIN
&&
rtmp_handle_data
(
rsession
)
!=
SWITCH_STATUS_SUCCESS
)
{
switch_log_printf
(
SWITCH_CHANNEL_UUID_LOG
(
rsession
->
uuid
),
SWITCH_LOG_DEBUG
,
"Closing socket
\n
"
);
switch_mutex_lock
(
io
->
mutex
);
...
...
src/mod/endpoints/mod_rtmp/rtmp_video.c
0 → 100644
浏览文件 @
0c819da6
差异被折叠。
点击展开。
src/mod/endpoints/mod_rtmp/rtmp_video.h
0 → 100644
浏览文件 @
0c819da6
/*
* mod_rtmp for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2015, Seven Du.
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is rtmp_video for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is Seven Du
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Seven Du <dujinfang@gmail.com>
* Da Xiong <wavecb@gmail.com>
*
* rtmp_video.h -- RTMP video
*
*/
#include "amf0.h"
#include "mod_rtmp.h"
#define MAX_RTP_PAYLOAD_SIZE 1400
void
rtmp2rtp_helper_init
(
rtmp2rtp_helper_t
*
helper
);
void
rtp2rtmp_helper_init
(
rtp2rtmp_helper_t
*
helper
);
void
rtmp2rtp_helper_destroy
(
rtmp2rtp_helper_t
*
helper
);
void
rtp2rtmp_helper_destroy
(
rtp2rtmp_helper_t
*
helper
);
switch_status_t
on_rtmp_tech_init
(
switch_core_session_t
*
session
,
rtmp_private_t
*
tech_pvt
);
switch_status_t
on_rtmp_destroy
(
rtmp_private_t
*
tech_pvt
);
/*Rtmp packet to rtp frame*/
switch_status_t
rtmp_rtmp2rtpH264
(
rtmp2rtp_helper_t
*
read_helper
,
uint8_t
*
data
,
uint32_t
len
);
switch_status_t
rtmp_rtp2rtmpH264
(
rtp2rtmp_helper_t
*
helper
,
switch_frame_t
*
frame
);
switch_status_t
rtmp_write_video_frame
(
switch_core_session_t
*
session
,
switch_frame_t
*
frame
,
switch_io_flag_t
flags
,
int
stream_id
);
switch_status_t
rtmp_read_video_frame
(
switch_core_session_t
*
session
,
switch_frame_t
**
frame
,
switch_io_flag_t
flags
,
int
stream_id
);
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论