diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b67c074..f10e685e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/cmake/FindMYSQL.cmake b/cmake/FindMYSQL.cmake index f9c82627..3828ed3e 100644 --- a/cmake/FindMYSQL.cmake +++ b/cmake/FindMYSQL.cmake @@ -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 ) diff --git a/cmake/FindZLTOOLKIT.cmake b/cmake/FindZLTOOLKIT.cmake index 642aabc2..5fcaa4c0 100644 --- a/cmake/FindZLTOOLKIT.cmake +++ b/cmake/FindZLTOOLKIT.cmake @@ -1,8 +1,10 @@ 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}) diff --git a/src/Codec/H264Encoder.cpp b/src/Codec/H264Encoder.cpp index f4696a39..e4c70d37 100644 --- a/src/Codec/H264Encoder.cpp +++ b/src/Codec/H264Encoder.cpp @@ -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帧, diff --git a/src/Common/config.cpp b/src/Common/config.cpp index bb30b1ec..5b0c9629 100644 --- a/src/Common/config.cpp +++ b/src/Common/config.cpp @@ -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(){ diff --git a/src/Device/Device.h b/src/Device/Device.h index 45033fe8..3c4582d2 100644 --- a/src/Device/Device.h +++ b/src/Device/Device.h @@ -8,7 +8,6 @@ #ifndef DEVICE_DEVICE_H_ #define DEVICE_DEVICE_H_ -#include #include #include #include diff --git a/src/H264/SPSParser.c b/src/H264/SPSParser.c index 5640c707..342f407f 100644 --- a/src/H264/SPSParser.c +++ b/src/H264/SPSParser.c @@ -2,8 +2,6 @@ #include #include #include /* for uint32_t, etc */ -#include - #include "SPSParser.h" /******************************************** diff --git a/src/H264/h264_parser.cpp b/src/H264/h264_parser.cpp index 20b0ad39..ab39ea77 100644 --- a/src/H264/h264_parser.cpp +++ b/src/H264/h264_parser.cpp @@ -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); diff --git a/src/H264/h264_poc.cpp b/src/H264/h264_poc.cpp index 451ca944..ab15975a 100644 --- a/src/H264/h264_poc.cpp +++ b/src/H264/h264_poc.cpp @@ -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; diff --git a/src/Http/HttpClient.cpp b/src/Http/HttpClient.cpp index f69ce0ed..787637e4 100644 --- a/src/Http/HttpClient.cpp +++ b/src/Http/HttpClient.cpp @@ -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); } diff --git a/src/Http/HttpSession.cpp b/src/Http/HttpSession.cpp index 5673871f..4d3b0eb8 100644 --- a/src/Http/HttpSession.cpp +++ b/src/Http/HttpSession.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include "Common/config.h" #include "strCoding.h" @@ -146,7 +145,7 @@ void HttpSession::onManager() { static uint32_t keepAliveSec = mINI::Instance()[Config::Http::kKeepAliveSecond].as(); 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 += "
  • "; - strRet += "根目录"; + strRet += "root directory"; strRet += "
  • \r\n"; strRet += "
  • "; - strRet += "上一级目录"; + strRet += "parent directory"; strRet += "
  • \r\n"; } diff --git a/src/MediaFile/HLSMaker.cpp b/src/MediaFile/HLSMaker.cpp index c342e1ad..46b46ee7 100644 --- a/src/MediaFile/HLSMaker.cpp +++ b/src/MediaFile/HLSMaker.cpp @@ -6,7 +6,10 @@ */ #include "HLSMaker.h" -#include +#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 diff --git a/src/MediaFile/MediaReader.cpp b/src/MediaFile/MediaReader.cpp index d6fd4d55..01aa224c 100644 --- a/src/MediaFile/MediaReader.cpp +++ b/src/MediaFile/MediaReader.cpp @@ -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); diff --git a/src/MediaFile/TSMaker.cpp b/src/MediaFile/TSMaker.cpp index efb46a3f..6a27f951 100644 --- a/src/MediaFile/TSMaker.cpp +++ b/src/MediaFile/TSMaker.cpp @@ -6,7 +6,6 @@ */ #include "TSMaker.h" -#include #include "Util/logger.h" using namespace ZL::Util; diff --git a/src/RTP/RtpMakerAAC.cpp b/src/RTP/RtpMakerAAC.cpp index 6adee9d3..f0c12145 100644 --- a/src/RTP/RtpMakerAAC.cpp +++ b/src/RTP/RtpMakerAAC.cpp @@ -5,7 +5,6 @@ * Author: xzl */ -#include #include "Common/config.h" #include "RtpMakerAAC.h" #include "Util/mini.h" diff --git a/src/RTP/RtpMakerH264.cpp b/src/RTP/RtpMakerH264.cpp index b613f582..28b009b4 100644 --- a/src/RTP/RtpMakerH264.cpp +++ b/src/RTP/RtpMakerH264.cpp @@ -5,7 +5,6 @@ * Author: xzl */ -#include #include "Common/config.h" #include "RtpMakerH264.h" #include "Util/mini.h" diff --git a/src/Rtmp/Rtmp.h b/src/Rtmp/Rtmp.h index 9c274cdf..3cac3713 100644 --- a/src/Rtmp/Rtmp.h +++ b/src/Rtmp/Rtmp.h @@ -1,7 +1,6 @@ #ifndef __rtmp_h #define __rtmp_h -#include #include #include #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: diff --git a/src/Rtmp/RtmpMediaSource.h b/src/Rtmp/RtmpMediaSource.h index 0952158a..459db69c 100644 --- a/src/Rtmp/RtmpMediaSource.h +++ b/src/Rtmp/RtmpMediaSource.h @@ -8,7 +8,6 @@ #ifndef SRC_RTMP_RTMPMEDIASOURCE_H_ #define SRC_RTMP_RTMPMEDIASOURCE_H_ -#include #include #include #include diff --git a/src/Rtmp/RtmpParser.cpp b/src/Rtmp/RtmpParser.cpp index 68cf2e6f..82d510a7 100644 --- a/src/Rtmp/RtmpParser.cpp +++ b/src/Rtmp/RtmpParser.cpp @@ -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(); } } diff --git a/src/Rtmp/RtmpPlayer.cpp b/src/Rtmp/RtmpPlayer.cpp index c4fa7e61..781ef38a 100644 --- a/src/Rtmp/RtmpPlayer.cpp +++ b/src/Rtmp/RtmpPlayer.cpp @@ -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 lck(m_mtxOnStatusCB); diff --git a/src/Rtmp/RtmpPlayer.h b/src/Rtmp/RtmpPlayer.h index 7012991b..8cb7b81d 100644 --- a/src/Rtmp/RtmpPlayer.h +++ b/src/Rtmp/RtmpPlayer.h @@ -8,7 +8,6 @@ #ifndef SRC_RTMP_RtmpPlayer2_H_ #define SRC_RTMP_RtmpPlayer2_H_ -#include #include #include #include diff --git a/src/Rtmp/RtmpProtocol.cpp b/src/Rtmp/RtmpProtocol.cpp index a85a4a1d..e7468c6c 100644 --- a/src/Rtmp/RtmpProtocol.cpp +++ b/src/Rtmp/RtmpProtocol.cpp @@ -14,17 +14,29 @@ using namespace ZL::Util; #ifdef ENABLE_OPENSSL +#include "Util/SSLBox.h" #include static string openssl_HMACsha256(const void *key,unsigned int key_len, const void *data,unsigned int data_len){ std::shared_ptr 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); diff --git a/src/Rtmp/RtmpProtocol.h b/src/Rtmp/RtmpProtocol.h index d995e442..7de6efc8 100644 --- a/src/Rtmp/RtmpProtocol.h +++ b/src/Rtmp/RtmpProtocol.h @@ -8,7 +8,6 @@ #ifndef SRC_RTMP_RTMPPROTOCOL_H_ #define SRC_RTMP_RTMPPROTOCOL_H_ -#include #include #include #include diff --git a/src/Rtmp/RtmpPusher.cpp b/src/Rtmp/RtmpPusher.cpp index 9146e028..c28e01a5 100644 --- a/src/Rtmp/RtmpPusher.cpp +++ b/src/Rtmp/RtmpPusher.cpp @@ -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 lck(m_mtxOnStatusCB); diff --git a/src/Rtmp/RtmpSession.h b/src/Rtmp/RtmpSession.h index 60f6d465..215d9c2a 100644 --- a/src/Rtmp/RtmpSession.h +++ b/src/Rtmp/RtmpSession.h @@ -8,7 +8,6 @@ #ifndef SRC_RTMP_RTMPSESSION_H_ #define SRC_RTMP_RTMPSESSION_H_ -#include #include #include "amf.h" #include "Rtmp.h" diff --git a/src/Rtmp/amf.cpp b/src/Rtmp/amf.cpp index 9bef838f..e374381e 100644 --- a/src/Rtmp/amf.cpp +++ b/src/Rtmp/amf.cpp @@ -1,6 +1,5 @@ #include #include -#include #include "amf.h" #include "utils.h" #include "Util/logger.h" diff --git a/src/Rtmp/utils.cpp b/src/Rtmp/utils.cpp index ed0dd331..d2648653 100644 --- a/src/Rtmp/utils.cpp +++ b/src/Rtmp/utils.cpp @@ -3,7 +3,9 @@ #include #include #include -#include +#include "Util/util.h" + +using namespace ZL::Util; /* * Used to do unaligned loads on archs that don't support them. GCC can mostly diff --git a/src/Rtsp/RtpBroadCaster.cpp b/src/Rtsp/RtpBroadCaster.cpp index 3c914bc6..dc3d97eb 100644 --- a/src/Rtsp/RtpBroadCaster.cpp +++ b/src/Rtsp/RtpBroadCaster.cpp @@ -5,7 +5,6 @@ * Author: xzl */ -#include #include #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(); diff --git a/src/Rtsp/RtpBroadCaster.h b/src/Rtsp/RtpBroadCaster.h index bf1c0bbf..7e4fd5ce 100644 --- a/src/Rtsp/RtpBroadCaster.h +++ b/src/Rtsp/RtpBroadCaster.h @@ -8,8 +8,7 @@ #ifndef SRC_RTSP_RTPBROADCASTER_H_ #define SRC_RTSP_RTPBROADCASTER_H_ -#include -#include + #include #include #include diff --git a/src/Rtsp/RtpParser.cpp b/src/Rtsp/RtpParser.cpp index b80fb04c..6e668562 100644 --- a/src/Rtsp/RtpParser.cpp +++ b/src/Rtsp/RtpParser.cpp @@ -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"); } } diff --git a/src/Rtsp/RtspPlayer.cpp b/src/Rtsp/RtspPlayer.cpp index 19738d79..0240e610 100644 --- a/src/Rtsp/RtspPlayer.cpp +++ b/src/Rtsp/RtspPlayer.cpp @@ -2,13 +2,13 @@ #include #include #include -#include #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 &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; } diff --git a/src/Rtsp/RtspPlayer.h b/src/Rtsp/RtspPlayer.h index dd68b8f9..d613e11d 100644 --- a/src/Rtsp/RtspPlayer.h +++ b/src/Rtsp/RtspPlayer.h @@ -8,7 +8,6 @@ #ifndef SRC_RTSPPLAYER_RTSPPLAYER_H_TXT_ #define SRC_RTSPPLAYER_RTSPPLAYER_H_TXT_ -#include #include #include #include "Rtsp.h" @@ -37,7 +36,7 @@ class RtspPlayer: public PlayerBase,public TcpClient { public: typedef std::shared_ptr Ptr; //设置rtp传输类型,可选项有0(tcp,默认)、1(udp)、2(组播) - //设置方法:player[RtspPlayer::kRtpType] = 0/1/2; + //设置方法:player[RtspPlayer::kRtpType] = 0/1/2; static const char kRtpType[]; RtspPlayer(); diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index d79c3eca..66ee1213 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -4,8 +4,7 @@ * Created on: 2016年8月12日 * Author: xzl */ -#include -#include + #include #include "Common/config.h" #include "UDPServer.h" @@ -106,7 +105,7 @@ void RtspSession::onError(const SockException& err) { lock_guard lock(g_mtxPostter); //为了保证脱离TCPServer后还能正常运作,需要保持本对象的强引用 g_mapPostter.emplace(this, dynamic_pointer_cast(shared_from_this())); - TraceL << "quickTime已经不再发送请求"; + TraceL << "quickTime will not send request any more!"; } } diff --git a/src/Rtsp/RtspSession.h b/src/Rtsp/RtspSession.h index 3deceae3..21de5a66 100644 --- a/src/Rtsp/RtspSession.h +++ b/src/Rtsp/RtspSession.h @@ -8,7 +8,6 @@ #ifndef SESSION_RTSPSESSION_H_ #define SESSION_RTSPSESSION_H_ -#include #include #include #include diff --git a/src/Rtsp/RtspToRtmpMediaSource.cpp b/src/Rtsp/RtspToRtmpMediaSource.cpp index 5c1c742a..bd386b81 100644 --- a/src/Rtsp/RtspToRtmpMediaSource.cpp +++ b/src/Rtsp/RtspToRtmpMediaSource.cpp @@ -5,13 +5,7 @@ * Author: xzl */ -#include #include -#include -#include -#include -#include -#include #include "Common/config.h" #include "Rtmp/Rtmp.h" #include "RtspToRtmpMediaSource.h" diff --git a/src/Rtsp/UDPServer.cpp b/src/Rtsp/UDPServer.cpp index e229867c..a306dd60 100644 --- a/src/Rtsp/UDPServer.cpp +++ b/src/Rtsp/UDPServer.cpp @@ -5,7 +5,7 @@ * Author: xzl */ -#include + #include "UDPServer.h" #include "Util/TimeTicker.h" diff --git a/src/Shell/CMD.h b/src/Shell/CMD.h index a86c2073..bab72949 100644 --- a/src/Shell/CMD.h +++ b/src/Shell/CMD.h @@ -8,7 +8,6 @@ #ifndef SRC_SHELL_CMD_H_ #define SRC_SHELL_CMD_H_ -#include #include #include #include @@ -69,7 +68,7 @@ public: typedef function< void(OutStream *stream, const unordered_multimap &)> 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-"< -#include #include #include #include @@ -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" < -#include #include #include "Http/HttpDownloader.h" #include "Http/HttpRequester.h" diff --git a/tests/test_rtmpPusher.cpp b/tests/test_rtmpPusher.cpp index eb0a9aff..5098e085 100644 --- a/tests/test_rtmpPusher.cpp +++ b/tests/test_rtmpPusher.cpp @@ -6,7 +6,6 @@ #include -#include #include #include "Util/logger.h" #include "Util/onceToken.h" @@ -44,14 +43,14 @@ int main(int argc,char *argv[]){ const_cast(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"; } }); diff --git a/tests/test_server.cpp b/tests/test_server.cpp index 47191833..96ccdb47 100644 --- a/tests/test_server.cpp +++ b/tests/test_server.cpp @@ -5,9 +5,10 @@ //============================================================================ +#include #include -#include #include +#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 +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("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::Ptr rtspSrv(new TcpServer()); TcpServer::Ptr rtmpSrv(new TcpServer()); TcpServer::Ptr httpSrv(new TcpServer()); - TcpServer::Ptr shellSrv(new TcpServer()); + 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::Ptr shellSrv(new TcpServer()); ShellSession::addUser("test","123456"); shellSrv->start(8023); +#endif // !defined(_WIN32) #ifdef ENABLE_OPENSSL TcpServer::Ptr httpsSrv(new TcpServer()); @@ -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();