Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
a769d6c2
Commit
a769d6c2
authored
Aug 09, 2017
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
初步完成Windows下的移植
parent
a8b7d53f
隐藏空白字符变更
内嵌
并排
正在显示
42 个修改的文件
包含
160 行增加
和
121 行删除
+160
-121
CMakeLists.txt
+22
-14
cmake/FindMYSQL.cmake
+2
-1
cmake/FindZLTOOLKIT.cmake
+4
-2
src/Codec/H264Encoder.cpp
+9
-9
src/Common/config.cpp
+11
-0
src/Device/Device.h
+0
-1
src/H264/SPSParser.c
+0
-2
src/H264/h264_parser.cpp
+2
-2
src/H264/h264_poc.cpp
+2
-2
src/Http/HttpClient.cpp
+1
-1
src/Http/HttpSession.cpp
+4
-5
src/MediaFile/HLSMaker.cpp
+5
-2
src/MediaFile/MediaReader.cpp
+2
-2
src/MediaFile/TSMaker.cpp
+0
-1
src/RTP/RtpMakerAAC.cpp
+0
-1
src/RTP/RtpMakerH264.cpp
+0
-1
src/Rtmp/Rtmp.h
+15
-1
src/Rtmp/RtmpMediaSource.h
+0
-1
src/Rtmp/RtmpParser.cpp
+4
-4
src/Rtmp/RtmpPlayer.cpp
+4
-4
src/Rtmp/RtmpPlayer.h
+0
-1
src/Rtmp/RtmpProtocol.cpp
+19
-4
src/Rtmp/RtmpProtocol.h
+0
-1
src/Rtmp/RtmpPusher.cpp
+6
-6
src/Rtmp/RtmpSession.h
+0
-1
src/Rtmp/amf.cpp
+0
-1
src/Rtmp/utils.cpp
+3
-1
src/Rtsp/RtpBroadCaster.cpp
+1
-2
src/Rtsp/RtpBroadCaster.h
+1
-2
src/Rtsp/RtpParser.cpp
+3
-3
src/Rtsp/RtspPlayer.cpp
+5
-7
src/Rtsp/RtspPlayer.h
+1
-2
src/Rtsp/RtspSession.cpp
+2
-3
src/Rtsp/RtspSession.h
+0
-1
src/Rtsp/RtspToRtmpMediaSource.cpp
+0
-6
src/Rtsp/UDPServer.cpp
+1
-1
src/Shell/CMD.h
+1
-2
tests/CMakeLists.txt
+5
-3
tests/test_benchmark.cpp
+3
-4
tests/test_httpClient.cpp
+0
-1
tests/test_rtmpPusher.cpp
+3
-4
tests/test_server.cpp
+19
-9
没有找到文件。
CMakeLists.txt
查看文件 @
a769d6c2
...
...
@@ -8,20 +8,31 @@ set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
#设置可执行程序路径
set
(
EXECUTABLE_OUTPUT_PATH
${
PROJECT_BINARY_DIR
}
/bin
)
#设置子目录
set
(
SUB_DIR_LIST
"Codec"
"Common"
"Device"
"H264"
"Http"
"MediaFile"
"Player"
"Rtmp"
"RTP"
"Rtsp"
"Shell"
)
set
(
SUB_DIR_LIST
"Codec"
"Common"
"Device"
"H264"
"Http"
"MediaFile"
"Player"
"Rtmp"
"RTP"
"Rtsp"
)
if
(
NOT WIN32
)
list
(
APPEND SUB_DIR_LIST
"Shell"
)
endif
()
#使能GOP缓存
add_definitions
(
-DENABLE_RING_USEBUF
)
#安装目录
if
(
WIN32
)
set
(
INSTALL_PATH_LIB $ENV{HOME}/
${
CMAKE_PROJECT_NAME
}
/lib
)
set
(
INSTALL_PATH_INCLUDE $ENV{HOME}/
${
CMAKE_PROJECT_NAME
}
/include
)
else
()
set
(
INSTALL_PATH_LIB lib
)
set
(
INSTALL_PATH_INCLUDE include
)
endif
()
foreach
(
SUB_DIR
${
SUB_DIR_LIST
}
)
#遍历源文件
aux_source_directory
(
src/
${
SUB_DIR
}
SRC_LIST
)
#创建头文件安装文件夹
execute_process
(
COMMAND mkdir -p
${
PROJECT_BINARY_DIR
}
/include/
${
CMAKE_PROJECT_NAME
}
/
${
SUB_DIR
}
/
)
#遍历头文件
file
(
GLOB_RECURSE HEADER_FILES
"
${
PROJECT_SOURCE_DIR
}
/src/
${
SUB_DIR
}
/*.h"
)
#拷贝头文件至安装文件夹
execute_process
(
COMMAND cp
${
HEADER_FILES
}
${
PROJECT_BINARY_DIR
}
/include/
${
CMAKE_PROJECT_NAME
}
/
${
SUB_DIR
}
/
)
#安装头文件至系统目录
install
(
DIRECTORY src/
${
SUB_DIR
}
DESTINATION
${
INSTALL_PATH_INCLUDE
}
/
${
CMAKE_PROJECT_NAME
}
FILES_MATCHING PATTERN
"*.h"
)
endforeach
(
SUB_DIR
${
SUB_DIR_LIST
}
)
set
(
LINK_LIB_LIST
)
...
...
@@ -91,32 +102,29 @@ include_directories(${PROJECT_SOURCE_DIR}/src)
#使能c++11
set
(
CMAKE_CXX_FLAGS
"-std=c++11
${
CMAKE_CXX_FLAGS
}
"
)
if
(
NOT WIN32
)
#关闭过期接口警告
add_compile_options
(
-Wno-deprecated-declarations
)
#关闭__FUNCTION__宏在函数外警告
add_compile_options
(
-Wno-predefined-identifier-outside-function
)
endif
(
NOT WIN32
)
#编译动态库
if
(
NOT IOS AND NOT ANDROID
)
add_library
(
${
CMAKE_PROJECT_NAME
}
_shared SHARED
${
SRC_LIST
}
)
set_target_properties
(
${
CMAKE_PROJECT_NAME
}
_shared PROPERTIES OUTPUT_NAME
"
${
CMAKE_PROJECT_NAME
}
"
)
install
(
TARGETS
${
CMAKE_PROJECT_NAME
}
_shared
LIBRARY DESTINATION lib
)
install
(
TARGETS
${
CMAKE_PROJECT_NAME
}
_shared
ARCHIVE DESTINATION
${
INSTALL_PATH_LIB
}
LIBRARY DESTINATION
${
INSTALL_PATH_LIB
}
)
target_link_libraries
(
${
CMAKE_PROJECT_NAME
}
_shared
${
LINK_LIB_LIST
}
)
endif
()
#编译静态库
add_library
(
${
CMAKE_PROJECT_NAME
}
_static STATIC
${
SRC_LIST
}
)
set_target_properties
(
${
CMAKE_PROJECT_NAME
}
_static PROPERTIES OUTPUT_NAME
"
${
CMAKE_PROJECT_NAME
}
"
)
install
(
TARGETS
${
CMAKE_PROJECT_NAME
}
_static ARCHIVE DESTINATION lib
)
#安装头文件至系统目录
install
(
DIRECTORY
${
PROJECT_BINARY_DIR
}
/include/
${
CMAKE_PROJECT_NAME
}
DESTINATION include
)
install
(
TARGETS
${
CMAKE_PROJECT_NAME
}
_static ARCHIVE DESTINATION
${
INSTALL_PATH_LIB
}
)
#测试程序
if
(
NOT IOS
)
add_subdirectory
(
tests
)
else
(
NOT IOS
)
include_directories
(
${
PROJECT_SOURCE_DIR
}
/../ZLToolKit/src
)
endif
(
NOT IOS
)
...
...
cmake/FindMYSQL.cmake
查看文件 @
a769d6c2
...
...
@@ -17,7 +17,7 @@
include
(
CheckCXXSourceCompiles
)
if
(
WIN32
)
find_path
(
MYSQL_INCLUDE_DIR mysql
/mysql
.h
find_path
(
MYSQL_INCLUDE_DIR mysql.h
PATHS
$ENV{MYSQL_INCLUDE_DIR}
$ENV{MYSQL_DIR}/include
...
...
@@ -64,6 +64,7 @@ if(WIN32)
$ENV{MYSQL_DIR}/lib/opt
$ENV{MYSQL_DIR}/client/release
$ENV{ProgramFiles}/MySQL/*/lib/opt
$ENV{ProgramFiles}/MySQL/*/lib/
$ENV{SystemDrive}/MySQL/*/lib/opt
$ENV{ProgramW6432}/MySQL/*/lib
)
...
...
cmake/FindZLTOOLKIT.cmake
查看文件 @
a769d6c2
find_path
(
ZLTOOLKIT_INCLUDE_DIR
NAMES ZLToolKit/Network/Socket.h
)
NAMES ZLToolKit/Network/Socket.h
PATHS $ENV{HOME}/ZLToolKit/include
)
find_library
(
ZLTOOLKIT_LIBRARY
NAMES ZLToolKit
)
NAMES ZLToolKit
PATHS $ENV{HOME}/ZLToolKit/lib
)
set
(
ZLTOOLKIT_LIBRARIES
${
ZLTOOLKIT_LIBRARY
}
)
set
(
ZLTOOLKIT_INCLUDE_DIRS
${
ZLTOOLKIT_INCLUDE_DIR
}
)
...
...
src/Codec/H264Encoder.cpp
查看文件 @
a769d6c2
...
...
@@ -57,20 +57,20 @@ Vui参数集视频可用性信息视频标准化选项
int i_sar_height;
int i_sar_width; 设置长宽比
int i_overscan; 0=undef, 1=no overscan, 2=overscan 过扫描线,默认"undef"(不设置),可选项
:
show(观看)/crop(去除)
int i_overscan; 0=undef, 1=no overscan, 2=overscan 过扫描线,默认"undef"(不设置),可选项
:
show(观看)/crop(去除)
见以下的值h264附件E
Int i_vidformat; 视频格式,默认"undef",component/pal/ntsc/secam/mac/undef
int b_fullrange; Specify full range samples setting,默认"off",可选项
:
off/on
int i_colorprim; 原始色度格式,默认"undef",可选项
:
undef/bt709/bt470m/bt470bg,smpte170m/smpte240m/film
int i_transfer; 转换方式,默认"undef",可选项
:
undef/bt709/bt470m/bt470bg/linear,log100/log316/smpte170m/smpte240m
int b_fullrange; Specify full range samples setting,默认"off",可选项
:
off/on
int i_colorprim; 原始色度格式,默认"undef",可选项
:
undef/bt709/bt470m/bt470bg,smpte170m/smpte240m/film
int i_transfer; 转换方式,默认"undef",可选项
:
undef/bt709/bt470m/bt470bg/linear,log100/log316/smpte170m/smpte240m
int i_colmatrix; 色度矩阵设置,默认"undef",undef/bt709/fcc/bt470bg,smpte170m/smpte240m/GBR/YCgCo
int i_chroma_loc; both top & bottom色度样本指定,范围0~5,默认0
} vui;
int i_fps_num;
int i_fps_den;
这两个参数是由fps帧率确定的,赋值的过程见下
:
这两个参数是由fps帧率确定的,赋值的过程见下
:
{ float fps;
if( sscanf( value, "%d/%d", &p->i_fps_num, &p->i_fps_den ) == 2 )
;
...
...
@@ -137,7 +137,7 @@ Value的值就是fps。
int i_subpel_refine; 亚像素运动估计质量
int b_chroma_me; 亚像素色度运动估计和P帧的模式选择
int b_mixed_references; 允许每个宏块的分区在P帧有它自己的参考号
int i_trellis; Trellis量化,对每个8x8的块寻找合适的量化值,需要CABAC,默认0 0
:关闭1:只在最后编码时使用2:
一直使用
int i_trellis; Trellis量化,对每个8x8的块寻找合适的量化值,需要CABAC,默认0 0
:关闭1:只在最后编码时使用2:
一直使用
int b_fast_pskip; 快速P帧跳过检测
int b_dct_decimate; 在P-frames转换参数域
int i_noise_reduction; 自适应伪盲区
...
...
@@ -249,13 +249,13 @@ bool H264Encoder::init(int iWidth, int iHeight, int iFps) {
这个GOP就称为open-GOP。
有些解码器不能完全支持open-GOP码流,
例如蓝光解码器,因此在x264里面open-GOP是默认关闭的。
对于解码端,接收到的码流如果如下
:
I0 B0 B1 P0 B2 B3...这就是一个open-GOP码流(I帧后面紧跟B帧)。
对于解码端,接收到的码流如果如下
:
I0 B0 B1 P0 B2 B3...这就是一个open-GOP码流(I帧后面紧跟B帧)。
因此B0 B1的解码需要用到I0前面一个GOP的数据,B0 B1的dts是小于I0的。
如果码流如下
:
I0 P0 B0 B1 P1 B2 B3...这就是一个close-GOP码流,
如果码流如下
:
I0 P0 B0 B1 P1 B2 B3...这就是一个close-GOP码流,
I0后面所有帧的解码不依赖于I0前面的帧,I0后面所有帧的dts都比I0的大。
如果码流是IDR0 B0 B1 P0 B2 B3...那个这个GOP是close-GOP,B0,B1虽然dst比IDR0小,
但编解码端都刷新了参考缓冲,B0,B1参考不到前向GOP帧。
对于编码端,如果编码帧类型决定如下
:
...P0 B1 B2 P3 B4 B5 I6这就会输出open-Gop码流 (P0 P3 B1 B2 I6 B4 B5...),
对于编码端,如果编码帧类型决定如下
:
...P0 B1 B2 P3 B4 B5 I6这就会输出open-Gop码流 (P0 P3 B1 B2 I6 B4 B5...),
B4 B5的解码依赖P3。
如果编码帧类型决定如下...P0 B1 B2 P3 B4 P5 I6这样就不会输出open-GOP码流(P0 P3 B1 B2 P5 B4 I6...)。
两者区别在于I6前面的第5帧是设置为B帧还是P帧,
...
...
src/Common/config.cpp
查看文件 @
a769d6c2
...
...
@@ -9,6 +9,17 @@
using
namespace
ZL
::
Network
;
#if defined(_WIN32)
static
onceToken
g_token
([]()
{
WORD
wVersionRequested
=
MAKEWORD
(
2
,
2
);
WSADATA
wsaData
;
WSAStartup
(
wVersionRequested
,
&
wsaData
);
},
[]()
{
WSACleanup
();
});
#endif // defined(_WIN32)
namespace
Config
{
void
loaIniConfig
(){
...
...
src/Device/Device.h
查看文件 @
a769d6c2
...
...
@@ -8,7 +8,6 @@
#ifndef DEVICE_DEVICE_H_
#define DEVICE_DEVICE_H_
#include <sys/time.h>
#include <memory>
#include <string>
#include <functional>
...
...
src/H264/SPSParser.c
查看文件 @
a769d6c2
...
...
@@ -2,8 +2,6 @@
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
/* for uint32_t, etc */
#include <pthread.h>
#include "SPSParser.h"
/********************************************
...
...
src/H264/h264_parser.cpp
查看文件 @
a769d6c2
...
...
@@ -173,7 +173,7 @@ return kInvalidStream; \
start
+=
subsamples
[
i
].
clear_bytes
;
const
uint8_t
*
end
=
std
::
min
(
start
+
subsamples
[
i
].
cypher_bytes
,
stream_end
);
min
(
start
+
subsamples
[
i
].
cypher_bytes
,
stream_end
);
encrypted_ranges_
.
Add
(
start
,
end
);
start
=
end
;
}
...
...
@@ -311,7 +311,7 @@ return kInvalidStream; \
// The start code is inside an encrypted section so we need to scan
// for another start code.
*
start_code_size
=
0
;
start
+=
std
::
min
(
*
offset
+
1
,
bytes_left
);
start
+=
min
(
*
offset
+
1
,
bytes_left
);
}
}
while
(
*
start_code_size
==
0
);
...
...
src/H264/h264_poc.cpp
查看文件 @
a769d6c2
...
...
@@ -113,7 +113,7 @@ namespace media {
// (assuming no interlacing).
int32_t
top_foc
=
pic_order_cnt_msb
+
slice_hdr
.
pic_order_cnt_lsb
;
int32_t
bottom_foc
=
top_foc
+
slice_hdr
.
delta_pic_order_cnt_bottom
;
*
pic_order_cnt
=
std
::
min
(
top_foc
,
bottom_foc
);
*
pic_order_cnt
=
min
(
top_foc
,
bottom_foc
);
// Store state.
prev_frame_num_
=
slice_hdr
.
frame_num
;
...
...
@@ -182,7 +182,7 @@ namespace media {
int32_t
top_foc
=
expected_pic_order_cnt
+
slice_hdr
.
delta_pic_order_cnt0
;
int32_t
bottom_foc
=
top_foc
+
sps
->
offset_for_top_to_bottom_field
+
slice_hdr
.
delta_pic_order_cnt1
;
*
pic_order_cnt
=
std
::
min
(
top_foc
,
bottom_foc
);
*
pic_order_cnt
=
min
(
top_foc
,
bottom_foc
);
// Store state.
prev_frame_num_
=
slice_hdr
.
frame_num
;
...
...
src/Http/HttpClient.cpp
查看文件 @
a769d6c2
...
...
@@ -27,7 +27,7 @@ void HttpClient::sendRequest(const string &strUrl){
defaultPort
=
443
;
isHttps
=
true
;
}
else
{
auto
strErr
=
StrPrinter
<<
"非法的协议
:
"
<<
protocol
<<
endl
;
auto
strErr
=
StrPrinter
<<
"非法的协议
:
"
<<
protocol
<<
endl
;
throw
std
::
invalid_argument
(
strErr
);
}
...
...
src/Http/HttpSession.cpp
查看文件 @
a769d6c2
...
...
@@ -8,7 +8,6 @@
#include <stdio.h>
#include <sys/stat.h>
#include <algorithm>
#include <dirent.h>
#include "Common/config.h"
#include "strCoding.h"
...
...
@@ -146,7 +145,7 @@ void HttpSession::onManager() {
static
uint32_t
keepAliveSec
=
mINI
::
Instance
()[
Config
::
Http
::
kKeepAliveSecond
].
as
<
uint32_t
>
();
if
(
m_ticker
.
elapsedTime
()
>
keepAliveSec
*
1000
){
//1分钟超时
WarnL
<<
"HttpSession
超时断开!
"
;
WarnL
<<
"HttpSession
timeouted!
"
;
shutdown
();
}
}
...
...
@@ -226,7 +225,7 @@ inline HttpSession::HttpCode HttpSession::Handle_Req_GET() {
int64_t
iReq
=
MIN
(
sendBufSize
,
*
piLeft
);
int64_t
iRead
=
fread
(
pacSendBuf
.
get
(),
1
,
iReq
,
pFilePtr
.
get
());
*
piLeft
-=
iRead
;
//InfoL << "Send file
:
" << iReq << " " << *piLeft;
//InfoL << "Send file
:
" << iReq << " " << *piLeft;
if
(
iRead
<
iReq
||
!*
piLeft
)
{
//send completed!
//FatalL << "send completed!";
...
...
@@ -280,13 +279,13 @@ inline bool HttpSession::makeMeun(const string &strFullPath, string &strRet) {
strRet
+=
"<li><a href=
\"
"
;
strRet
+=
"/"
;
strRet
+=
"
\"
>"
;
strRet
+=
"
根目录
"
;
strRet
+=
"
root directory
"
;
strRet
+=
"</a></li>
\r\n
"
;
strRet
+=
"<li><a href=
\"
"
;
strRet
+=
"../"
;
strRet
+=
"
\"
>"
;
strRet
+=
"
上一级目录
"
;
strRet
+=
"
parent directory
"
;
strRet
+=
"</a></li>
\r\n
"
;
}
...
...
src/MediaFile/HLSMaker.cpp
查看文件 @
a769d6c2
...
...
@@ -6,7 +6,10 @@
*/
#include "HLSMaker.h"
#include <sys/time.h>
#include "Util/File.h"
#include "Util/uv_errno.h"
using
namespace
ZL
::
Util
;
namespace
ZL
{
namespace
MediaFile
{
...
...
@@ -126,7 +129,7 @@ void HLSMaker::inputH264(void *data, uint32_t length, uint32_t timeStamp,
m_Timer
.
resetTime
();
removets
();
if
(
write_index_file
(
m_ui64TsCnt
-
m_ui32NumSegments
,
m_ui64TsCnt
,
0
)
==
-
1
)
{
WarnL
<<
"write_index_file error :"
<<
strerror
(
errno
);
WarnL
<<
"write_index_file error :"
<<
get_uv_errmsg
(
);
}
}
case
1
:
//P
...
...
src/MediaFile/MediaReader.cpp
查看文件 @
a769d6c2
...
...
@@ -23,7 +23,7 @@ MediaReader::MediaReader(const string &strApp, const string &strId) {
m_hMP4File
=
MP4Read
(
strFileName
.
data
());
if
(
m_hMP4File
==
MP4_INVALID_FILE_HANDLE
){
throw
runtime_error
(
StrPrinter
<<
"打开MP4文件失败
:
"
<<
strFileName
<<
endl
);
throw
runtime_error
(
StrPrinter
<<
"打开MP4文件失败
:
"
<<
strFileName
<<
endl
);
}
m_video_trId
=
MP4FindTrackId
(
m_hMP4File
,
0
,
MP4_VIDEO_TRACK_TYPE
,
0
);
if
(
m_video_trId
!=
MP4_INVALID_TRACK_ID
){
...
...
@@ -106,7 +106,7 @@ MediaReader::MediaReader(const string &strApp, const string &strId) {
if
(
m_audio_trId
==
MP4_INVALID_TRACK_ID
&&
m_video_trId
==
MP4_INVALID_TRACK_ID
){
MP4Close
(
m_hMP4File
);
m_hMP4File
=
MP4_INVALID_FILE_HANDLE
;
throw
runtime_error
(
StrPrinter
<<
"该MP4文件音视频格式不支持
:
"
<<
strFileName
<<
endl
);
throw
runtime_error
(
StrPrinter
<<
"该MP4文件音视频格式不支持
:
"
<<
strFileName
<<
endl
);
}
m_iDuration
=
MAX
(
m_video_ms
,
m_audio_ms
);
...
...
src/MediaFile/TSMaker.cpp
查看文件 @
a769d6c2
...
...
@@ -6,7 +6,6 @@
*/
#include "TSMaker.h"
#include <sys/time.h>
#include "Util/logger.h"
using
namespace
ZL
::
Util
;
...
...
src/RTP/RtpMakerAAC.cpp
查看文件 @
a769d6c2
...
...
@@ -5,7 +5,6 @@
* Author: xzl
*/
#include <netinet/in.h>
#include "Common/config.h"
#include "RtpMakerAAC.h"
#include "Util/mini.h"
...
...
src/RTP/RtpMakerH264.cpp
查看文件 @
a769d6c2
...
...
@@ -5,7 +5,6 @@
* Author: xzl
*/
#include <netinet/in.h>
#include "Common/config.h"
#include "RtpMakerH264.h"
#include "Util/mini.h"
...
...
src/Rtmp/Rtmp.h
查看文件 @
a769d6c2
#ifndef __rtmp_h
#define __rtmp_h
#include <netinet/in.h>
#include <memory>
#include <string>
#include "Util/util.h"
...
...
@@ -12,7 +11,14 @@ using namespace ZL::Util;
#define PORT 1935
#define DEFAULT_CHUNK_LEN 128
#if !defined(_WIN32)
#define PACKED __attribute__((packed))
#else
#define PACKED
#endif //!defined(_WIN32)
#define HANDSHAKE_PLAINTEXT 0x03
#define RANDOM_LEN (1536 - 8)
...
...
@@ -52,6 +58,11 @@ using namespace ZL::Util;
#define FLV_KEY_FRAME 1
#define FLV_INTER_FRAME 2
#if defined(_WIN32)
#pragma pack(push, 1)
#endif // defined(_WIN32)
class
RtmpHandshake
{
public
:
RtmpHandshake
(
uint32_t
_time
,
uint8_t
*
_random
=
nullptr
)
{
...
...
@@ -87,6 +98,9 @@ public:
uint8_t
streamId
[
4
];
/* Note, this is little-endian while others are BE */
}
PACKED
;
#if defined(_WIN32)
#pragma pack(pop)
#endif // defined(_WIN32)
class
RtmpPacket
{
public
:
...
...
src/Rtmp/RtmpMediaSource.h
查看文件 @
a769d6c2
...
...
@@ -8,7 +8,6 @@
#ifndef SRC_RTMP_RTMPMEDIASOURCE_H_
#define SRC_RTMP_RTMPMEDIASOURCE_H_
#include <netinet/in.h>
#include <mutex>
#include <memory>
#include <string>
...
...
src/Rtmp/RtmpParser.cpp
查看文件 @
a769d6c2
...
...
@@ -19,14 +19,14 @@ RtmpParser::RtmpParser(const AMFValue &val) {
//264
m_bHaveVideo
=
true
;
}
else
{
InfoL
<<
"不支持RTMP视频格式
:
"
<<
videoCodec
.
as_string
();
InfoL
<<
"不支持RTMP视频格式
:
"
<<
videoCodec
.
as_string
();
}
}
else
if
(
videoCodec
.
type
()
!=
AMF_NULL
){
if
(
videoCodec
.
as_integer
()
==
7
)
{
//264
m_bHaveVideo
=
true
;
}
else
{
InfoL
<<
"不支持RTMP视频格式
:
"
<<
videoCodec
.
as_integer
();
InfoL
<<
"不支持RTMP视频格式
:
"
<<
videoCodec
.
as_integer
();
}
}
...
...
@@ -36,14 +36,14 @@ RtmpParser::RtmpParser(const AMFValue &val) {
//aac
m_bHaveAudio
=
true
;
}
else
{
InfoL
<<
"不支持RTMP音频格式
:
"
<<
audioCodec
.
as_string
();
InfoL
<<
"不支持RTMP音频格式
:
"
<<
audioCodec
.
as_string
();
}
}
else
if
(
audioCodec
.
type
()
!=
AMF_NULL
)
{
if
(
audioCodec
.
as_integer
()
==
10
)
{
//aac
m_bHaveAudio
=
true
;
}
else
{
InfoL
<<
"不支持RTMP音频格式
:
"
<<
audioCodec
.
as_integer
();
InfoL
<<
"不支持RTMP音频格式
:
"
<<
audioCodec
.
as_integer
();
}
}
...
...
src/Rtmp/RtmpPlayer.cpp
查看文件 @
a769d6c2
...
...
@@ -144,7 +144,7 @@ inline void RtmpPlayer::send_connect() {
auto
level
=
val
[
"level"
].
as_string
();
auto
code
=
val
[
"code"
].
as_string
();
if
(
level
!=
"status"
){
throw
std
::
runtime_error
(
StrPrinter
<<
"connect 失败
:
"
<<
level
<<
" "
<<
code
<<
endl
);
throw
std
::
runtime_error
(
StrPrinter
<<
"connect 失败
:
"
<<
level
<<
" "
<<
code
<<
endl
);
}
send_createStream
();
});
...
...
@@ -170,7 +170,7 @@ inline void RtmpPlayer::send_play() {
auto
level
=
val
[
"level"
].
as_string
();
auto
code
=
val
[
"code"
].
as_string
();
if
(
level
!=
"status"
){
throw
std
::
runtime_error
(
StrPrinter
<<
"play 失败
:
"
<<
level
<<
" "
<<
code
<<
endl
);
throw
std
::
runtime_error
(
StrPrinter
<<
"play 失败
:
"
<<
level
<<
" "
<<
code
<<
endl
);
}
};
addOnStatusCB
(
fun
);
...
...
@@ -187,7 +187,7 @@ inline void RtmpPlayer::send_pause(bool bPause) {
auto
code
=
val
[
"code"
].
as_string
();
if
(
level
!=
"status"
)
{
if
(
!
bPause
){
throw
std
::
runtime_error
(
StrPrinter
<<
"pause 恢复播放失败
:
"
<<
level
<<
" "
<<
code
<<
endl
);
throw
std
::
runtime_error
(
StrPrinter
<<
"pause 恢复播放失败
:
"
<<
level
<<
" "
<<
code
<<
endl
);
}
}
else
{
m_bPaused
=
bPause
;
...
...
@@ -236,7 +236,7 @@ void RtmpPlayer::onCmd_onStatus(AMFDecoder &dec) {
}
}
if
(
val
.
type
()
!=
AMF_OBJECT
){
throw
std
::
runtime_error
(
"onStatus:
未找到结果对象
"
);
throw
std
::
runtime_error
(
"onStatus:
the result object was not found
"
);
}
lock_guard
<
recursive_mutex
>
lck
(
m_mtxOnStatusCB
);
...
...
src/Rtmp/RtmpPlayer.h
查看文件 @
a769d6c2
...
...
@@ -8,7 +8,6 @@
#ifndef SRC_RTMP_RtmpPlayer2_H_
#define SRC_RTMP_RtmpPlayer2_H_
#include <netinet/in.h>
#include <memory>
#include <string>
#include <functional>
...
...
src/Rtmp/RtmpProtocol.cpp
查看文件 @
a769d6c2
...
...
@@ -14,17 +14,29 @@
using
namespace
ZL
::
Util
;
#ifdef ENABLE_OPENSSL
#include "Util/SSLBox.h"
#include <openssl/hmac.h>
static
string
openssl_HMACsha256
(
const
void
*
key
,
unsigned
int
key_len
,
const
void
*
data
,
unsigned
int
data_len
){
std
::
shared_ptr
<
char
>
out
(
new
char
[
32
],[](
char
*
ptr
){
delete
[]
ptr
;});
unsigned
int
out_len
;
#if defined(WIN32)
HMAC_CTX
*
ctx
=
HMAC_CTX_new
();
HMAC_CTX_reset
(
ctx
);
HMAC_Init_ex
(
ctx
,
key
,
key_len
,
EVP_sha256
(),
NULL
);
HMAC_Update
(
ctx
,
(
unsigned
char
*
)
data
,
data_len
);
HMAC_Final
(
ctx
,
(
unsigned
char
*
)
out
.
get
(),
&
out_len
);
HMAC_CTX_reset
(
ctx
);
HMAC_CTX_free
(
ctx
);
#else
HMAC_CTX
ctx
;
HMAC_CTX_init
(
&
ctx
);
HMAC_Init_ex
(
&
ctx
,
key
,
key_len
,
EVP_sha256
(),
NULL
);
HMAC_Update
(
&
ctx
,
(
unsigned
char
*
)
data
,
data_len
);
HMAC_Final
(
&
ctx
,
(
unsigned
char
*
)
out
.
get
(),
&
out_len
);
HMAC_CTX_cleanup
(
&
ctx
);
#endif // defined(WIN32)
return
string
(
out
.
get
(),
out_len
);
}
#endif //ENABLE_OPENSSL
...
...
@@ -159,7 +171,7 @@ void RtmpProtocol::sendRequest(int iCmd, const string& str) {
void
RtmpProtocol
::
sendRtmp
(
uint8_t
ui8Type
,
uint32_t
ui32StreamId
,
const
std
::
string
&
strBuf
,
uint32_t
ui32TimeStamp
,
int
iChunkId
)
{
if
(
iChunkId
<
2
||
iChunkId
>
63
)
{
auto
strErr
=
StrPrinter
<<
"不支持发送该类型的块流 ID
:
"
<<
iChunkId
<<
endl
;
auto
strErr
=
StrPrinter
<<
"不支持发送该类型的块流 ID
:
"
<<
iChunkId
<<
endl
;
throw
std
::
runtime_error
(
strErr
);
}
...
...
@@ -275,7 +287,7 @@ void RtmpProtocol::handle_C1_simple(){
}
#ifdef ENABLE_OPENSSL
void
RtmpProtocol
::
handle_C1_complex
(){
//参考自
:
http://blog.csdn.net/win_lin/article/details/13006803
//参考自
:
http://blog.csdn.net/win_lin/article/details/13006803
//skip c0,time,version
const
char
*
c1_start
=
m_strRcvBuf
.
data
()
+
1
;
const
char
*
schema_start
=
c1_start
+
8
;
...
...
@@ -318,6 +330,9 @@ void RtmpProtocol::handle_C1_complex(){
}
}
#if !defined(u_int8_t)
#define u_int8_t unsigned char
#endif // !defined(u_int8_t)
static
u_int8_t
FMSKey
[]
=
{
0x47
,
0x65
,
0x6e
,
0x75
,
0x69
,
0x6e
,
0x65
,
0x20
,
...
...
@@ -344,7 +359,7 @@ static u_int8_t FPKey[] = {
void
RtmpProtocol
::
check_C1_Digest
(
const
string
&
digest
,
const
string
&
data
){
auto
sha256
=
openssl_HMACsha256
(
FPKey
,
C1_FPKEY_SIZE
,
data
.
data
(),
data
.
size
());
if
(
sha256
!=
digest
){
throw
std
::
runtime_error
(
"digest
不匹配
"
);
throw
std
::
runtime_error
(
"digest
mismatched
"
);
}
else
{
InfoL
<<
"check rtmp complex handshark success!"
;
}
...
...
@@ -383,7 +398,7 @@ string RtmpProtocol::get_C1_key(const uint8_t *ptr){
return
key
;
}
void
RtmpProtocol
::
send_complex_S0S1S2
(
int
schemeType
,
const
string
&
digest
){
//S1S2计算参考自
:
https://github.com/hitYangfei/golang/blob/master/rtmpserver.go
//S1S2计算参考自
:
https://github.com/hitYangfei/golang/blob/master/rtmpserver.go
//发送S0
char
handshake_head
=
HANDSHAKE_PLAINTEXT
;
onSendRawData
(
&
handshake_head
,
1
);
...
...
src/Rtmp/RtmpProtocol.h
查看文件 @
a769d6c2
...
...
@@ -8,7 +8,6 @@
#ifndef SRC_RTMP_RTMPPROTOCOL_H_
#define SRC_RTMP_RTMPPROTOCOL_H_
#include <netinet/in.h>
#include <memory>
#include <string>
#include <functional>
...
...
src/Rtmp/RtmpPusher.cpp
查看文件 @
a769d6c2
...
...
@@ -26,7 +26,7 @@ RtmpPusher::RtmpPusher(const char *strApp,const char *strStream) {
},
[]()
{});
auto
src
=
RtmpMediaSource
::
find
(
strApp
,
strStream
);
if
(
!
src
)
{
auto
strErr
=
StrPrinter
<<
"
媒体源:"
<<
strApp
<<
"/"
<<
strStream
<<
"不存在
"
<<
endl
;
auto
strErr
=
StrPrinter
<<
"
media source:"
<<
strApp
<<
"/"
<<
strStream
<<
"not found!
"
<<
endl
;
throw
std
::
runtime_error
(
strErr
);
}
m_pMediaSrc
=
src
;
...
...
@@ -132,7 +132,7 @@ inline void RtmpPusher::send_connect() {
auto
level
=
val
[
"level"
].
as_string
();
auto
code
=
val
[
"code"
].
as_string
();
if
(
level
!=
"status"
){
throw
std
::
runtime_error
(
StrPrinter
<<
"connect 失败
:
"
<<
level
<<
" "
<<
code
<<
endl
);
throw
std
::
runtime_error
(
StrPrinter
<<
"connect 失败
:
"
<<
level
<<
" "
<<
code
<<
endl
);
}
send_createStream
();
});
...
...
@@ -157,7 +157,7 @@ inline void RtmpPusher::send_publish() {
auto
level
=
val
[
"level"
].
as_string
();
auto
code
=
val
[
"code"
].
as_string
();
if
(
level
!=
"status"
)
{
throw
std
::
runtime_error
(
StrPrinter
<<
"publish 失败
:
"
<<
level
<<
" "
<<
code
<<
endl
);
throw
std
::
runtime_error
(
StrPrinter
<<
"publish 失败
:
"
<<
level
<<
" "
<<
code
<<
endl
);
}
//start send media
send_metaData
();
...
...
@@ -167,10 +167,10 @@ inline void RtmpPusher::send_publish() {
inline
void
RtmpPusher
::
send_metaData
(){
auto
src
=
m_pMediaSrc
.
lock
();
if
(
!
src
)
{
throw
std
::
runtime_error
(
"
媒体源已被释放
"
);
throw
std
::
runtime_error
(
"
the media source was released
"
);
}
if
(
!
src
->
ready
())
{
throw
std
::
runtime_error
(
"
媒体源尚未准备就绪
"
);
throw
std
::
runtime_error
(
"
the media source is not ready
"
);
}
AMFEncoder
enc
;
...
...
@@ -219,7 +219,7 @@ void RtmpPusher::onCmd_onStatus(AMFDecoder &dec) {
}
}
if
(
val
.
type
()
!=
AMF_OBJECT
){
throw
std
::
runtime_error
(
"onStatus:
未找到结果对象
"
);
throw
std
::
runtime_error
(
"onStatus:
the result object was not found
"
);
}
lock_guard
<
recursive_mutex
>
lck
(
m_mtxOnStatusCB
);
...
...
src/Rtmp/RtmpSession.h
查看文件 @
a769d6c2
...
...
@@ -8,7 +8,6 @@
#ifndef SRC_RTMP_RTMPSESSION_H_
#define SRC_RTMP_RTMPSESSION_H_
#include <netinet/in.h>
#include <unordered_map>
#include "amf.h"
#include "Rtmp.h"
...
...
src/Rtmp/amf.cpp
查看文件 @
a769d6c2
#include <string.h>
#include <stdexcept>
#include <arpa/inet.h>
#include "amf.h"
#include "utils.h"
#include "Util/logger.h"
...
...
src/Rtmp/utils.cpp
查看文件 @
a769d6c2
...
...
@@ -3,7 +3,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <arpa/inet.h>
#include "Util/util.h"
using
namespace
ZL
::
Util
;
/*
* Used to do unaligned loads on archs that don't support them. GCC can mostly
...
...
src/Rtsp/RtpBroadCaster.cpp
查看文件 @
a769d6c2
...
...
@@ -5,7 +5,6 @@
* Author: xzl
*/
#include <arpa/inet.h>
#include <list>
#include "RtpBroadCaster.h"
#include "Util/util.h"
...
...
@@ -65,7 +64,7 @@ RtpBroadCaster::~RtpBroadCaster() {
RtpBroadCaster
::
RtpBroadCaster
(
const
string
&
strLocalIp
,
const
string
&
strApp
,
const
string
&
strStream
)
{
auto
src
=
RtspMediaSource
::
find
(
strApp
,
strStream
);
if
(
!
src
){
auto
strErr
=
StrPrinter
<<
"未找到媒体源
:
"
<<
strApp
<<
" "
<<
strStream
<<
endl
;
auto
strErr
=
StrPrinter
<<
"未找到媒体源
:
"
<<
strApp
<<
" "
<<
strStream
<<
endl
;
throw
std
::
runtime_error
(
strErr
);
}
m_multiAddr
=
MultiCastAddressMaker
::
Instance
().
obtain
();
...
...
src/Rtsp/RtpBroadCaster.h
查看文件 @
a769d6c2
...
...
@@ -8,8 +8,7 @@
#ifndef SRC_RTSP_RTPBROADCASTER_H_
#define SRC_RTSP_RTPBROADCASTER_H_
#include <arpa/inet.h>
#include <netinet/in.h>
#include <mutex>
#include <memory>
#include <unordered_set>
...
...
src/Rtsp/RtpParser.cpp
查看文件 @
a769d6c2
...
...
@@ -35,7 +35,7 @@ RtpParser::RtpParser(const string& sdp) {
RtspTrack
tmp
[
2
];
int
cnt
=
parserSDP
(
sdp
,
tmp
);
if
(
0
==
cnt
)
{
throw
std
::
runtime_error
(
"
解析SDP失败!
"
);
throw
std
::
runtime_error
(
"
parse sdp failed
"
);
}
for
(
int
i
=
0
;
i
<
cnt
;
i
++
)
{
...
...
@@ -129,7 +129,7 @@ inline bool RtpParser::inputVideo(const RtpPacket& rtppack,
if
(
rtppack
.
sequence
!=
(
uint16_t
)(
m_h264frame
.
sequence
+
1
))
{
m_h264frame
.
data
.
clear
();
WarnL
<<
"丢包,帧废弃
:
"
<<
rtppack
.
sequence
<<
","
<<
m_h264frame
.
sequence
;
WarnL
<<
"丢包,帧废弃
:
"
<<
rtppack
.
sequence
<<
","
<<
m_h264frame
.
sequence
;
return
false
;
}
m_h264frame
.
sequence
=
rtppack
.
sequence
;
...
...
@@ -204,7 +204,7 @@ inline void RtpParser::onGetVideoTrack(const RtspTrack& video) {
string
strTmp
((
char
*
)
SPS_BUF
,
SPS_LEN
);
if
(
!
getAVCInfo
(
strTmp
,
m_iVideoWidth
,
m_iVideoHeight
,
m_fVideoFps
))
{
throw
std
::
runtime_error
(
"
解析SPS失败!
"
);
throw
std
::
runtime_error
(
"
parse sdp failed
"
);
}
}
...
...
src/Rtsp/RtspPlayer.cpp
查看文件 @
a769d6c2
...
...
@@ -2,13 +2,13 @@
#include <cmath>
#include <stdarg.h>
#include <algorithm>
#include <arpa/inet.h>
#include "Common/config.h"
#include "RtspPlayer.h"
#include "Device/base64.h"
#include "H264/SPSParser.h"
#include "Util/mini.h"
#include "Util/util.h"
#include "Network/sockutil.h"
using
namespace
ZL
::
Util
;
...
...
@@ -127,7 +127,7 @@ void RtspPlayer::onConnect(const SockException &err){
teardown
();
return
;
}
//发送DESCRIBE命令后处理函数
:
HandleResDESCRIBE
//发送DESCRIBE命令后处理函数
:
HandleResDESCRIBE
m_onHandshake
=
std
::
bind
(
&
RtspPlayer
::
HandleResDESCRIBE
,
this
,
placeholders
::
_1
);
write
(
"DESCRIBE %s RTSP/1.0
\r\n
"
"CSeq: %d
\r\n
"
...
...
@@ -345,9 +345,7 @@ void RtspPlayer::HandleResSETUP(const Parser& parser, unsigned int uiTrackIndex)
return
;
}
if
(((
struct
sockaddr_in
*
)
addr
)
->
sin_addr
.
s_addr
!=
srcIP
)
{
char
strAddr
[
32
]
=
{
0
};
inet_ntop
(
addr
->
sa_family
,(
&
((
struct
sockaddr_in
*
)
addr
)
->
sin_addr
),
strAddr
,
sizeof
(
strAddr
));
WarnL
<<
"收到请他地址的UDP数据:"
<<
strAddr
;
WarnL
<<
"收到请他地址的UDP数据:"
<<
inet_ntoa
(((
struct
sockaddr_in
*
)
addr
)
->
sin_addr
);
return
;
}
strongSelf
->
HandleOneRtp
(
i
,(
unsigned
char
*
)
buf
->
data
(),
buf
->
size
());
...
...
@@ -404,7 +402,7 @@ void RtspPlayer::pause(bool bPause) {
sendPause
(
bPause
,
getProgressTime
());
}
//注意
:
当字符串为空时,也会返回一个空字符串
//注意
:
当字符串为空时,也会返回一个空字符串
static
void
split
(
const
string
&
s
,
const
char
*
delim
,
vector
<
string
>
&
ret
)
{
size_t
last
=
0
;
size_t
index
=
s
.
find_first_of
(
delim
,
last
);
...
...
@@ -573,7 +571,7 @@ inline bool RtspPlayer::HandleOneRtp(int iTrackidx, unsigned char *pucData, unsi
WarnL
<<
"ssrc错误"
;
if
(
m_aui32SsrcErrorCnt
[
iTrackidx
]
++
>
10
)
{
track
.
ssrc
=
rtppt
.
ssrc
;
WarnL
<<
"ssrc更换
!
"
;
WarnL
<<
"ssrc更换
!
"
;
}
return
false
;
}
...
...
src/Rtsp/RtspPlayer.h
查看文件 @
a769d6c2
...
...
@@ -8,7 +8,6 @@
#ifndef SRC_RTSPPLAYER_RTSPPLAYER_H_TXT_
#define SRC_RTSPPLAYER_RTSPPLAYER_H_TXT_
#include <netinet/in.h>
#include <string>
#include <memory>
#include "Rtsp.h"
...
...
@@ -37,7 +36,7 @@ class RtspPlayer: public PlayerBase,public TcpClient {
public
:
typedef
std
::
shared_ptr
<
RtspPlayer
>
Ptr
;
//设置rtp传输类型,可选项有0(tcp,默认)、1(udp)、2(组播)
//设置方法
:
player[RtspPlayer::kRtpType] = 0/1/2;
//设置方法
:
player[RtspPlayer::kRtpType] = 0/1/2;
static
const
char
kRtpType
[];
RtspPlayer
();
...
...
src/Rtsp/RtspSession.cpp
查看文件 @
a769d6c2
...
...
@@ -4,8 +4,7 @@
* Created on: 2016年8月12日
* Author: xzl
*/
#include <arpa/inet.h>
#include <netinet/in.h>
#include <atomic>
#include "Common/config.h"
#include "UDPServer.h"
...
...
@@ -106,7 +105,7 @@ void RtspSession::onError(const SockException& err) {
lock_guard
<
recursive_mutex
>
lock
(
g_mtxPostter
);
//为了保证脱离TCPServer后还能正常运作,需要保持本对象的强引用
g_mapPostter
.
emplace
(
this
,
dynamic_pointer_cast
<
RtspSession
>
(
shared_from_this
()));
TraceL
<<
"quickTime
已经不再发送请求
"
;
TraceL
<<
"quickTime
will not send request any more!
"
;
}
}
...
...
src/Rtsp/RtspSession.h
查看文件 @
a769d6c2
...
...
@@ -8,7 +8,6 @@
#ifndef SESSION_RTSPSESSION_H_
#define SESSION_RTSPSESSION_H_
#include <netinet/in.h>
#include <set>
#include <vector>
#include <unordered_map>
...
...
src/Rtsp/RtspToRtmpMediaSource.cpp
查看文件 @
a769d6c2
...
...
@@ -5,13 +5,7 @@
* Author: xzl
*/
#include <unistd.h>
#include <string.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include "Common/config.h"
#include "Rtmp/Rtmp.h"
#include "RtspToRtmpMediaSource.h"
...
...
src/Rtsp/UDPServer.cpp
查看文件 @
a769d6c2
...
...
@@ -5,7 +5,7 @@
* Author: xzl
*/
#include <arpa/inet.h>
#include "UDPServer.h"
#include "Util/TimeTicker.h"
...
...
src/Shell/CMD.h
查看文件 @
a769d6c2
...
...
@@ -8,7 +8,6 @@
#ifndef SRC_SHELL_CMD_H_
#define SRC_SHELL_CMD_H_
#include <getopt.h>
#include <string>
#include <vector>
#include <iostream>
...
...
@@ -69,7 +68,7 @@ public:
typedef
function
<
void
(
OutStream
*
stream
,
const
unordered_multimap
<
char
,
string
>
&
)
>
OptionCompleted
;
OptionParser
(
const
OptionCompleted
&
_cb
)
{
onCompleted
=
_cb
;
helper
=
Option
(
'h'
,
"help"
,
Option
::
ArgNone
,
"
获取此帮助
"
,
[
this
](
OutStream
*
stream
,
const
char
*
arg
)
->
bool
{
helper
=
Option
(
'h'
,
"help"
,
Option
::
ArgNone
,
"
print this help
"
,
[
this
](
OutStream
*
stream
,
const
char
*
arg
)
->
bool
{
_StrPrinter
printer
;
for
(
auto
&
pr
:
options
)
{
printer
<<
"
\t
-"
<<
pr
.
first
<<
"
\t
--"
<<
pr
.
second
.
longOpt
<<
"
\t
"
<<
pr
.
second
.
des
<<
"
\r\n
"
;
...
...
tests/CMakeLists.txt
查看文件 @
a769d6c2
...
...
@@ -39,9 +39,11 @@ add_executable(${TEST_EXE_NAME} ${TEST_SRC})
if
(
ANDROID
)
target_link_libraries
(
${
TEST_EXE_NAME
}
${
CMAKE_PROJECT_NAME
}
_static
${
LINK_LIB_LIST
}
)
else
(
ANDROID
)
target_link_libraries
(
${
TEST_EXE_NAME
}
${
CMAKE_PROJECT_NAME
}
_shared
${
LINK_LIB_LIST
}
pthread
)
endif
(
ANDROID
)
elseif
(
WIN32
)
target_link_libraries
(
${
TEST_EXE_NAME
}
${
CMAKE_PROJECT_NAME
}
_shared
${
LINK_LIB_LIST
}
)
else
()
target_link_libraries
(
${
TEST_EXE_NAME
}
${
CMAKE_PROJECT_NAME
}
_shared
${
LINK_LIB_LIST
}
pthread
)
endif
()
endforeach
(
TEST_SRC
${
TEST_SRC_LIST
}
)
...
...
tests/test_benchmark.cpp
查看文件 @
a769d6c2
#include <signal.h>
#include <unistd.h>
#include <atomic>
#include <iostream>
#include <list>
...
...
@@ -29,8 +28,8 @@ int main(int argc, char *argv[]){
signal
(
SIGINT
,
programExit
);
if
(
argc
!=
5
){
FatalL
<<
"
\r\n
测试方法
:
./test_benchmark player_count play_interval rtxp_url rtp_type
\r\n
"
<<
"例如你想每隔50毫秒启动共计100个播放器(tcp方式播放rtsp://127.0.0.1/live/0 )可以输入以下命令
:
\r\n
"
FatalL
<<
"
\r\n
测试方法
:
./test_benchmark player_count play_interval rtxp_url rtp_type
\r\n
"
<<
"例如你想每隔50毫秒启动共计100个播放器(tcp方式播放rtsp://127.0.0.1/live/0 )可以输入以下命令
:
\r\n
"
<<
"./test_benchmark 100 50 rtsp://127.0.0.1/live/0 0
\r\n
"
<<
endl
;
Logger
::
Destory
();
...
...
@@ -59,7 +58,7 @@ int main(int argc, char *argv[]){
});
AsyncTaskThread
::
Instance
().
DoTaskDelay
(
0
,
1000
,
[
&
](){
InfoL
<<
"存活播放器个数
:
"
<<
alivePlayerCnt
.
load
();
InfoL
<<
"存活播放器个数
:
"
<<
alivePlayerCnt
.
load
();
return
true
;
});
EventPoller
::
Instance
().
runLoop
();
...
...
tests/test_httpClient.cpp
查看文件 @
a769d6c2
...
...
@@ -5,7 +5,6 @@
//============================================================================
#include <signal.h>
#include <unistd.h>
#include <iostream>
#include "Http/HttpDownloader.h"
#include "Http/HttpRequester.h"
...
...
tests/test_rtmpPusher.cpp
查看文件 @
a769d6c2
...
...
@@ -6,7 +6,6 @@
#include <signal.h>
#include <unistd.h>
#include <iostream>
#include "Util/logger.h"
#include "Util/onceToken.h"
...
...
@@ -44,14 +43,14 @@ int main(int argc,char *argv[]){
const_cast
<
RtmpPusher
::
Ptr
&>
(
pusher
).
reset
(
new
RtmpPusher
(
app
,
stream
));
pusher
->
setOnShutdown
([](
const
SockException
&
ex
){
WarnL
<<
"已断开与服务器连接
:
"
<<
ex
.
getErrCode
()
<<
" "
<<
ex
.
what
();
WarnL
<<
"已断开与服务器连接
:
"
<<
ex
.
getErrCode
()
<<
" "
<<
ex
.
what
();
});
pusher
->
setOnPublished
([](
const
SockException
&
ex
){
if
(
ex
){
WarnL
<<
"发布失败
:
"
<<
ex
.
getErrCode
()
<<
" "
<<
ex
.
what
();
WarnL
<<
"发布失败
:
"
<<
ex
.
getErrCode
()
<<
" "
<<
ex
.
what
();
}
else
{
InfoL
<<
"发布成功,请用播放器打开
:
rtmp://jizan.iok.la/live/test"
;
InfoL
<<
"发布成功,请用播放器打开
:
rtmp://jizan.iok.la/live/test"
;
}
});
...
...
tests/test_server.cpp
查看文件 @
a769d6c2
...
...
@@ -5,9 +5,10 @@
//============================================================================
#include <map>
#include <signal.h>
#include <unistd.h>
#include <iostream>
#include "Common/config.h"
#include "Rtsp/UDPServer.h"
#include "Rtsp/RtspSession.h"
#include "Rtmp/RtmpSession.h"
...
...
@@ -18,22 +19,24 @@
#include "Http/HttpsSession.h"
#endif//ENABLE_OPENSSL
#include "Util/File.h"
#include "Util/logger.h"
#include "Util/onceToken.h"
#include "Util/File.h"
#include "Network/TcpServer.h"
#include "Poller/EventPoller.h"
#include "Thread/WorkThreadPool.h"
#include "Device/PlayerProxy.h"
#if !defined(_WIN32)
#include "Shell/ShellSession.h"
#include "Common/config.h"
#include <map>
using
namespace
ZL
::
Shell
;
#endif // !defined(_WIN32)
using
namespace
std
;
using
namespace
ZL
::
Util
;
using
namespace
ZL
::
Http
;
using
namespace
ZL
::
Rtsp
;
using
namespace
ZL
::
Rtmp
;
using
namespace
ZL
::
Shell
;
using
namespace
ZL
::
Thread
;
using
namespace
ZL
::
Network
;
using
namespace
ZL
::
DEV
;
...
...
@@ -42,10 +45,11 @@ void programExit(int arg) {
EventPoller
::
Instance
().
shutdown
();
}
int
main
(
int
argc
,
char
*
argv
[]){
setExePath
(
argv
[
0
]);
//
setExePath(argv[0]);
signal
(
SIGINT
,
programExit
);
Logger
::
Instance
().
add
(
std
::
make_shared
<
ConsoleChannel
>
(
"stdout"
,
LTrace
));
Config
::
loaIniConfig
();
DebugL
<<
exePath
();
//support rtmp and rtsp url
//just support H264+AAC
auto
urlList
=
{
"rtmp://live.hkstv.hk.lxdns.com/live/hks"
,
...
...
@@ -54,11 +58,11 @@ int main(int argc,char *argv[]){
int
i
=
0
;
for
(
auto
url
:
urlList
){
//PlayerProxy构造函数前两个参数分别为应用名(app),流id(streamId)
//比如说应用为live,流id为0,那么直播地址为
:
//比如说应用为live,流id为0,那么直播地址为
:
//http://127.0.0.1/live/0/hls.m3u8
//rtsp://127.0.0.1/live/0
//rtmp://127.0.0.1/live/0
//录像地址为
:
//录像地址为
:
//http://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
//rtsp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
//rtmp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
...
...
@@ -81,17 +85,20 @@ int main(int argc,char *argv[]){
TcpServer
<
RtspSession
>::
Ptr
rtspSrv
(
new
TcpServer
<
RtspSession
>
());
TcpServer
<
RtmpSession
>::
Ptr
rtmpSrv
(
new
TcpServer
<
RtmpSession
>
());
TcpServer
<
HttpSession
>::
Ptr
httpSrv
(
new
TcpServer
<
HttpSession
>
());
TcpServer
<
ShellSession
>::
Ptr
shellSrv
(
new
TcpServer
<
ShellSession
>
());
rtspSrv
->
start
(
mINI
::
Instance
()[
Config
::
Rtsp
::
kPort
]);
rtmpSrv
->
start
(
mINI
::
Instance
()[
Config
::
Rtmp
::
kPort
]);
httpSrv
->
start
(
mINI
::
Instance
()[
Config
::
Http
::
kPort
]);
#if !defined(_WIN32)
//简单的telnet服务器,可用于服务器调试,但是不能使用23端口
//测试方法:telnet 127.0.0.1 8023
//输入用户名和密码登录(user:test,pwd:123456),输入help命令查看帮助
TcpServer
<
ShellSession
>::
Ptr
shellSrv
(
new
TcpServer
<
ShellSession
>
());
ShellSession
::
addUser
(
"test"
,
"123456"
);
shellSrv
->
start
(
8023
);
#endif // !defined(_WIN32)
#ifdef ENABLE_OPENSSL
TcpServer
<
HttpsSession
>::
Ptr
httpsSrv
(
new
TcpServer
<
HttpsSession
>
());
...
...
@@ -103,7 +110,10 @@ int main(int argc,char *argv[]){
rtspSrv
.
reset
();
rtmpSrv
.
reset
();
httpSrv
.
reset
();
#if !defined(_WIN32)
shellSrv
.
reset
();
#endif // !defined(_WIN32)
#ifdef ENABLE_OPENSSL
httpsSrv
.
reset
();
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论