diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d168c1..fe38504 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,31 +1,7 @@ -cmake_minimum_required(VERSION 3.9) +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) -include_directories(include) +PROJECT(gear-lib) -set(darray_src src/libdarray.c src/libserializer.c) -set(hash_src src/libhash.c) -set(posix_src src/libposix.c) -set(base64_src src/libbase64.c) -set(log_src src/liblog.c) -set(file_src src/filewatcher.c src/fio.c src/io.c src/libfile.c) -set(ipc_src src/libipc.c src/msgq_posix.c src/msgq_sysv.c src/netlink.c src/shm.c src/unix_socket.c) -set(gevent_src src/epoll.c src/libgevent.c src/poll.c src/select.c) -set(dict_src src/libdict.c) -set(queue_src src/libqueue.c) -set(vector_src src/libvector.c) -set(media-io_src src/audio-def.c src/libmedia-io.c src/video-def.c) - -add_library(posix SHARED ${posix_src}) -add_library(hash SHARED ${hash_src}) -add_library(media-io SHARED ${media-io_src}) -add_library(darray SHARED ${darray_src}) -add_library(gevent SHARED ${gevent_src}) -add_library(dict SHARED ${dict_src}) -add_library(ipc SHARED ${ipc_src}) -target_link_libraries(ipc rt gevent dict) - -add_library(log SHARED ${log_src}) -add_library(file SHARED ${file_src}) -add_library(queue SHARED ${queue_src}) -add_library(vector SHARED ${vector_src}) +INCLUDE(build/cmake_env.inc) +ADD_SUBDIRECTORY(gear-lib) diff --git a/README.cn.md b/README.cn.md index 544a7b9..df60201 100644 --- a/README.cn.md +++ b/README.cn.md @@ -10,7 +10,7 @@ * 全部用POSIX C实现,目标是为了跨平台兼容linux, windows, android, ios. * 适用于物联网,嵌入式,以及网络服务开发等场景 -![struct](https://github.com/gozfree/gear-lib/blob/master/build/gear-lib.png) +![struct](./build/gear-lib.png) ## 数据结构 | | | diff --git a/README.md b/README.md index 50e69a1..673da92 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This is a collection of basic libraries. * All are written in POSIX C, aim to used compatibility on linux, windows, android, ios. * Aim to reuse for IOT, embedded and network service development -![struct](https://github.com/gozfree/gear-lib/blob/master/build/gear-lib.png) +![struct](./build/gear-lib.png) ## Data Struct | | | diff --git a/build/cmake_env.inc b/build/cmake_env.inc new file mode 100644 index 0000000..a3548bf --- /dev/null +++ b/build/cmake_env.inc @@ -0,0 +1,24 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8...3.20) +PROJECT(gear-lib) + +#set output directory +SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/build/lib) +SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/build/bin) +SET(TD_TESTS_OUTPUT_DIR ${PROJECT_BINARY_DIR}/test) + +MESSAGE(STATUS "============= Compile Env ============= ") +MESSAGE(STATUS " CPU Info: " ${CMAKE_SYSTEM_PROCESSOR}) +MESSAGE(STATUS " OS Info: " ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_VERSION}) +MESSAGE(STATUS "Host Info: " ${CMAKE_HOST_SYSTEM_NAME}) +MESSAGE(STATUS "============= Compile Env ============= ") + +MESSAGE(STATUS "Project source directory: " ${PROJECT_SOURCE_DIR}) +MESSAGE(STATUS "Project binary files output path: " ${PROJECT_BINARY_DIR}) +MESSAGE(STATUS "Project executable files output path: " ${EXECUTABLE_OUTPUT_PATH}) +MESSAGE(STATUS "Project library files output path: " ${LIBRARY_OUTPUT_PATH}) + +IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + SET(OS_LINUX TRUE) +ELSEIF (${CMAKE_SYSTEM_NAME} MATCHES "Windows") + SET(OS_WINDOWS TRUE) +ENDIF () diff --git a/build/visual studio 2010/gear-lib/gear-lib.sln b/build/visual studio 2010/gear-lib/gear-lib.sln index 1af5c5e..5ad347f 100644 --- a/build/visual studio 2010/gear-lib/gear-lib.sln +++ b/build/visual studio 2010/gear-lib/gear-lib.sln @@ -80,8 +80,10 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "librtsp", "librtsp\librtsp.vcxproj", "{968FA321-4230-4DD4-A554-2619A7D5D080}" ProjectSection(ProjectDependencies) = postProject {2B438236-335D-4F87-8D3A-A10300C7F7DA} = {2B438236-335D-4F87-8D3A-A10300C7F7DA} + {BAF9105C-FF03-4D1C-96A0-DF2F8270936F} = {BAF9105C-FF03-4D1C-96A0-DF2F8270936F} {8682FC88-8540-447B-87CF-4E2B3DAF50A9} = {8682FC88-8540-447B-87CF-4E2B3DAF50A9} {88F2DE94-0375-40CF-92C0-70B98C56B508} = {88F2DE94-0375-40CF-92C0-70B98C56B508} + {67EEB99D-920D-4E28-BC28-477A8E334023} = {67EEB99D-920D-4E28-BC28-477A8E334023} {C8C000B6-BF66-420C-A7B8-D566E955731A} = {C8C000B6-BF66-420C-A7B8-D566E955731A} {2E965CCF-A6DE-4D7D-84A6-ED3F79659914} = {2E965CCF-A6DE-4D7D-84A6-ED3F79659914} {819399D0-724E-4805-B513-480B317CE139} = {819399D0-724E-4805-B513-480B317CE139} @@ -102,6 +104,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhal", "libhal\libhal.vcx {2E965CCF-A6DE-4D7D-84A6-ED3F79659914} = {2E965CCF-A6DE-4D7D-84A6-ED3F79659914} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libvector", "libvector\libvector.vcxproj", "{8CAD541B-A89A-48B0-B7EC-AF9E527EA8CE}" + ProjectSection(ProjectDependencies) = postProject + {2E965CCF-A6DE-4D7D-84A6-ED3F79659914} = {2E965CCF-A6DE-4D7D-84A6-ED3F79659914} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdict", "libdict\libdict.vcxproj", "{46503A91-6BD1-4B9A-8DE4-7EA7AA0091B7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -176,6 +185,14 @@ Global {496D075D-50CA-465D-9D0A-D9229257FC48}.Debug|Win32.Build.0 = Debug|Win32 {496D075D-50CA-465D-9D0A-D9229257FC48}.Release|Win32.ActiveCfg = Release|Win32 {496D075D-50CA-465D-9D0A-D9229257FC48}.Release|Win32.Build.0 = Release|Win32 + {8CAD541B-A89A-48B0-B7EC-AF9E527EA8CE}.Debug|Win32.ActiveCfg = Debug|Win32 + {8CAD541B-A89A-48B0-B7EC-AF9E527EA8CE}.Debug|Win32.Build.0 = Debug|Win32 + {8CAD541B-A89A-48B0-B7EC-AF9E527EA8CE}.Release|Win32.ActiveCfg = Release|Win32 + {8CAD541B-A89A-48B0-B7EC-AF9E527EA8CE}.Release|Win32.Build.0 = Release|Win32 + {46503A91-6BD1-4B9A-8DE4-7EA7AA0091B7}.Debug|Win32.ActiveCfg = Debug|Win32 + {46503A91-6BD1-4B9A-8DE4-7EA7AA0091B7}.Debug|Win32.Build.0 = Debug|Win32 + {46503A91-6BD1-4B9A-8DE4-7EA7AA0091B7}.Release|Win32.ActiveCfg = Release|Win32 + {46503A91-6BD1-4B9A-8DE4-7EA7AA0091B7}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/build/visual studio 2010/gear-lib/libdict/libdict.vcxproj b/build/visual studio 2010/gear-lib/libdict/libdict.vcxproj new file mode 100644 index 0000000..cb1df19 --- /dev/null +++ b/build/visual studio 2010/gear-lib/libdict/libdict.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {46503A91-6BD1-4B9A-8DE4-7EA7AA0091B7} + libdict + + + + StaticLibrary + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + ..\..\..\..\gear-lib\libposix;..\..\..\..\gear-lib\libposix\MsvcLibX\include;..\..\..\..\gear-lib\libposix\pthreads4w;%(AdditionalIncludeDirectories) + "/DUCRTINCLUDE=$(VCInstallDir)include" "/DMSVCINCLUDE=$(VCInstallDir)include" "/DWSDKINCLUDE=$(WindowsSdkDir)Include" %(AdditionalOptions) + MultiThreaded + + + true + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + diff --git a/build/visual studio 2010/gear-lib/libdict/libdict.vcxproj.filters b/build/visual studio 2010/gear-lib/libdict/libdict.vcxproj.filters new file mode 100644 index 0000000..de4c02a --- /dev/null +++ b/build/visual studio 2010/gear-lib/libdict/libdict.vcxproj.filters @@ -0,0 +1,34 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + + + Header Files + + + + + + + \ No newline at end of file diff --git a/build/visual studio 2010/gear-lib/libdict/libdict.vcxproj.user b/build/visual studio 2010/gear-lib/libdict/libdict.vcxproj.user new file mode 100644 index 0000000..695b5c7 --- /dev/null +++ b/build/visual studio 2010/gear-lib/libdict/libdict.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/build/visual studio 2010/gear-lib/libgevent/libgevent.vcxproj b/build/visual studio 2010/gear-lib/libgevent/libgevent.vcxproj index 338ecf5..38512ba 100644 --- a/build/visual studio 2010/gear-lib/libgevent/libgevent.vcxproj +++ b/build/visual studio 2010/gear-lib/libgevent/libgevent.vcxproj @@ -69,6 +69,7 @@ + diff --git a/build/visual studio 2010/gear-lib/libhal/libhal.vcxproj b/build/visual studio 2010/gear-lib/libhal/libhal.vcxproj index aa752d5..5ee2681 100644 --- a/build/visual studio 2010/gear-lib/libhal/libhal.vcxproj +++ b/build/visual studio 2010/gear-lib/libhal/libhal.vcxproj @@ -16,7 +16,7 @@ - Application + StaticLibrary true MultiByte @@ -74,4 +74,4 @@ - \ No newline at end of file + diff --git a/build/visual studio 2010/gear-lib/librtsp/librtsp.vcxproj b/build/visual studio 2010/gear-lib/librtsp/librtsp.vcxproj index 29909a3..2360d96 100644 --- a/build/visual studio 2010/gear-lib/librtsp/librtsp.vcxproj +++ b/build/visual studio 2010/gear-lib/librtsp/librtsp.vcxproj @@ -42,7 +42,7 @@ Level3 Disabled MultiThreaded - ..\..\..\..\gear-lib\libposix;..\..\..\..\gear-lib\libposix\MsvcLibX\include;..\..\..\..\gear-lib\libposix\pthreads4w;..\..\..\..\gear-lib\liblog;..\..\..\..\gear-lib\libsock;%(AdditionalIncludeDirectories) + ..\..\..\..\gear-lib\libposix;..\..\..\..\gear-lib\libposix\MsvcLibX\include;..\..\..\..\gear-lib\libposix\pthreads4w;..\..\..\..\gear-lib\liblog;..\..\..\..\gear-lib\libsock;..\..\..\..\gear-lib\libtime;..\..\..\..\gear-lib\libdict;..\..\..\..\gear-lib\libgevent;..\..\..\..\gear-lib\libdarray;..\..\..\..\gear-lib\libthread;..\..\..\..\gear-lib\libmedia-io;..\..\..\..\gear-lib\libfile;..\..\..\..\gear-lib\libuvc;..\..\..\..\gear-lib\libqueue;..\..\..\..\gear-lib\librtsp;%(AdditionalIncludeDirectories) "/DUCRTINCLUDE=$(VCInstallDir)include" "/DMSVCINCLUDE=$(VCInstallDir)include" "/DWSDKINCLUDE=$(WindowsSdkDir)Include" %(AdditionalOptions) @@ -64,6 +64,7 @@ + @@ -79,12 +80,12 @@ + + - - diff --git a/build/visual studio 2010/gear-lib/librtsp/librtsp.vcxproj.filters b/build/visual studio 2010/gear-lib/librtsp/librtsp.vcxproj.filters index affb51b..ca35993 100644 --- a/build/visual studio 2010/gear-lib/librtsp/librtsp.vcxproj.filters +++ b/build/visual studio 2010/gear-lib/librtsp/librtsp.vcxproj.filters @@ -20,6 +20,7 @@ + @@ -49,6 +50,12 @@ Header Files + + Header Files + + + Header Files + @@ -57,12 +64,6 @@ Source Files - - Source Files - - - Source Files - Source Files diff --git a/build/visual studio 2010/gear-lib/libvector/libvector.vcxproj b/build/visual studio 2010/gear-lib/libvector/libvector.vcxproj new file mode 100644 index 0000000..5480874 --- /dev/null +++ b/build/visual studio 2010/gear-lib/libvector/libvector.vcxproj @@ -0,0 +1,80 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {8CAD541B-A89A-48B0-B7EC-AF9E527EA8CE} + libvector + + + + StaticLibrary + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + MultiThreaded + ..\..\..\..\gear-lib\libposix;..\..\..\..\gear-lib\libposix\MsvcLibX\include;..\..\..\..\gear-lib\libposix\pthreads4w;%(AdditionalIncludeDirectories) + "/DUCRTINCLUDE=$(VCInstallDir)include" "/DMSVCINCLUDE=$(VCInstallDir)include" "/DWSDKINCLUDE=$(WindowsSdkDir)Include" %(AdditionalOptions) + + + true + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/visual studio 2010/gear-lib/libvector/libvector.vcxproj.filters b/build/visual studio 2010/gear-lib/libvector/libvector.vcxproj.filters new file mode 100644 index 0000000..20a12e3 --- /dev/null +++ b/build/visual studio 2010/gear-lib/libvector/libvector.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + + + Header Files + + + + + + + + \ No newline at end of file diff --git a/build/visual studio 2010/gear-lib/libvector/libvector.vcxproj.user b/build/visual studio 2010/gear-lib/libvector/libvector.vcxproj.user new file mode 100644 index 0000000..695b5c7 --- /dev/null +++ b/build/visual studio 2010/gear-lib/libvector/libvector.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/gear-lib/CMakeLists.txt b/gear-lib/CMakeLists.txt new file mode 100644 index 0000000..33cb7bb --- /dev/null +++ b/gear-lib/CMakeLists.txt @@ -0,0 +1,32 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +SET(POSIX_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libposix/) +SET(DICT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libdict/) +SET(DARRAY_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libdarray/) +SET(THREAD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libthread/) +SET(GEVENT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libgevent/) +SET(MEDIA_IO_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libmedia-io/) +SET(QUEUE_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libqueue/) +SET(LOG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/liblog/) +SET(SOCK_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libsock/) +SET(FILE_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libfile/) +SET(UVC_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libuvc/) +SET(TIME_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libtime/) + +ADD_SUBDIRECTORY(libposix) +ADD_SUBDIRECTORY(libbase64) +ADD_SUBDIRECTORY(libbitmap) +ADD_SUBDIRECTORY(libdict) +ADD_SUBDIRECTORY(libdarray) +ADD_SUBDIRECTORY(libqueue) +ADD_SUBDIRECTORY(libthread) +ADD_SUBDIRECTORY(libgevent) +ADD_SUBDIRECTORY(libfile) +ADD_SUBDIRECTORY(libtime) +ADD_SUBDIRECTORY(libsock) +ADD_SUBDIRECTORY(liblog) +ADD_SUBDIRECTORY(libmedia-io) +ADD_SUBDIRECTORY(libuvc) +ADD_SUBDIRECTORY(librtmpc) +ADD_SUBDIRECTORY(librtsp) diff --git a/gear-lib/libbase64/CMakeLists.txt b/gear-lib/libbase64/CMakeLists.txt new file mode 100644 index 0000000..8cdaf85 --- /dev/null +++ b/gear-lib/libbase64/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR}) +AUX_SOURCE_DIRECTORY(. SOURCE_FILES) + +ADD_LIBRARY(base64 ${SOURCE_FILES}) diff --git a/gear-lib/libbitmap/CMakeLists.txt b/gear-lib/libbitmap/CMakeLists.txt new file mode 100644 index 0000000..afc9d89 --- /dev/null +++ b/gear-lib/libbitmap/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR}) +AUX_SOURCE_DIRECTORY(. SOURCE_FILES) + +ADD_LIBRARY(bitmap ${SOURCE_FILES}) diff --git a/gear-lib/libconfig/CMakeLists.txt b/gear-lib/libconfig/CMakeLists.txt new file mode 100644 index 0000000..be863a7 --- /dev/null +++ b/gear-lib/libconfig/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${POSIX_INCLUDE_DIR}) +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_FILES) + +add_library(config ${SOURCE_FILES}) diff --git a/gear-lib/libdarray/CMakeLists.txt b/gear-lib/libdarray/CMakeLists.txt new file mode 100644 index 0000000..ec671db --- /dev/null +++ b/gear-lib/libdarray/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR}) +AUX_SOURCE_DIRECTORY(. SOURCE_FILES) + +ADD_LIBRARY(darray ${SOURCE_FILES}) diff --git a/gear-lib/libdict/CMakeLists.txt b/gear-lib/libdict/CMakeLists.txt new file mode 100644 index 0000000..244b8c4 --- /dev/null +++ b/gear-lib/libdict/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR}) +AUX_SOURCE_DIRECTORY(. SOURCE_FILES) + +ADD_LIBRARY(dict ${SOURCE_FILES}) diff --git a/gear-lib/libdict/libdict.c b/gear-lib/libdict/libdict.c index e969ff1..cec518a 100644 --- a/gear-lib/libdict/libdict.c +++ b/gear-lib/libdict/libdict.c @@ -19,6 +19,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. ******************************************************************************/ +#include #include "libdict.h" #include #include diff --git a/gear-lib/libdict/test_libdict.c b/gear-lib/libdict/test_libdict.c index 1fd0bf7..cdd3d07 100644 --- a/gear-lib/libdict/test_libdict.c +++ b/gear-lib/libdict/test_libdict.c @@ -21,7 +21,6 @@ ******************************************************************************/ #include "libdict.h" #include -#include #include #define ALIGN "%15s: %6.4f sec\n" diff --git a/gear-lib/libfile/CMakeLists.txt b/gear-lib/libfile/CMakeLists.txt new file mode 100644 index 0000000..999b5e4 --- /dev/null +++ b/gear-lib/libfile/CMakeLists.txt @@ -0,0 +1,13 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR} ${DICT_INCLUDE_DIR} ${GEVENT_INCLUDE_DIR} ${DARRAY_INCLUDE_DIR} ${THREAD_INCLUDE_DIR}) + +LIST(APPEND SOURCE_FILES libfile.c fio.c io.c) + +IF (DEFINED OS_LINUX) +LIST(APPEND SOURCE_FILES filewatcher.c) +ENDIF () + +ADD_LIBRARY(file ${SOURCE_FILES}) + diff --git a/gear-lib/libgevent/CMakeLists.txt b/gear-lib/libgevent/CMakeLists.txt new file mode 100644 index 0000000..1dd03d7 --- /dev/null +++ b/gear-lib/libgevent/CMakeLists.txt @@ -0,0 +1,14 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR} ${DARRAY_INCLUDE_DIR} ${THREAD_INCLUDE_DIR}) + +LIST(APPEND SOURCE_FILES libgevent.c) + +IF (DEFINED OS_LINUX) +LIST(APPEND SOURCE_FILES epoll.c libgevent.c poll.c select.c) +ELSEIF (DEFINED OS_WINDOWS) +LIST(APPEND SOURCE_FILES wepoll.c iocp.c) +ENDIF () + +ADD_LIBRARY(gevent ${SOURCE_FILES}) diff --git a/gear-lib/libgevent/Makefile b/gear-lib/libgevent/Makefile index 1333328..794fbcf 100644 --- a/gear-lib/libgevent/Makefile +++ b/gear-lib/libgevent/Makefile @@ -80,7 +80,7 @@ $(TGT_LIB_A): $(OBJS_LIB) $(AR_V) rcs $@ $^ $(TGT_LIB_SO): $(OBJS_LIB) - $(CC_V) -o $@ $^ $(SHARED) + $(CC_V) -o $@ $^ $(SHARED) $(LDFLAGS) @mv $(TGT_LIB_SO) $(TGT_LIB_SO_VER) @ln -sf $(TGT_LIB_SO_VER) $(TGT_LIB_SO) diff --git a/gear-lib/libgevent/epoll.c b/gear-lib/libgevent/epoll.c index 7f740ba..4291612 100644 --- a/gear-lib/libgevent/epoll.c +++ b/gear-lib/libgevent/epoll.c @@ -20,18 +20,28 @@ * SOFTWARE. ******************************************************************************/ #include "libgevent.h" -#if defined (OS_LINUX) -#ifndef __CYGWIN__ #include #include #include #include #include #include +#if defined (OS_LINUX) #include +#elif defined (OS_WINDOWS) +#include "wepoll.h" +#endif + +#if defined (OS_LINUX) +#define epoll_fd_t int +#define is_epoll_fd_invalid(fd) (fd == -1) +#elif defined (OS_WINDOWS) +#define epoll_fd_t HANDLE +#define is_epoll_fd_invalid(fd) (fd == NULL) +#endif #ifdef __ANDROID__ -#define EPOLLRDHUP (0x2000) +#define EPOLLRDHUP (1U << 13) #endif #define EPOLL_MAX_NEVENT (4096) @@ -39,17 +49,17 @@ (((LONG_MAX) - 999) / 1000) struct epoll_ctx { - int epfd; + epoll_fd_t epfd; int nevents; struct epoll_event *events; }; static void *epoll_init(void) { - int fd; + epoll_fd_t fd; struct epoll_ctx *ec; fd = epoll_create(1); - if (-1 == fd) { + if (is_epoll_fd_invalid(fd)) { printf("epoll_create errno=%d %s\n", errno, strerror(errno)); return NULL; } @@ -93,7 +103,6 @@ static int epoll_add(struct gevent_base *eb, struct gevent *e) epev.events |= EPOLLONESHOT; else epev.events &= ~EPOLLONESHOT; - epev.events |= EPOLLET; epev.data.ptr = (void *)e; @@ -129,7 +138,6 @@ static int epoll_mod(struct gevent_base *eb, struct gevent *e) epev.events |= EPOLLONESHOT; else epev.events &= ~EPOLLONESHOT; - epev.events |= EPOLLET; epev.data.ptr = (void *)e; @@ -201,12 +209,28 @@ static int epoll_dispatch(struct gevent_base *eb, struct timeval *tv) } struct gevent_ops epollops = { - .init = epoll_init, - .deinit = epoll_deinit, - .add = epoll_add, - .del = epoll_del, - .mod = epoll_mod, - .dispatch = epoll_dispatch, +#if defined (OS_LINUX) + .init = +#endif + epoll_init, +#if defined (OS_LINUX) + .deinit = +#endif + epoll_deinit, +#if defined (OS_LINUX) + .add = +#endif + epoll_add, +#if defined (OS_LINUX) + .del = +#endif + epoll_del, +#if defined (OS_LINUX) + .mod = +#endif + epoll_mod, +#if defined (OS_LINUX) + .dispatch = +#endif + epoll_dispatch, }; -#endif -#endif diff --git a/gear-lib/libgevent/libgevent.c b/gear-lib/libgevent/libgevent.c index ff1b7d4..f3902bf 100644 --- a/gear-lib/libgevent/libgevent.c +++ b/gear-lib/libgevent/libgevent.c @@ -22,20 +22,20 @@ #include "libgevent.h" #include #include -#if defined (OS_LINUX) || defined (OS_APPLE) #include #include +#include +#if defined (OS_LINUX) || defined (OS_APPLE) #ifndef __CYGWIN__ #include #endif #endif -#include #if defined (OS_LINUX) || defined (OS_RTTHREAD) || defined (OS_APPLE) extern const struct gevent_ops selectops; extern const struct gevent_ops pollops; #endif -#if defined (OS_LINUX) +#if defined (OS_LINUX) || defined (OS_WINDOWS) #ifndef __CYGWIN__ extern const struct gevent_ops epollops; #endif @@ -45,10 +45,16 @@ extern const struct gevent_ops iocpops; #endif enum gevent_backend_type { +#if defined (OS_LINUX) || defined (OS_RTTHREAD) || defined (OS_APPLE) GEVENT_SELECT, GEVENT_POLL, +#endif +#if defined (OS_LINUX) || defined (OS_WINDOWS) GEVENT_EPOLL, +#endif +#if defined (OS_WINDOWS) GEVENT_IOCP, +#endif }; struct gevent_backend { @@ -61,7 +67,7 @@ static struct gevent_backend gevent_backend_list[] = { {GEVENT_SELECT, &selectops}, {GEVENT_POLL, &pollops}, #endif -#if defined (OS_LINUX) +#if defined (OS_LINUX) || defined (OS_WINDOWS) #ifndef __CYGWIN__ {GEVENT_EPOLL, &epollops}, #endif @@ -76,7 +82,8 @@ static struct gevent_backend gevent_backend_list[] = { #elif defined (OS_APPLE) #define GEVENT_BACKEND GEVENT_POLL #elif defined (OS_WINDOWS) -#define GEVENT_BACKEND GEVENT_IOCP +//#define GEVENT_BACKEND GEVENT_IOCP +#define GEVENT_BACKEND GEVENT_EPOLL #endif static void event_in(int fd, void *arg) @@ -201,7 +208,7 @@ void gevent_base_loop_break(struct gevent_base *eb) void gevent_base_signal(struct gevent_base *eb) { - uint64_t notify; + uint64_t notify = '1'; if (sizeof(uint64_t) != write(eb->inner_fd, ¬ify, sizeof(uint64_t))) { perror("write error"); } diff --git a/gear-lib/libgevent/wepoll.c b/gear-lib/libgevent/wepoll.c index b24f64e..ebc7e71 100644 --- a/gear-lib/libgevent/wepoll.c +++ b/gear-lib/libgevent/wepoll.c @@ -47,7 +47,8 @@ enum EPOLL_EVENTS { EPOLLWRBAND = (int) (1U << 9), EPOLLMSG = (int) (1U << 10), /* Never reported. */ EPOLLRDHUP = (int) (1U << 13), - EPOLLONESHOT = (int) (1U << 31) + EPOLLONESHOT = (int) (1U << 30), + EPOLLET = (int) (1U << 31) /* Not used, just for compile compatible */ }; #define EPOLLIN (1U << 0) @@ -61,7 +62,8 @@ enum EPOLL_EVENTS { #define EPOLLWRBAND (1U << 9) #define EPOLLMSG (1U << 10) #define EPOLLRDHUP (1U << 13) -#define EPOLLONESHOT (1U << 31) +#define EPOLLONESHOT (1U << 30) +#define EPOLLET (1U << 31) #define EPOLL_CTL_ADD 1 #define EPOLL_CTL_MOD 2 diff --git a/gear-lib/libgevent/wepoll.h b/gear-lib/libgevent/wepoll.h index daf6bdb..a7781ad 100644 --- a/gear-lib/libgevent/wepoll.h +++ b/gear-lib/libgevent/wepoll.h @@ -50,7 +50,8 @@ enum EPOLL_EVENTS { EPOLLWRBAND = (int) (1U << 9), EPOLLMSG = (int) (1U << 10), /* Never reported. */ EPOLLRDHUP = (int) (1U << 13), - EPOLLONESHOT = (int) (1U << 31) + EPOLLONESHOT = (int) (1U << 30), + EPOLLET = (int) (1U << 31) /* Not used, just for compile compatible */ }; #define EPOLLIN (1U << 0) @@ -64,7 +65,8 @@ enum EPOLL_EVENTS { #define EPOLLWRBAND (1U << 9) #define EPOLLMSG (1U << 10) #define EPOLLRDHUP (1U << 13) -#define EPOLLONESHOT (1U << 31) +#define EPOLLONESHOT (1U << 30) +#define EPOLLET (1U << 31) #define EPOLL_CTL_ADD 1 #define EPOLL_CTL_MOD 2 diff --git a/gear-lib/libipc/Makefile b/gear-lib/libipc/Makefile index 76ff8f7..72012fc 100644 --- a/gear-lib/libipc/Makefile +++ b/gear-lib/libipc/Makefile @@ -61,7 +61,7 @@ EXTRA_CFLAGS += -I$(OUTPUT)/include/gear-lib SHARED := -shared EXTRA_LDFLAGS := $($(ARCH)_LDFLAGS) -EXTRA_LDFLAGS += -L$(OUTLIBPATH)/lib/gear-lib -ldict -lgevent -ldarray -lthread +EXTRA_LDFLAGS += -L$(OUTLIBPATH)/lib/gear-lib -lposix -ldict -lgevent -ldarray -lthread EXTRA_LDFLAGS += -pthread -lrt diff --git a/gear-lib/liblog/CMakeLists.txt b/gear-lib/liblog/CMakeLists.txt new file mode 100644 index 0000000..992e950 --- /dev/null +++ b/gear-lib/liblog/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR}) +AUX_SOURCE_DIRECTORY(. SOURCE_FILES) + +ADD_LIBRARY(log ${SOURCE_FILES}) diff --git a/gear-lib/libmedia-io/CMakeLists.txt b/gear-lib/libmedia-io/CMakeLists.txt new file mode 100644 index 0000000..c7b9d6a --- /dev/null +++ b/gear-lib/libmedia-io/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR}) +AUX_SOURCE_DIRECTORY(. SOURCE_FILES) + +ADD_LIBRARY(media-io ${SOURCE_FILES}) diff --git a/gear-lib/libposix/CMakeLists.txt b/gear-lib/libposix/CMakeLists.txt new file mode 100644 index 0000000..39df381 --- /dev/null +++ b/gear-lib/libposix/CMakeLists.txt @@ -0,0 +1,16 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(.) + +LIST(APPEND SOURCE_FILES libposix.c) + +IF (DEFINED OS_LINUX) +LIST(APPEND SOURCE_FILES libposix4nix.c) +ELSEIF (DEFINED OS_WINDOWS) +AUX_SOURCE_DIRECTORY(MsvcLibX MSVCLIBX_SRC) +AUX_SOURCE_DIRECTORY(pthreads4w PTHREADS4W_SRC) +LIST(APPEND SOURCE_FILES ${MSVCLIBX_SRC} ${PTHREADS4W_SRC}) +ENDIF () + +ADD_LIBRARY(posix ${SOURCE_FILES}) diff --git a/gear-lib/libposix/libposix4win.h b/gear-lib/libposix/libposix4win.h index b8ae0cb..d6180c4 100644 --- a/gear-lib/libposix/libposix4win.h +++ b/gear-lib/libposix/libposix4win.h @@ -134,7 +134,10 @@ GEAR_API void usleep(unsigned long usec); typedef int clockid_t; #ifndef CLOCK_REALTIME -#define CLOCK_REALTIME ((clockid_t)1) +#define CLOCK_REALTIME ((clockid_t)0) +#endif +#ifndef CLOCK_MONOTONIC +#define CLOCK_MONOTONIC ((clockid_t)1) #endif #ifndef CLOCK_PROCESS_CPUTIME_ID #define CLOCK_PROCESS_CPUTIME_ID ((clockid_t)2) @@ -142,9 +145,7 @@ typedef int clockid_t; #ifndef CLOCK_THREAD_CPUTIME_ID #define CLOCK_THREAD_CPUTIME_ID ((clockid_t)3) #endif -#ifndef CLOCK_MONOTONIC -#define CLOCK_MONOTONIC ((clockid_t)4) -#endif + /****************************************************************************** diff --git a/gear-lib/libqueue/CMakeLists.txt b/gear-lib/libqueue/CMakeLists.txt new file mode 100644 index 0000000..b50c36c --- /dev/null +++ b/gear-lib/libqueue/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR}) +AUX_SOURCE_DIRECTORY(. SOURCE_FILES) + +ADD_LIBRARY(queue ${SOURCE_FILES}) diff --git a/gear-lib/librtmpc/CMakeLists.txt b/gear-lib/librtmpc/CMakeLists.txt new file mode 100644 index 0000000..9d1f916 --- /dev/null +++ b/gear-lib/librtmpc/CMakeLists.txt @@ -0,0 +1,9 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR} ${DARRAY_INCLUDE_DIR} ${MEDIA_IO_INCLUDE_DIR} ${QUEUE_INCLUDE_DIR} ${THREAD_INCLUDE_DIR}) +AUX_SOURCE_DIRECTORY(. SOURCE_FILES) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNO_CRYPTO") + +ADD_LIBRARY(rtmpc ${SOURCE_FILES}) diff --git a/gear-lib/librtsp/CMakeLists.txt b/gear-lib/librtsp/CMakeLists.txt new file mode 100644 index 0000000..53861e6 --- /dev/null +++ b/gear-lib/librtsp/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR} ${LOG_INCLUDE_DIR} ${DICT_INCLUDE_DIR} ${THREAD_INCLUDE_DIR} ${GEVENT_INCLUDE_DIR} ${DARRAY_INCLUDE_DIR} ${SOCK_INCLUDE_DIR} ${MEDIA_IO_INCLUDE_DIR} ${FILE_INCLUDE_DIR} ${QUEUE_INCLUDE_DIR} ${UVC_INCLUDE_DIR} ${TIME_INCLUDE_DIR}) +AUX_SOURCE_DIRECTORY(. SOURCE_FILES) + +ADD_LIBRARY(rtsp ${SOURCE_FILES}) diff --git a/gear-lib/librtsp/librtsp_server.c b/gear-lib/librtsp/librtsp_server.c index bdeb41e..57f81cf 100644 --- a/gear-lib/librtsp/librtsp_server.c +++ b/gear-lib/librtsp/librtsp_server.c @@ -19,6 +19,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. ******************************************************************************/ +#include +#include +#include +#include "librtsp.h" +#include #include #include #include @@ -26,10 +31,7 @@ #include #include #include -#include -#include -#include "librtsp.h" -#include + #include "media_source.h" #include "transport_session.h" #include "rtsp_parser.h" @@ -98,8 +100,9 @@ static void rtsp_connect_create(struct rtsp_server *rtsp, int fd, uint32_t ip, u static void rtsp_connect_destroy(struct rtsp_server *rtsp, int fd) { char key[9]; + struct rtsp_request *req; snprintf(key, sizeof(key), "%d", fd); - struct rtsp_request *req = (struct rtsp_request *)dict_get(rtsp->connect_pool, key, NULL); + req = (struct rtsp_request *)dict_get(rtsp->connect_pool, key, NULL); logi("fd = %d, req=%p\n", fd, req); dict_del(rtsp->connect_pool, key); gevent_del(rtsp->evbase, &req->event); diff --git a/gear-lib/librtsp/media_source.h b/gear-lib/librtsp/media_source.h index 5543896..e050f6e 100644 --- a/gear-lib/librtsp/media_source.h +++ b/gear-lib/librtsp/media_source.h @@ -40,10 +40,10 @@ typedef struct media_source { char sdp[SDP_LEN_MAX]; struct timeval tm_create; int (*sdp_generate)(struct media_source *ms); - int (*open)(struct media_source *ms, const char *uri); - int (*read)(struct media_source *ms, void **data, size_t *len); - int (*write)(struct media_source *ms, void *data, size_t len); - void (*close)(struct media_source *ms); + int (*_open)(struct media_source *ms, const char *uri); + int (*_read)(struct media_source *ms, void **data, size_t *len); + int (*_write)(struct media_source *ms, void *data, size_t len); + void (*_close)(struct media_source *ms); int (*get_frame)(); void *opaque; bool is_active; diff --git a/gear-lib/librtsp/media_source_h264.c b/gear-lib/librtsp/media_source_h264.c index b8f53d6..b274bff 100644 --- a/gear-lib/librtsp/media_source_h264.c +++ b/gear-lib/librtsp/media_source_h264.c @@ -40,12 +40,13 @@ struct h264_source_ctx { static void *item_alloc_hook(void *data, size_t len, void *arg) { + struct media_packet *new_pkt; struct media_packet *pkt = (struct media_packet *)arg; if (!pkt) { loge("calloc packet failed!\n"); return NULL; } - struct media_packet *new_pkt = media_packet_copy(pkt, MEDIA_MEM_SHALLOW); + new_pkt = media_packet_copy(pkt, MEDIA_MEM_SHALLOW); logd("media_packet size=%d\n", media_packet_get_size(new_pkt)); return new_pkt; } @@ -71,26 +72,29 @@ static int h264_parser_frame(struct h264_source_ctx *c, const char *name) { int ret = 0; size_t count = 0; + size_t bytes; + const uint8_t *start, *end, *nalu, *nalu2; + struct media_packet *pkt; + struct queue_item *it; struct iovec *data = file_dump(name); if (!data) { loge("file_dump %s failed!\n", name); return -1; } - const uint8_t *start = data->iov_base; - const uint8_t *end = start + data->iov_len; - const uint8_t *nalu = h264_find_start_code(start, end); + start = data->iov_base; + end = start + data->iov_len; + nalu = h264_find_start_code(start, end); while (nalu < end) { - const uint8_t *nalu2 = h264_find_start_code(nalu + 4, end); - size_t bytes = nalu2 - nalu; - - struct media_packet *pkt = media_packet_create(MEDIA_TYPE_VIDEO, MEDIA_MEM_SHALLOW, (uint8_t *)nalu, bytes); + nalu2 = h264_find_start_code(nalu + 4, end); + bytes = nalu2 - nalu; + pkt = media_packet_create(MEDIA_TYPE_VIDEO, MEDIA_MEM_SHALLOW, (uint8_t *)nalu, bytes); pkt->video->pts = 90000 * count++; pkt->video->dts = 90000 * count++; pkt->video->encoder.timebase.num = 30; pkt->video->encoder.timebase.den = 1; - struct queue_item *it = queue_item_alloc(c->q, pkt->video->data, pkt->video->size, pkt); + it = queue_item_alloc(c->q, pkt->video->data, pkt->video->size, pkt); if (!it) { loge("item_alloc packet type %d failed!\n", pkt->type); ret = -1; @@ -199,8 +203,8 @@ static int sdp_generate(struct media_source *ms) struct media_source media_source_h264 = { .name = "H264", .sdp_generate = sdp_generate, - .open = h264_file_open, - .read = h264_file_read_frame, - .write = h264_file_write, - .close = h264_file_close, + ._open = h264_file_open, + ._read = h264_file_read_frame, + ._write = h264_file_write, + ._close = h264_file_close, }; diff --git a/gear-lib/librtsp/media_source_live.c b/gear-lib/librtsp/media_source_live.c index 1f1af92..455060a 100644 --- a/gear-lib/librtsp/media_source_live.c +++ b/gear-lib/librtsp/media_source_live.c @@ -68,7 +68,7 @@ struct live_source_ctx { void *priv; }; -static struct live_source_ctx g_live = {.uvc_opened = false}; +static struct live_source_ctx g_live; static int pixel_format_to_x264_csp(enum pixel_format fmt) { @@ -205,6 +205,7 @@ failed: static int init_pic_data(struct x264_ctx *c, x264_picture_t *pic, struct video_frame *frame) { + int i; x264_picture_init(pic); pic->i_pts = frame->timestamp; pic->img.i_csp = c->param.i_csp; @@ -233,7 +234,7 @@ pic->img.i_plane, frame->planes); return -1; } - for (int i = 0; i < pic->img.i_plane; i++) { + for (i = 0; i < pic->img.i_plane; i++) { pic->img.i_stride[i] = (int)frame->linesize[i]; pic->img.plane[i] = frame->data[i]; } @@ -243,6 +244,7 @@ pic->img.i_plane, frame->planes); static int fill_packet(struct x264_ctx *c, struct video_packet *pkt, x264_nal_t *nals, int nal_cnt, x264_picture_t *pic_out) { + int i; if (!nal_cnt) return -1; @@ -253,7 +255,7 @@ static int fill_packet(struct x264_ctx *c, struct video_packet *pkt, pkt->encoder.extra_size = c->encoder.extra_size; c->append_extra = true; } - for (int i = 0; i < nal_cnt; i++) { + for (i = 0; i < nal_cnt; i++) { x264_nal_t *nal = nals + i; da_push_back_array(c->packet_data, nal->p_payload, nal->i_payload); } @@ -341,6 +343,7 @@ static uint32_t get_random_number() static int live_open(struct media_source *ms, const char *name) { struct live_source_ctx *c = &g_live; + g_live.uvc_opened = false; if (c->uvc_opened) { logi("uvc already opened!\n"); return 0; @@ -350,7 +353,7 @@ static int live_open(struct media_source *ms, const char *name) c->conf.fps.num = 30; c->conf.fps.den = 1; c->conf.format = PIXEL_FORMAT_YUY2, - c->uvc = uvc_open(UVC_TYPE_V4L2, "/dev/video0", &c->conf); + c->uvc = uvc_open("/dev/video0", &c->conf); if (!c->uvc) { loge("uvc open failed!\n"); return -1; @@ -444,7 +447,7 @@ static int live_read(struct media_source *ms, void **data, size_t *len) struct media_source media_source_uvc = { .name = "uvc", .sdp_generate = sdp_generate, - .open = live_open, - .read = live_read, - .close = live_close, + ._open = live_open, + ._read = live_read, + ._close = live_close, }; diff --git a/gear-lib/librtsp/request_handle.c b/gear-lib/librtsp/request_handle.c index e4ed8ac..7f01ae9 100644 --- a/gear-lib/librtsp/request_handle.c +++ b/gear-lib/librtsp/request_handle.c @@ -91,13 +91,15 @@ int handle_rtsp_response(struct rtsp_request *req, int code, const char *msg) static int on_teardown(struct rtsp_request *req, char *url) { + struct rtsp_server *rc; + struct transport_session *ts; //int len = sock_send(req->fd, resp, strlen(resp)); if (-1 == parse_range(&req->range, (char *)req->raw->iov_base, req->raw->iov_len)) { loge("parse_range failed!\n"); return -1; } - struct rtsp_server *rc = req->rtsp_server; - struct transport_session *ts = transport_session_lookup(rc->transport_session_pool, req->session.id); + rc = req->rtsp_server; + ts = transport_session_lookup(rc->transport_session_pool, req->session.id); if (!ts) { loge("transport_session is NULL\n"); return handle_rtsp_response(req, 454, NULL); @@ -153,6 +155,7 @@ static int on_setup(struct rtsp_request *req, char *url) { char buf[RTSP_RESPONSE_LEN_MAX]; char transport[128]; + struct transport_session *ts; struct rtsp_server *rc = req->rtsp_server; if (-1 == parse_transport(&req->transport, (char *)req->raw->iov_base, req->raw->iov_len)) { @@ -171,7 +174,7 @@ static int on_setup(struct rtsp_request *req, char *url) sock_addr_ntop(req->transport.destination, req->client.ip); } - struct transport_session *ts = transport_session_lookup(rc->transport_session_pool, req->session.id); + ts = transport_session_lookup(rc->transport_session_pool, req->session.id); if (!ts) { ts = transport_session_create(rc->transport_session_pool, &req->transport); if (!ts) { @@ -210,18 +213,21 @@ static int on_play(struct rtsp_request *req, char *url) { int n = 0; char buf[RTSP_RESPONSE_LEN_MAX]; + struct rtsp_server *rc; + struct transport_session *ts; + struct media_source *ms; if (-1 == parse_range(&req->range, (char *)req->raw->iov_base, req->raw->iov_len)) { loge("parse_range failed!\n"); return -1; } - struct rtsp_server *rc = req->rtsp_server; - struct transport_session *ts = transport_session_lookup(rc->transport_session_pool, req->session.id); + rc = req->rtsp_server; + ts = transport_session_lookup(rc->transport_session_pool, req->session.id); if (!ts) { handle_rtsp_response(req, 454, NULL); return -1; } - struct media_source *ms = rtsp_media_source_lookup(url); + ms = rtsp_media_source_lookup(url); if (req->range.to > 0) { n += snprintf(buf+n, sizeof(buf)-n, "Range: npt=%.3f-%.3f\r\n", (float)(req->range.from / 1000.0f), (float)(req->range.to / 1000.0f)); diff --git a/gear-lib/librtsp/rtp.c b/gear-lib/librtsp/rtp.c index 4154665..b8cb29d 100644 --- a/gear-lib/librtsp/rtp.c +++ b/gear-lib/librtsp/rtp.c @@ -301,11 +301,12 @@ int rtp_ssrc(void) struct rtp_socket *rtp_socket_create(enum rtp_mode mode, int tcp_fd, const char* src_ip, const char *dst_ip) { + unsigned short i; struct rtp_socket *s = calloc(1, sizeof(struct rtp_socket)); if (!s) { return NULL; } - unsigned short i; + s->mode = mode; switch (mode) { case RTP_TCP: diff --git a/gear-lib/librtsp/rtp.h b/gear-lib/librtsp/rtp.h index 0fb416b..19bb83e 100644 --- a/gear-lib/librtsp/rtp.h +++ b/gear-lib/librtsp/rtp.h @@ -22,8 +22,11 @@ #ifndef LIBRTP_H #define LIBRTP_H +#include #include +#if defined (OS_LINUX) #include +#endif #include #ifdef __cplusplus diff --git a/gear-lib/librtsp/rtsp_parser.c b/gear-lib/librtsp/rtsp_parser.c index bd263a2..fa05681 100644 --- a/gear-lib/librtsp/rtsp_parser.c +++ b/gear-lib/librtsp/rtsp_parser.c @@ -64,8 +64,12 @@ int parse_rtsp_request(struct rtsp_request *req) int session_id_len = sizeof(req->session.id); int cur; char c; + char *p; const char *rtsp_prefix = "rtsp://"; int rtsp_prefix_len = sizeof(rtsp_prefix); + int parse_succeed = 0; + int i, j, k, k1, k2, n; + int num, org = 0; logi("rtsp request[%d]:\n==== C >>>> S ====\n%s==== C >>>> S ====\n", len, str); @@ -82,8 +86,7 @@ int parse_rtsp_request(struct rtsp_request *req) } // Then read everything up to the next space (or tab) as the command name: - int parse_succeed = 0; - int i; + for (i = 0; i < cmd_len - 1 && i < len; ++cur, ++i) { c = str[cur]; if (c == ' ' || c == '\t') { @@ -99,7 +102,7 @@ int parse_rtsp_request(struct rtsp_request *req) } // Skip over the prefix of any "rtsp://" or "rtsp:/" URL that follows: - int j = cur+1; + j = cur+1; while (j < len && (str[j] == ' ' || str[j] == '\t')) { ++j; // skip over any additional white space } @@ -125,12 +128,11 @@ int parse_rtsp_request(struct rtsp_request *req) // Look for the URL suffix (before the following "RTSP/"): parse_succeed = 0; - int k; for (k = cur+1; k < (len-5); ++k) { if (str[k] == 'R' && str[k+1] == 'T' && str[k+2] == 'S' && str[k+3] == 'P' && str[k+4] == '/') { while (--k >= cur && str[k] == ' ') {} // go back over all spaces before "RTSP/" - int k1 = k; + k1 = k; while (k1 > cur && str[k1] != '/') --k1; // ASSERT: At this point // cur: first space or slash after "host" or "host:port" @@ -138,7 +140,8 @@ int parse_rtsp_request(struct rtsp_request *req) // k1: last slash in the range [cur,k] // The URL suffix comes from [k1+1,k] // Copy "url_suffix": - int n = 0, k2 = k1+1; + n = 0; + k2 = k1+1; if (k2 <= k) { if (k - k1 + 1 > url_suffix_len) return -1; // there's no room while (k2 <= k) req->url_suffix[n++] = str[k2++]; @@ -161,7 +164,7 @@ int parse_rtsp_request(struct rtsp_request *req) if (!parse_succeed) { return -1; } - int org = 0; + org = 0; for (org = 0; org < k-7; org++) { req->url_origin[org] = str[i+org+1]; } @@ -169,7 +172,7 @@ int parse_rtsp_request(struct rtsp_request *req) // Look for "CSeq:" (mandatory, case insensitive), skip whitespace, // then read everything up to the next \r or \n as 'CSeq': parse_succeed = 0; - int n; + for (j = cur; j < (len-5); ++j) { if (strncasecmp("CSeq:", &str[j], 5) == 0) { j += 5; @@ -206,7 +209,7 @@ int parse_rtsp_request(struct rtsp_request *req) } req->session.id[n] = '\0'; req->session.timeout = 60000; - char *p = strchr(&str[j], ';'); + p = strchr(&str[j], ';'); if (p && 0 == strncmp("timeout=", p+1, 8)) { req->session.timeout = (int)(atof(p+9) * 1000); } @@ -220,7 +223,7 @@ int parse_rtsp_request(struct rtsp_request *req) if (strncasecmp("Content-Length:", &(str[j]), 15) == 0) { j += 15; while (j < len && (str[j] == ' ' || str[j] == '\t')) ++j; - int num; + if (sscanf(&str[j], "%u", &num) == 1) { req->content_len = num; } @@ -231,6 +234,8 @@ int parse_rtsp_request(struct rtsp_request *req) int parse_transport(struct transport_header *t, char *buf, int len) { + char const* fields; + char* field; // First, find "Transport:" while (1) { if (*buf == '\0') @@ -243,9 +248,9 @@ int parse_transport(struct transport_header *t, char *buf, int len) } // Then, run through each of the fields, looking for ones we handle: - char const* fields = buf + 10; + fields = buf + 10; while (*fields == ' ') ++fields; - char* field = (char *)calloc(1, strlen(fields)+1); + field = (char *)calloc(1, strlen(fields)+1); while (sscanf(fields, "%[^;\r\n]", field) == 1) { switch (*field) { case 'r': @@ -376,7 +381,9 @@ int parse_transport(struct transport_header *t, char *buf, int len) int parse_session(struct session_header *s, char *buf, int len) { + const char* p; int found = 0; + size_t n; while (1) { if (*buf == '\0') { break; @@ -394,10 +401,10 @@ int parse_session(struct session_header *s, char *buf, int len) return 0; } s->timeout = 60000; - const char* p; + p = strchr(buf, ';'); if (p) { - size_t n = (size_t)(p - buf); + n = (size_t)(p - buf); if (n >= sizeof(s->id)) return -1; @@ -407,7 +414,7 @@ int parse_session(struct session_header *s, char *buf, int len) if (0 == strncmp("timeout=", p+1, 8)) s->timeout = (int)(atof(p+9) * 1000); } else { - size_t n = strlen(buf); + n = strlen(buf); if (n >= sizeof(s->id)) return -1; memcpy(s->id, buf, n); @@ -533,17 +540,17 @@ struct time_smpte_t struct time_npt_t { - int64_t second; // [0,---) - int fraction; // [0,999] + int64_t second; // [0,---) + int fraction; // [0,999] }; struct time_clock_t { - int second; // [0,24*60*60) - int fraction; // [0,999] - int day; // [0,30] - int month; // [0,11] - int year; // [xxxx] + int second; // [0,24*60*60) + int fraction; // [0,999] + int day; // [0,30] + int month; // [0,11] + int year; // [xxxx] }; #define RANGE_SPECIAL ",;\r\n" @@ -557,7 +564,7 @@ static uint64_t utc_mktime(const struct tm *t) mon += 12; /* Puts Feb last since it has leap day */ year -= 1; } - + return ((((uint64_t) (year/4 - year/100 + year/400 + 367*mon/12 + t->tm_mday) + year*365 - 719499 @@ -568,56 +575,52 @@ static uint64_t utc_mktime(const struct tm *t) static inline const char* string_token_int(const char* str, int *value) { - *value = 0; - while ('0' <= *str && *str <= '9') - { - *value = (*value * 10) + (*str - '0'); - ++str; - } - return str; + *value = 0; + while ('0' <= *str && *str <= '9') { + *value = (*value * 10) + (*str - '0'); + ++str; + } + return str; } static inline const char* string_token_int64(const char* str, int64_t *value) { - *value = 0; - while ('0' <= *str && *str <= '9') - { - *value = (*value * 10) + (*str - '0'); - ++str; - } - return str; + *value = 0; + while ('0' <= *str && *str <= '9') { + *value = (*value * 10) + (*str - '0'); + ++str; + } + return str; } // smpte-time = 1*2DIGIT ":" 1*2DIGIT ":" 1*2DIGIT [ ":" 1*2DIGIT ][ "." 1*2DIGIT ] // hours:minutes:seconds:frames.subframes static const char* rtsp_header_range_smpte_time(const char* str, int *hours, int *minutes, int *seconds, int *frames, int *subframes) { - const char* p; + const char* p; - assert(str); - p = string_token_int(str, hours); - if(*p != ':') - return NULL; + assert(str); + p = string_token_int(str, hours); + if(*p != ':') + return NULL; - p = string_token_int(p+1, minutes); - if(*p != ':') - return NULL; + p = string_token_int(p+1, minutes); + if(*p != ':') + return NULL; - p = string_token_int(p+1, seconds); + p = string_token_int(p+1, seconds); - *frames = 0; - *subframes = 0; - if(*p == ':') - { - p = string_token_int(p+1, frames); - } + *frames = 0; + *subframes = 0; + if(*p == ':') { + p = string_token_int(p+1, frames); + } - if(*p == '.') - { - p = string_token_int(p+1, subframes); - } + if(*p == '.') { + p = string_token_int(p+1, subframes); + } - return p; + return p; } // 3.5 SMPTE Relative Timestamps (p16) @@ -630,36 +633,33 @@ static const char* rtsp_header_range_smpte_time(const char* str, int *hours, int // smpte-25=10:07:00-10:07:33:05.01 static int rtsp_header_range_smpte(const char* fields, struct range_header* range) { - const char *p; - int hours, minutes, seconds, frames, subframes; + const char *p; + int hours, minutes, seconds, frames, subframes; - assert(fields); - p = rtsp_header_range_smpte_time(fields, &hours, &minutes, &seconds, &frames, &subframes); - if(!p || '-' != *p) - return -1; + assert(fields); + p = rtsp_header_range_smpte_time(fields, &hours, &minutes, &seconds, &frames, &subframes); + if(!p || '-' != *p) + return -1; - range->from_value = RTSP_RANGE_TIME_NORMAL; - range->from = (hours%24)*3600 + (minutes%60)*60 + seconds; - range->from = range->from * 1000 + frames % 1000; + range->from_value = RTSP_RANGE_TIME_NORMAL; + range->from = (hours%24)*3600 + (minutes%60)*60 + seconds; + range->from = range->from * 1000 + frames % 1000; - assert('-' == *p); - if('\0' == p[1] || strchr(RANGE_SPECIAL, p[1])) - { - range->to_value = RTSP_RANGE_TIME_NOVALUE; - range->to = 0; - } - else - { - p = rtsp_header_range_smpte_time(p+1, &hours, &minutes, &seconds, &frames, &subframes); - if(!p ) return -1; - assert('\0' == p[0] || strchr(RANGE_SPECIAL, p[0])); + assert('-' == *p); + if('\0' == p[1] || strchr(RANGE_SPECIAL, p[1])) { + range->to_value = RTSP_RANGE_TIME_NOVALUE; + range->to = 0; + } else { + p = rtsp_header_range_smpte_time(p+1, &hours, &minutes, &seconds, &frames, &subframes); + if(!p ) return -1; + assert('\0' == p[0] || strchr(RANGE_SPECIAL, p[0])); - range->to_value = RTSP_RANGE_TIME_NORMAL; - range->to = (hours%24)*3600 + (minutes%60)*60 + seconds; - range->to = range->to * 1000 + frames % 1000; - } + range->to_value = RTSP_RANGE_TIME_NORMAL; + range->to = (hours%24)*3600 + (minutes%60)*60 + seconds; + range->to = range->to * 1000 + frames % 1000; + } - return 0; + return 0; } // npt-time = "now" | npt-sec | npt-hhmmss @@ -670,45 +670,45 @@ static int rtsp_header_range_smpte(const char* fields, struct range_header* rang // npt-ss = 1*2DIGIT ; 0-59 static const char* rtsp_header_range_npt_time(const char* str, uint64_t *seconds, int *fraction) { - const char* p; - int v1, v2; + const char* p; + int v1, v2; - assert(str); - p = strpbrk(str, "-\r\n"); - if(!str || (p-str==3 && 0==strncasecmp(str, "now", 3))) - { - *seconds = 0; // now - *fraction = -1; - } - else - { - p = string_token_int64(str, (int64_t*)seconds); - if(*p == ':') - { - // npt-hhmmss - p = string_token_int(p+1, &v1); - if(*p != ':') - return NULL; + assert(str); + p = strpbrk(str, "-\r\n"); + if(!str || (p-str==3 && 0==strncasecmp(str, "now", 3))) + { + *seconds = 0; // now + *fraction = -1; + } + else + { + p = string_token_int64(str, (int64_t*)seconds); + if(*p == ':') + { + // npt-hhmmss + p = string_token_int(p+1, &v1); + if(*p != ':') + return NULL; - p = string_token_int(p+1, &v2); + p = string_token_int(p+1, &v2); - assert(0 <= v1 && v1 < 60); - assert(0 <= v2 && v2 < 60); - *seconds = *seconds * 3600 + (v1%60)*60 + v2%60; - } - else - { - // npt-sec - //*seconds = hours; - } + assert(0 <= v1 && v1 < 60); + assert(0 <= v2 && v2 < 60); + *seconds = *seconds * 3600 + (v1%60)*60 + v2%60; + } + else + { + // npt-sec + //*seconds = hours; + } - if(*p == '.') - p = string_token_int(p+1, fraction); - else - *fraction = 0; - } + if(*p == '.') + p = string_token_int(p+1, fraction); + else + *fraction = 0; + } - return p; + return p; } // 3.6 Normal Play Time (p17) @@ -719,54 +719,54 @@ static const char* rtsp_header_range_npt_time(const char* str, uint64_t *seconds // npt=now- static int rtsp_header_range_npt(const char* fields, struct range_header* range) { - const char* p; - uint64_t seconds; - int fraction; + const char* p; + uint64_t seconds; + int fraction; - p = fields; - if('-' != *p) - { - p = rtsp_header_range_npt_time(p, &seconds, &fraction); - if(!p || '-' != *p) - return -1; + p = fields; + if('-' != *p) + { + p = rtsp_header_range_npt_time(p, &seconds, &fraction); + if(!p || '-' != *p) + return -1; - if(0 == seconds && -1 == fraction) - { - range->from_value = RTSP_RANGE_TIME_NOW; - range->from = 0L; - } - else - { - range->from_value = RTSP_RANGE_TIME_NORMAL; - range->from = seconds; - range->from = range->from * 1000 + fraction % 1000; - } - } - else - { - range->from_value = RTSP_RANGE_TIME_NOVALUE; - range->from = 0; - } + if(0 == seconds && -1 == fraction) + { + range->from_value = RTSP_RANGE_TIME_NOW; + range->from = 0L; + } + else + { + range->from_value = RTSP_RANGE_TIME_NORMAL; + range->from = seconds; + range->from = range->from * 1000 + fraction % 1000; + } + } + else + { + range->from_value = RTSP_RANGE_TIME_NOVALUE; + range->from = 0; + } - assert('-' == *p); - if('\0' == p[1] || strchr(RANGE_SPECIAL, p[1])) - { - assert('-' != *fields); - range->to_value = RTSP_RANGE_TIME_NOVALUE; - range->to = 0; - } - else - { - p = rtsp_header_range_npt_time(p+1, &seconds, &fraction); - if( !p ) return -1; - assert('\0' == p[0] || strchr(RANGE_SPECIAL, p[0])); + assert('-' == *p); + if('\0' == p[1] || strchr(RANGE_SPECIAL, p[1])) + { + assert('-' != *fields); + range->to_value = RTSP_RANGE_TIME_NOVALUE; + range->to = 0; + } + else + { + p = rtsp_header_range_npt_time(p+1, &seconds, &fraction); + if( !p ) return -1; + assert('\0' == p[0] || strchr(RANGE_SPECIAL, p[0])); - range->to_value = RTSP_RANGE_TIME_NORMAL; - range->to = seconds; - range->to = range->to * 1000 + fraction % 1000; - } + range->to_value = RTSP_RANGE_TIME_NORMAL; + range->to = seconds; + range->to = range->to * 1000 + fraction % 1000; + } - return 0; + return 0; } // utc-time = utc-date "T" utc-time "Z" @@ -774,36 +774,36 @@ static int rtsp_header_range_npt(const char* fields, struct range_header* range) // utc-time = 6DIGIT [ "." fraction ] ; < HHMMSS.fraction > static const char* rtsp_header_range_clock_time(const char* str, uint64_t *second, int *fraction) { - struct tm t; - const char* p; - int year, month, day; - int hour, minute; + struct tm t; + const char* p; + int year, month, day; + int hour, minute; - assert(str); - if(!str || 5 != sscanf(str, "%4d%2d%2dT%2d%2d", &year, &month, &day, &hour, &minute)) - return NULL; + assert(str); + if(!str || 5 != sscanf(str, "%4d%2d%2dT%2d%2d", &year, &month, &day, &hour, &minute)) + return NULL; - *second = 0; - *fraction = 0; - p = string_token_int64(str + 13, (int64_t*)second); + *second = 0; + *fraction = 0; + p = string_token_int64(str + 13, (int64_t*)second); assert(p); - if(*p == '.') - { - p = string_token_int(p+1, fraction); - } + if(*p == '.') + { + p = string_token_int(p+1, fraction); + } - memset(&t, 0, sizeof(t)); - t.tm_year = year - 1900; - t.tm_mon = month - 1; - t.tm_mday = day; - t.tm_hour = hour; - t.tm_min = minute; -// *second += mktime(&t); + memset(&t, 0, sizeof(t)); + t.tm_year = year - 1900; + t.tm_mon = month - 1; + t.tm_mday = day; + t.tm_hour = hour; + t.tm_min = minute; + // *second += mktime(&t); *second += utc_mktime(&t); -// assert('Z' == *p); -// assert('\0' == p[1] || strchr(RANGE_SPECIAL"-", p[1])); - return 'Z'==*p ? p+1 : p; + // assert('Z' == *p); + // assert('\0' == p[1] || strchr(RANGE_SPECIAL"-", p[1])); + return 'Z'==*p ? p+1 : p; } // 3.7 Absolute Time (p18) @@ -812,41 +812,42 @@ static const char* rtsp_header_range_clock_time(const char* str, uint64_t *secon // Range: clock=19961110T1925-19961110T2015 (p72) static int rtsp_header_range_clock(const char* fields, struct range_header* range) { - const char* p; - uint64_t second; - int fraction; + const char* p; + uint64_t second; + int fraction; - p = rtsp_header_range_clock_time(fields, &second, &fraction); - if(!p || '-' != *p) - return -1; + p = rtsp_header_range_clock_time(fields, &second, &fraction); + if(!p || '-' != *p) + return -1; - range->from_value = RTSP_RANGE_TIME_NORMAL; - range->from = second * 1000; - range->from += fraction % 1000; + range->from_value = RTSP_RANGE_TIME_NORMAL; + range->from = second * 1000; + range->from += fraction % 1000; - assert('-' == *p); - if('\0'==p[1] || strchr(RANGE_SPECIAL, p[1])) - { - range->to_value = RTSP_RANGE_TIME_NOVALUE; - range->to = 0; - } - else - { - p = rtsp_header_range_clock_time(p+1, &second, &fraction); - if( !p ) return -1; + assert('-' == *p); + if('\0'==p[1] || strchr(RANGE_SPECIAL, p[1])) + { + range->to_value = RTSP_RANGE_TIME_NOVALUE; + range->to = 0; + } + else + { + p = rtsp_header_range_clock_time(p+1, &second, &fraction); + if( !p ) return -1; - range->to_value = RTSP_RANGE_TIME_NORMAL; - range->to = second * 1000; - range->to += (unsigned int)fraction % 1000; - } + range->to_value = RTSP_RANGE_TIME_NORMAL; + range->to = second * 1000; + range->to += (unsigned int)fraction % 1000; + } - return 0; + return 0; } int parse_range(struct range_header *range, char* buf, int len) { int r = 0; int found = 0; + char *field; while (1) { if (*buf == '\0') { break; @@ -863,57 +864,45 @@ int parse_range(struct range_header *range, char* buf, int len) if (!found) { return 0; } - char *field = buf; - range->time = 0L; - while(field && 0 == r) - { - if(0 == strncasecmp("clock=", field, 6)) - { - range->type = RTSP_RANGE_CLOCK; - r = rtsp_header_range_clock(field+6, range); - } - else if(0 == strncasecmp("npt=", field, 4)) - { - range->type = RTSP_RANGE_NPT; - r = rtsp_header_range_npt(field+4, range); - } - else if(0 == strncasecmp("smpte=", field, 6)) - { - range->type = RTSP_RANGE_SMPTE; - r = rtsp_header_range_smpte(field+6, range); - if(RTSP_RANGE_TIME_NORMAL == range->from_value) - range->from = (range->from/1000 * 1000) + (1000/30 * (range->from%1000)); // frame to ms - if(RTSP_RANGE_TIME_NORMAL == range->to_value) - range->to = (range->to/1000 * 1000) + (1000/30 * (range->to%1000)); // frame to ms - } - else if(0 == strncasecmp("smpte-30-drop=", field, 15)) - { - range->type = RTSP_RANGE_SMPTE_30; - r = rtsp_header_range_smpte(field+15, range); - if(RTSP_RANGE_TIME_NORMAL == range->from_value) - range->from = (range->from/1000 * 1000) + (1000/30 * (range->from%1000)); // frame to ms - if(RTSP_RANGE_TIME_NORMAL == range->to_value) - range->to = (range->to/1000 * 1000) + (1000/30 * (range->to%1000)); // frame to ms - } - else if(0 == strncasecmp("smpte-25=", field, 9)) - { - range->type = RTSP_RANGE_SMPTE_25; - r = rtsp_header_range_smpte(field+9, range); - if(RTSP_RANGE_TIME_NORMAL == range->from_value) - range->from = (range->from/1000 * 1000) + (1000/25 * (range->from%1000)); // frame to ms - if(RTSP_RANGE_TIME_NORMAL == range->to_value) - range->to = (range->to/1000 * 1000) + (1000/25 * (range->to%1000)); // frame to ms - } - else if(0 == strncasecmp("time=", field, 5)) - { - if (rtsp_header_range_clock_time(field + 5, &range->time, &r)) - range->time = range->time * 1000 + r % 1000; - } - - field = strchr(field, ';'); - if(field) - ++field; - } + field = buf; + range->time = 0L; + while (field && 0 == r) { + if (0 == strncasecmp("clock=", field, 6)) { + range->type = RTSP_RANGE_CLOCK; + r = rtsp_header_range_clock(field+6, range); + } else if (0 == strncasecmp("npt=", field, 4)) { + range->type = RTSP_RANGE_NPT; + r = rtsp_header_range_npt(field+4, range); + } else if (0 == strncasecmp("smpte=", field, 6)) { + range->type = RTSP_RANGE_SMPTE; + r = rtsp_header_range_smpte(field+6, range); + if (RTSP_RANGE_TIME_NORMAL == range->from_value) + range->from = (range->from/1000 * 1000) + (1000/30 * (range->from%1000)); // frame to ms + if (RTSP_RANGE_TIME_NORMAL == range->to_value) + range->to = (range->to/1000 * 1000) + (1000/30 * (range->to%1000)); // frame to ms + } else if(0 == strncasecmp("smpte-30-drop=", field, 15)) { + range->type = RTSP_RANGE_SMPTE_30; + r = rtsp_header_range_smpte(field+15, range); + if (RTSP_RANGE_TIME_NORMAL == range->from_value) + range->from = (range->from/1000 * 1000) + (1000/30 * (range->from%1000)); // frame to ms + if (RTSP_RANGE_TIME_NORMAL == range->to_value) + range->to = (range->to/1000 * 1000) + (1000/30 * (range->to%1000)); // frame to ms + } else if(0 == strncasecmp("smpte-25=", field, 9)) { + range->type = RTSP_RANGE_SMPTE_25; + r = rtsp_header_range_smpte(field+9, range); + if(RTSP_RANGE_TIME_NORMAL == range->from_value) + range->from = (range->from/1000 * 1000) + (1000/25 * (range->from%1000)); // frame to ms + if(RTSP_RANGE_TIME_NORMAL == range->to_value) + range->to = (range->to/1000 * 1000) + (1000/25 * (range->to%1000)); // frame to ms + } else if(0 == strncasecmp("time=", field, 5)) { + if (rtsp_header_range_clock_time(field + 5, &range->time, &r)) + range->time = range->time * 1000 + r % 1000; + } - return r; + field = strchr(field, ';'); + if (field) + ++field; + } + + return r; } diff --git a/gear-lib/librtsp/sdp.c b/gear-lib/librtsp/sdp.c index 677ab7a..5cac079 100644 --- a/gear-lib/librtsp/sdp.c +++ b/gear-lib/librtsp/sdp.c @@ -19,11 +19,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. ******************************************************************************/ -#include "sdp.h" +#include #include #include #include #include +#include "sdp.h" #define SDP_TOOL_NAME ((const char *)"ipcam rtsp") #define SDP_TOOL_VERSION ((const char *)"version 2016.05.22") @@ -267,21 +268,6 @@ const char* SDP_LIVE_FMT = int get_sdp(struct media_source *ms, char *sdp, size_t len) { - int sdp_len = 0; - char sdp_filter[128]; - char sdp_range[128]; - const char *sdp_media = "m=video 0 RTP/AVP 33\r\nc=IN IP4 0.0.0.0\r\nb=AS:5000\r\na=control:track1"; - - float dur = duration(); - if (dur == 0.0) { - snprintf(sdp_range, sizeof(sdp_range), "%s", "a=range:npt=0-\r\n"); - } else if (dur > 0.0) { - snprintf(sdp_range, sizeof(sdp_range), "%s", "a=range:npt=0-%.3f\r\n"); - } else { // subsessions have differing durations, so "a=range:" lines go there - snprintf(sdp_range, sizeof(sdp_range), "%s", ""); - } - snprintf(sdp_filter, sizeof(sdp_filter), SDP_FILTER_FMT, RTSP_SERVER_IP); - char const* const sdp_prefix_fmt = "v=0\r\n" "o=- %ld%06ld %d IN IP4 %s\r\n" @@ -296,6 +282,20 @@ int get_sdp(struct media_source *ms, char *sdp, size_t len) "a=x-qt-text-nam:%s\r\n" "a=x-qt-text-inf:%s\r\n" "%s"; + int sdp_len = 0; + char sdp_filter[128]; + char sdp_range[128]; + const char *sdp_media = "m=video 0 RTP/AVP 33\r\nc=IN IP4 0.0.0.0\r\nb=AS:5000\r\na=control:track1"; + + float dur = duration(); + if (dur == 0.0) { + snprintf(sdp_range, sizeof(sdp_range), "%s", "a=range:npt=0-\r\n"); + } else if (dur > 0.0) { + snprintf(sdp_range, sizeof(sdp_range), "%s", "a=range:npt=0-%.3f\r\n"); + } else { // subsessions have differing durations, so "a=range:" lines go there + snprintf(sdp_range, sizeof(sdp_range), "%s", ""); + } + snprintf(sdp_filter, sizeof(sdp_filter), SDP_FILTER_FMT, RTSP_SERVER_IP); sdp_len = strlen(sdp_prefix_fmt) + 20 + 6 + 20 + strlen("127.0.0.1") diff --git a/gear-lib/librtsp/test_librtsp.c b/gear-lib/librtsp/test_librtsp.c index c829e55..d461cdf 100644 --- a/gear-lib/librtsp/test_librtsp.c +++ b/gear-lib/librtsp/test_librtsp.c @@ -19,10 +19,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. ******************************************************************************/ +#include "librtsp.h" #include #include #include -#include "librtsp.h" int main(int argc, char **argv) { diff --git a/gear-lib/librtsp/transport_session.c b/gear-lib/librtsp/transport_session.c index 3a6bb7f..55bfc7e 100644 --- a/gear-lib/librtsp/transport_session.c +++ b/gear-lib/librtsp/transport_session.c @@ -19,14 +19,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. ******************************************************************************/ -#include "transport_session.h" -#include "media_source.h" -#include "rtp.h" +#include #include #include #include #include #include +#include "transport_session.h" +#include "media_source.h" +#include "rtp.h" + #include #include #include @@ -103,40 +105,45 @@ static void *send_thread(struct thread *t, void *ptr) struct media_source *ms = ts->media_source; void *data = NULL; size_t len = 0; + unsigned int ssrc, seq; + uint64_t pts; int ret; - if (-1 == ms->open(ms, "sample.264")) { + struct media_packet *mpkt; + struct video_packet *vpkt; + struct rtp_packet *rpkt; + if (-1 == ms->_open(ms, "sample.264")) { loge("open failed!\n"); return NULL; } ms->is_active = true; - unsigned int ssrc = (unsigned int)rtp_ssrc(); - uint64_t pts = time_now_msec(); - unsigned int seq = ssrc; + ssrc = (unsigned int)rtp_ssrc(); + pts = time_now_msec(); + seq = ssrc; logd("rtp send thread %s created\n", t->name); while (t->run) { - if (-1 == ms->read(ms, &data, &len) || data == NULL) { + if (-1 == ms->_read(ms, &data, &len) || data == NULL) { loge("read failed!\n"); sleep(1); continue; } - struct media_packet *pkt = data; - switch (pkt->type) { + mpkt = data; + switch (mpkt->type) { case MEDIA_TYPE_AUDIO: logd("MEDIA_TYPE_AUDIO\n"); break; case MEDIA_TYPE_VIDEO: { logd("MEDIA_TYPE_VIDEO\n"); - struct video_packet *vpkt = pkt->video; - struct rtp_packet *pkt = rtp_packet_create(RTP_PT_H264, vpkt->size, seq, ssrc); - if (!pkt) { + vpkt = mpkt->video; + rpkt = rtp_packet_create(RTP_PT_H264, vpkt->size, seq, ssrc); + if (!rpkt) { loge("rtp_packet_create failed!\n"); break; } pts = get_ms_time_v(vpkt, vpkt->dts); logd("rtp_packet_create video size=%d, pts=%d\n", vpkt->size, pts); - ret = rtp_payload_h264_encode(ts->rtp->sock, pkt, vpkt->data, vpkt->size, pts); - seq = pkt->header.seq; - rtp_packet_destroy(pkt); + ret = rtp_payload_h264_encode(ts->rtp->sock, rpkt, vpkt->data, vpkt->size, pts); + seq = rpkt->header.seq; + rtp_packet_destroy(rpkt); if (ret == -1) { loge("rtp_payload_h264_encode failed!\n"); t->run = false; @@ -148,15 +155,16 @@ static void *send_thread(struct thread *t, void *ptr) } } ms->is_active = false; - ms->close(ms); + ms->_close(ms); return NULL; } static void on_recv(int fd, void *arg) { + int ret; char buf[2048]; memset(buf, 0, sizeof(buf)); - int ret = sock_recv(fd, buf, 2048); + ret = sock_recv(fd, buf, 2048); if (ret > 0) { rtcp_parse(buf, ret); } else if (ret == 0) { diff --git a/gear-lib/libsock/CMakeLists.txt b/gear-lib/libsock/CMakeLists.txt new file mode 100644 index 0000000..12ab42c --- /dev/null +++ b/gear-lib/libsock/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR} ${GEVENT_INCLUDE_DIR} ${DARRAY_INCLUDE_DIR} ${THREAD_INCLUDE_DIR}) +AUX_SOURCE_DIRECTORY(. SOURCE_FILES) + +ADD_LIBRARY(sock ${SOURCE_FILES}) diff --git a/gear-lib/libsock/Makefile b/gear-lib/libsock/Makefile index 967dd19..bf202cb 100644 --- a/gear-lib/libsock/Makefile +++ b/gear-lib/libsock/Makefile @@ -72,7 +72,7 @@ SHARED := -shared LDFLAGS := $($(ARCH)_LDFLAGS) LDFLAGS += -pthread ifeq ($(ENABLE_SOCK_EXT), 1) -LDFLAGS += -L$(OUTLIBPATH)/lib/gear-lib -lgevent -lthread +LDFLAGS += -L$(OUTLIBPATH)/lib/gear-lib -lposix -lgevent -lthread endif ifeq ($(ENABLE_PTCP), 1) LDFLAGS += -L$(OUTLIBPATH)/lib/gear-lib -lptcp diff --git a/gear-lib/libthread/CMakeLists.txt b/gear-lib/libthread/CMakeLists.txt new file mode 100644 index 0000000..fdd98ea --- /dev/null +++ b/gear-lib/libthread/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR}) +AUX_SOURCE_DIRECTORY(. SOURCE_FILES) + +ADD_LIBRARY(thread ${SOURCE_FILES}) diff --git a/gear-lib/libtime/CMakeLists.txt b/gear-lib/libtime/CMakeLists.txt new file mode 100644 index 0000000..6f4ee15 --- /dev/null +++ b/gear-lib/libtime/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR}) +AUX_SOURCE_DIRECTORY(. SOURCE_FILES) + +ADD_LIBRARY(time ${SOURCE_FILES}) diff --git a/gear-lib/libuvc/CMakeLists.txt b/gear-lib/libuvc/CMakeLists.txt new file mode 100644 index 0000000..167fbf6 --- /dev/null +++ b/gear-lib/libuvc/CMakeLists.txt @@ -0,0 +1,14 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.0...3.20) +PROJECT(gear-lib) + +INCLUDE_DIRECTORIES(. ${POSIX_INCLUDE_DIR} ${MEDIA_IO_INCLUDE_DIR} ${THREAD_INCLUDE_DIR}) + +LIST(APPEND SOURCE_FILES libuvc.c) + +IF (DEFINED OS_LINUX) +LIST(APPEND SOURCE_FILES v4l2.c) +ELSEIF (DEFINED OS_WINDOWS) +LIST(APPEND SOURCE_FILES dshow.c) +ENDIF () + +ADD_LIBRARY(uvc ${SOURCE_FILES}) diff --git a/gear-lib/libuvc/dummy.c b/gear-lib/libuvc/dummy.c index 30cde5f..67111cb 100644 --- a/gear-lib/libuvc/dummy.c +++ b/gear-lib/libuvc/dummy.c @@ -330,8 +330,8 @@ static void uvc_dummy_close(struct uvc_ctx *uvc) } struct uvc_ops dummy_ops = { - .open = uvc_dummy_open, - .close = uvc_dummy_close, + ._open = uvc_dummy_open, + ._close = uvc_dummy_close, .ioctl = uvc_dummy_ioctl, .start_stream = uvc_dummy_start_stream, .stop_stream = uvc_dummy_stop_stream, diff --git a/gear-lib/libuvc/libuvc.c b/gear-lib/libuvc/libuvc.c index 34eeece..a58b8d3 100644 --- a/gear-lib/libuvc/libuvc.c +++ b/gear-lib/libuvc/libuvc.c @@ -35,8 +35,17 @@ extern struct uvc_ops v4l2_ops; extern struct uvc_ops dshow_ops; #endif -static struct uvc_ops *uvc_ops[] = { +enum uvc_type { +#if defined (OS_LINUX) + UVC_TYPE_V4L2, +#elif defined (OS_WINDOWS) + UVC_TYPE_DSHOW, +#endif + UVC_TYPE_DUMMY, + UVC_TYPE_MAX, +}; +static struct uvc_ops *uvc_ops[] = { #if defined (OS_LINUX) &dummy_ops, &v4l2_ops, @@ -46,10 +55,21 @@ static struct uvc_ops *uvc_ops[] = { NULL, }; -struct uvc_ctx *uvc_open(enum uvc_type type, const char *dev, struct uvc_config *conf) +struct uvc_ctx *uvc_open(const char *dev, struct uvc_config *conf) { + enum uvc_type type; struct uvc_ctx *uvc; - if (!dev || !conf) { +#if defined (OS_LINUX) + type = UVC_TYPE_V4L2; +#elif defined (OS_WINDOWS) + type = UVC_TYPE_DSHOW; +#endif + if (!dev) { + type = UVC_TYPE_DUMMY; + dev = conf->dev_name; + printf("%s:%d open dummy device\n", __func__, __LINE__); + } + if (!conf) { printf("%s:%d invalid paraments!\n", __func__, __LINE__); return NULL; } diff --git a/gear-lib/libuvc/libuvc.h b/gear-lib/libuvc/libuvc.h index 8c91dc8..dc9615f 100644 --- a/gear-lib/libuvc/libuvc.h +++ b/gear-lib/libuvc/libuvc.h @@ -37,16 +37,6 @@ extern "C" { #endif -enum uvc_type { -#if defined (OS_LINUX) - UVC_TYPE_DUMMY = 0, - UVC_TYPE_V4L2, -#elif defined (OS_WINDOWS) - UVC_TYPE_DSHOW, -#endif - UVC_TYPE_MAX, -}; - struct uvc_ctx; struct uvc_ops; typedef int (video_frame_cb)(struct uvc_ctx *c, struct video_frame *frame); @@ -56,6 +46,7 @@ struct uvc_config { uint32_t height; rational_t fps; enum pixel_format format; + char *dev_name; }; struct uvc_image_quality { @@ -115,7 +106,7 @@ struct uvc_ops { int (*query_frame)(struct uvc_ctx *c, struct video_frame *frame); }; -GEAR_API struct uvc_ctx *uvc_open(enum uvc_type type, const char *dev, struct uvc_config *conf); +GEAR_API struct uvc_ctx *uvc_open(const char *dev, struct uvc_config *conf); GEAR_API int uvc_ioctl(struct uvc_ctx *c, unsigned long int cmd, ...); GEAR_API void uvc_close(struct uvc_ctx *c); diff --git a/gear-lib/libuvc/test_libuvc.c b/gear-lib/libuvc/test_libuvc.c index 5b9a5fd..e57f559 100644 --- a/gear-lib/libuvc/test_libuvc.c +++ b/gear-lib/libuvc/test_libuvc.c @@ -62,13 +62,7 @@ int v4l2_test() {30, 1}, PIXEL_FORMAT_YUY2, }; - enum uvc_type type; -#if defined (OS_LINUX) - type = UVC_TYPE_V4L2; -#elif defined (OS_WINDOWS) - type = UVC_TYPE_DSHOW; -#endif - uvc = uvc_open(type, VIDEO_DEV, &conf); + uvc = uvc_open(VIDEO_DEV, &conf); if (!uvc) { printf("uvc_open failed!\n"); return -1; @@ -104,8 +98,9 @@ int dummy_test() 240, {30, 1}, PIXEL_FORMAT_YUY2, + "sample_320x240_yuv422p.yuv", }; - struct uvc_ctx *uvc = uvc_open(UVC_TYPE_DUMMY, "sample_320x240_yuv422p.yuv", &conf); + struct uvc_ctx *uvc = uvc_open(NULL, &conf); if (!uvc) { printf("uvc_open failed!\n"); return -1; diff --git a/gear-lib/libuvc/v4l2.c b/gear-lib/libuvc/v4l2.c index 784cf4a..f0c61eb 100644 --- a/gear-lib/libuvc/v4l2.c +++ b/gear-lib/libuvc/v4l2.c @@ -1004,8 +1004,8 @@ static int uvc_v4l2_ioctl(struct uvc_ctx *uvc, unsigned long int cmd, ...) } struct uvc_ops v4l2_ops = { - .open = uvc_v4l2_open, - .close = uvc_v4l2_close, + ._open = uvc_v4l2_open, + ._close = uvc_v4l2_close, .ioctl = uvc_v4l2_ioctl, .start_stream = uvc_v4l2_start_stream, .stop_stream = uvc_v4l2_stop_stream, diff --git a/gear-lib/libvector/libvector.h b/gear-lib/libvector/libvector.h index ed70f6b..44f2109 100644 --- a/gear-lib/libvector/libvector.h +++ b/gear-lib/libvector/libvector.h @@ -78,6 +78,8 @@ void *_vector_at(struct vector *v, int pos); #if defined (__linux__) || defined (__CYGWIN__) #define vector_create(type_t) \ ({type_t t;struct vector *v = _vector_create(sizeof(t)); v;}) +#else +#define vector_create(type_t) _vector_create(sizeof(type_t)) #endif void vector_destroy(struct vector *v); int vector_empty(struct vector *v); @@ -90,6 +92,8 @@ void vector_pop_back(struct vector *v); memcpy(&__tmp, vector_last(v), v->type_size); \ &__tmp; \ }) +#else +#define vector_back(v, type_t) (type_t *)vector_last(v) #endif #define vector_iter_valuep(vector, iter, type_t) \