diff --git a/.idea/deployment.xml b/.idea/deployment.xml new file mode 100644 index 00000000..1a6c50e1 --- /dev/null +++ b/.idea/deployment.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CC_SDK/CMakeLists.txt b/CC_SDK/CMakeLists.txt index c9719f1b..9b5c2961 100644 --- a/CC_SDK/CMakeLists.txt +++ b/CC_SDK/CMakeLists.txt @@ -2,18 +2,23 @@ cmake_minimum_required(VERSION 3.0...3.5) if(CMAKE_SYSTEM_NAME STREQUAL "OHOS") message(WARNING "当前构建系统为 OpenHarmony") - set(OS_OHOS TRUE PARENT_SCOPE) + set(OS_OHOS ON PARENT_SCOPE) else() - set(OS_OHOS FALSE PARENT_SCOPE) + set(OS_OHOS OFF PARENT_SCOPE) endif() if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm|ARM|Armv[0-9]+") message(STATUS "Target architecture is ARM") message(STATUS "目标架构是 ARM") - set(ARCH_ARM TRUE) + set(ARCH_ARM ON) + if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64|ARM64") + set(ARM64 ON PARENT_SCOPE) + elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm|ARM") + set(ARM32 ON PARENT_SCOPE) + endif () elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i386|i686|x86_64|amd64|AMD64") message(STATUS "Target architecture is x86/x86_64") message(STATUS "目标架构是 x86/x86_64") - set(ARCH_X86 TRUE) + set(ARCH_X86 ON PARENT_SCOPE) else() message(WARNING "Unknown architecture: ${CMAKE_SYSTEM_PROCESSOR}") endif() @@ -21,11 +26,36 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(ENABLE_INSTALL_RULES OFF CACHE BOOL "Disable install rules for cppp-reiconv") add_subdirectory(Environment/cppp-reiconv) -add_subdirectory(Environment/CSerialPort) + add_subdirectory(Environment/mirrors_nlohmann_json) -add_subdirectory(Environment/portaudio) add_subdirectory(Environment/openssl-cmake) +option(SerialPort "CC_SerialPort_OAF" OFF) +if (SerialPort) + message(STATUS "CSerialPort ON") + add_subdirectory(Environment/CSerialPort) + set(SerialPort_STATIC + src/Module/Comm/CCSerialPort.cpp + ) +endif () + +option(AUDIO_IO "CC_Audio_IO_OAF" OFF) +if (AUDIO_IO) + message(STATUS "AUDIO_IO ON") + set(AUDIO_IO_STATIC + src/Module/Multimedia/CCAudioIO.cpp + ) +endif () + +option(PORTAUDIO "CC_PORTAUDIO_OAF" OFF) +if (PORTAUDIO) + message(STATUS "PORTAUDIO ON") + add_subdirectory(Environment/portaudio) + set(portaudio_STATIC + src/Module/Multimedia/CCAudio.cpp + ) +endif () + option(FFMPEG "CC_FFMPEG_OAF" OFF) if (FFMPEG) message(STATUS "FFMPEG ON") @@ -50,48 +80,113 @@ if(LIBRTC) add_subdirectory(Environment/libdatachannel) endif() +option(LIBJUICE "CC_LIBJUICE_OAF" OFF) +if(LIBJUICE) + if (NOT LIBRTC) + add_subdirectory(Environment/libjuice) + endif () +endif() + +option(IMGUI "CC_ImGui_OAF" OFF) +if (IMGUI) + message(STATUS "IMGUI ON") + set(IMGUI_SOURCES + src/Module/Window/ImGui/imgui.cpp + src/Module/Window/ImGui/imgui_draw.cpp + src/Module/Window/ImGui/imgui_impl_glfw.cpp + src/Module/Window/ImGui/imgui_impl_opengl3.cpp + src/Module/Window/ImGui/imgui_impl_win32.cpp + src/Module/Window/ImGui/imgui_tables.cpp + src/Module/Window/ImGui/imgui_widgets.cpp + src/Module/Window/CWidget.cpp + src/Module/Window/CApplication.cpp + src/Module/Window/Control/Button.cpp + src/Module/Window/Control/Combox.cpp + src/Module/Window/Control/Comboxs.cpp + src/Module/Window/Control/Image.cpp + src/Module/Window/Control/ImageButton.cpp + src/Module/Window/Control/Label.cpp + src/Module/Window/Control/Panel.cpp + src/Module/Window/Control/SliderBar.cpp + src/Module/Window/Control/SwitchBool.cpp + src/Module/Window/Control/TextBox.cpp + src/Module/Window/Drive/Drive.cpp + ) +endif () + option(GLFW "CC_GLFW_OAF" OFF) if (GLFW) + message(STATUS "GLFW ON") add_subdirectory(Environment/glfw) endif () +option(ZLIB "CC_ZLIB_OAF" OFF) +if (ZLIB) + add_subdirectory(Environment/zlib) + set(MINIZIP_SOURCES + Environment/zlib/contrib/minizip/ioapi.c + Environment/zlib/contrib/minizip/iowin32.c + Environment/zlib/contrib/minizip/unzip.c + Environment/zlib/contrib/minizip/zip.c + ) + add_library(minizip STATIC ${MINIZIP_SOURCES}) + target_include_directories(minizip PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/Environment/zlib + ${CMAKE_CURRENT_SOURCE_DIR}/Environment/zlib/contrib/minizip + ) + target_link_libraries(minizip zlib) +endif () -set(INC_DIR ${PROJECT_SOURCE_DIR}/CC_SDK/Include) -set(LINK_DIR ${PROJECT_SOURCE_DIR}/CC_SDK/Lib) -set(LINK_DLL_DIR ${PROJECT_SOURCE_DIR}/CC_SDK/Bin) -set(LIB_WX_D ${PROJECT_SOURCE_DIR}/CC_SDK/Lib/wx/libwxmsw32ud.a) -set(LIB_WX_R ${PROJECT_SOURCE_DIR}/CC_SDK/Lib/wx/libwxmsw32u.a) +set(INC_DIR ${CMAKE_CURRENT_LIST_DIR}/Include) +set(LINK_DIR ${CMAKE_CURRENT_LIST_DIR}/Lib) +set(LINK_DLL_DIR ${CMAKE_CURRENT_LIST_DIR}/Bin) +set(LIB_WX_D ${CMAKE_CURRENT_LIST_DIR}/Lib/wx/libwxmsw32ud.a) +set(LIB_WX_R ${CMAKE_CURRENT_LIST_DIR}/Lib/wx/libwxmsw32u.a) set(CC_API_INC - ${PROJECT_SOURCE_DIR}/CC_SDK/Include - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/basic - ${PROJECT_SOURCE_DIR}/CC_SDK/Environment/CSerialPort/include - ${PROJECT_SOURCE_DIR}/CC_SDK/Environment/mirrors_nlohmann_json/include - ${PROJECT_SOURCE_DIR}/CC_SDK/Environment/mirrors_nlohmann_json/include/nlohmann - ${PROJECT_SOURCE_DIR}/CC_SDK/Environment/portaudio/include - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/Multimedia - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/CCServlet/SQL - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/Module - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/Module/File - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/Module/Comm - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/Module/Data - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/Module/Multimedia - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/Module/IO - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/CCServlet/ - ${PROJECT_SOURCE_DIR}/CC_SDK/Environment/ImGUI/IMUI/Control - ${PROJECT_SOURCE_DIR}/CC_SDK/Environment/ImGUI/IMUI/Drive - ${PROJECT_SOURCE_DIR}/CC_SDK/Environment/ImGUI/IMUI/ImGui - ${PROJECT_SOURCE_DIR}/CC_SDK/Environment/ImGUI/IMUI/WindowOS - ${PROJECT_SOURCE_DIR}/CC_SDK/Environment/ImGUI/glfw/include - ${PROJECT_SOURCE_DIR}/CC_SDK/Environment/mysql-9.0.1/include - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/CCServlet/openssl - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/Module/Comm/WebSocket - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/Module/Comm/WebRTC - ${PROJECT_SOURCE_DIR}/CC_SDK/Include/Module/Window + ${CMAKE_CURRENT_LIST_DIR}/Include + ${CMAKE_CURRENT_LIST_DIR}/Include/basic + ${CMAKE_CURRENT_LIST_DIR}/Environment/mirrors_nlohmann_json/include + ${CMAKE_CURRENT_LIST_DIR}/Environment/mirrors_nlohmann_json/include/nlohmann + ${CMAKE_CURRENT_LIST_DIR}/Include/CCServlet/SQL + ${CMAKE_CURRENT_LIST_DIR}/Include/Module + ${CMAKE_CURRENT_LIST_DIR}/Include/Module/File + ${CMAKE_CURRENT_LIST_DIR}/Include/Module/Comm + ${CMAKE_CURRENT_LIST_DIR}/Include/Module/Data + ${CMAKE_CURRENT_LIST_DIR}/Include/Module/IO + ${CMAKE_CURRENT_LIST_DIR}/Include/CCServlet + ${CMAKE_CURRENT_LIST_DIR}/Environment/ImGUI/IMUI/WindowOS + ${CMAKE_CURRENT_LIST_DIR}/Environment/ImGUI/glfw/include + ${CMAKE_CURRENT_LIST_DIR}/Environment/mysql-9.0.1/include + ${CMAKE_CURRENT_LIST_DIR}/Include/CCServlet/openssl + ${CMAKE_CURRENT_LIST_DIR}/Include/Module/Comm/WebSocket + ${CMAKE_CURRENT_LIST_DIR}/Include/Module/Window + ${CMAKE_CURRENT_LIST_DIR}/Include/Module/Window/Control + ${CMAKE_CURRENT_LIST_DIR}/Include/Module/Window/Drive + ${CMAKE_CURRENT_LIST_DIR}/Include/Module/Window/ImGui + ${CMAKE_CURRENT_LIST_DIR}/Include/Module/Comm/Socket ) +if (AUDIO_IO) + list(APPEND CC_API_INC + ${CMAKE_CURRENT_LIST_DIR}/Include/Module/Multimedia + ) +endif () + +if (PORTAUDIO) + list(APPEND CC_API_INC + ${CMAKE_CURRENT_LIST_DIR}/Include/Module/Multimedia + ${CMAKE_CURRENT_LIST_DIR}/Include/Multimedia + ${CMAKE_CURRENT_LIST_DIR}/Environment/portaudio/include + ) +endif () + +if (SerialPort) + list(APPEND CC_API_INC ${CMAKE_CURRENT_LIST_DIR}/Environment/CSerialPort/include) +endif () + if (FFMPEG) list(APPEND CC_API_INC ${CC_FFMPEG_INC}) endif () @@ -106,15 +201,48 @@ endif () if (LIBRTC) list(APPEND CC_API_INC ${CMAKE_CURRENT_LIST_DIR}/Environment/libdatachannel/include) + list(APPEND CC_API_INC ${CMAKE_CURRENT_LIST_DIR}/Include/Module/Comm/WebRTC) + set(LIBRTC_STATIC src/Module/Comm/WebRTC/CCWebRTC.cpp) +endif () + +if (LIBJUICE) + if (NOT LIBRTC) + list(APPEND CC_API_INC ${CMAKE_CURRENT_LIST_DIR}/Environment/libjuice/include) + endif () + set(CC_DataChannel + src/Module/Comm/DataChannel/RTCPeerConnection.cpp + ) endif () if (GLFW) list(APPEND CC_API_INC ${CMAKE_CURRENT_LIST_DIR}/Environment/glfw/include) endif () +if (IMGUI) + +endif () + +if (ZLIB) + list(APPEND CC_API_INC ${CMAKE_CURRENT_LIST_DIR}/Environment/zlib/contrib/minizip) + list(APPEND CC_API_INC ${CMAKE_CURRENT_LIST_DIR}/Environment/zlib/contrib) + list(APPEND CC_API_INC ${CMAKE_CURRENT_LIST_DIR}/Environment/zlib) + list(APPEND CC_API_INC ${CMAKE_BINARY_DIR}/CC_SDK/Environment/zlib) + #list(APPEND CC_API_INC ${CMAKE_CURRENT_LIST_DIR}/Environment/zlib/include) + list(APPEND CC_API_INC ${CMAKE_CURRENT_LIST_DIR}/Include/Environment/zlib) + set(ZLIB_Module + Include/Environment/zlib/CCZip.cpp + Include/Environment/zlib/CCDataFormat.cpp + Include/Module/Multimedia/CCAudioIO.h + src/Module/Multimedia/CCAudioIO.cpp + Include/Module/Window/Control/Icon.h + ) +endif () + + option(APIS "APIS" ON) if (APIS) + add_library(CC_API STATIC Include/basic/CCEncode.h @@ -126,15 +254,13 @@ if (APIS) src/basic/CCString.cpp src/Module/File/CCFIleInStream.cpp src/Module/File/CCFileOutStream.cpp - src/Module/Comm/CCSocket.cpp + src/Module/Comm/Socket/CCSocket.cpp src/Module/Data/CCJSONObject.cpp src/Module/IO/CCThread.cpp src/Module/IO/CCProcess.cpp src/Module/IO/CCThreadPool.cpp src/Module/IO/CCTimeData.cpp - src/Module/Multimedia/CCAudio.cpp src/Module/Comm/CCEpoll.cpp - src/Module/Comm/CCSerialPort.cpp src/CCServlet/CCRequest.cpp src/CCServlet/CCResponse.cpp src/CCServlet/CCSQLite3.cpp @@ -177,9 +303,7 @@ if (APIS) Include/basic/ConcurrentLinkedList.h src/basic/CCTimer.cpp src/Module/File/CCLogger.cpp - Include/Module/Comm/WebRTC/CCWebRTC.cpp - Include/Module/Comm/WebRTC/CCWebRTC.h - Include/Module/Comm/WebRTC/CCWCTool.h + ${LIBRTC_STATIC} src/DataModule/NetSqlite.cpp Include/DataModule/NetSqlite.h Include/Module/Window/CCSystem.h @@ -187,6 +311,17 @@ if (APIS) Include/basic/StreamHandler.h Include/Multimedia/CCMiniMP3.cpp Include/Multimedia/CCMiniMP3.h + ${ZLIB_Module} + ${SerialPort_STATIC} + ${portaudio_STATIC} + ${IMGUI_SOURCES} + Include/TL/Array_CTL.h + Include/TL/Map_CTL.h + ${AUDIO_IO_STATIC} + src/Module/Comm/Socket/CCDatagramSocket.cpp + src/Module/Comm/Socket/CCServerSocket.cpp + src/Module/Comm/Socket/CCClientSocket.cpp + ${CC_DataChannel} ) target_include_directories(CC_API PUBLIC ${CC_API_INC} @@ -196,26 +331,34 @@ if (APIS) endif() if(CMAKE_HOST_UNIX) target_link_libraries(CC_API PUBLIC - libcserialport nlohmann_json - PortAudio libcppp-reiconv.shared crypto ssl ) + if (AUDIO_IO) + target_link_libraries(CC_API PUBLIC asound) + endif () elseif(CMAKE_HOST_WIN32) target_link_libraries(CC_API PUBLIC - libcserialport nlohmann_json - PortAudio libcppp-reiconv.shared crypto ssl - shlwapi shell32 Pdh iphlpapi ) + if (NOT CMAKE_SYSTEM_NAME STREQUAL "OHOS") + target_link_libraries(CC_API PUBLIC shlwapi shell32 Pdh iphlpapi winmm) + endif () add_compile_definitions(UNICODE _UNICODE) # 强制使用Unicode else() endif() + + if (PORTAUDIO) + target_link_libraries(CC_API PUBLIC PortAudio) + endif () + if (SerialPort) + target_link_libraries(CC_API PUBLIC libcserialport) + endif () if (FFMPEG) target_link_libraries(CC_API PUBLIC CC_FFmpeg_API) endif () @@ -247,9 +390,28 @@ if (APIS) if (LIBRTC) target_link_libraries(CC_API PUBLIC datachannel) endif () + if (LIBJUICE) + if (NOT LIBRTC) + target_link_libraries(CC_API PUBLIC LibJuice::LibJuiceStatic) + endif () + add_definitions(-DLIBJUICE_INC) + target_compile_definitions(CC_API PUBLIC LIBJUICE_INC) + endif () if (GLFW) target_link_libraries(CC_API PUBLIC glfw) endif () + if (IMGUI) + if(CMAKE_HOST_UNIX) + target_link_libraries(CC_API PUBLIC GL glfw X11) + elseif(CMAKE_HOST_WIN32) + target_link_libraries(CC_API PUBLIC opengl32 dwmapi glfw) + else() + + endif () + endif () + if (ZLIB) + target_link_libraries(CC_API PUBLIC zlib minizip) + endif () endif(APIS) diff --git a/CC_SDK/Environment/FFmpeg/CMakeLists.txt b/CC_SDK/Environment/FFmpeg/CMakeLists.txt index 10a948d2..3a996118 100644 --- a/CC_SDK/Environment/FFmpeg/CMakeLists.txt +++ b/CC_SDK/Environment/FFmpeg/CMakeLists.txt @@ -29,6 +29,46 @@ if (WIN32) ${CMAKE_CURRENT_LIST_DIR}/bin/Windows/swresample-6.dll ${CMAKE_CURRENT_LIST_DIR}/bin/Windows/swscale-9.dll ) + add_custom_command(TARGET CC_FFmpeg_API POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_LIST_DIR}/bin/Windows/avcodec-62.dll + ${CMAKE_CURRENT_LIST_DIR}/bin/Windows/avdevice-62.dll + ${CMAKE_CURRENT_LIST_DIR}/bin/Windows/avfilter-11.dll + ${CMAKE_CURRENT_LIST_DIR}/bin/Windows/avformat-62.dll + ${CMAKE_CURRENT_LIST_DIR}/bin/Windows/avutil-60.dll + ${CMAKE_CURRENT_LIST_DIR}/bin/Windows/swresample-6.dll + ${CMAKE_CURRENT_LIST_DIR}/bin/Windows/swscale-9.dll + ${CMAKE_BINARY_DIR}/bin + COMMENT "Copying FFmpeg DLLs to bin directory" + ) +elseif (CMAKE_SYSTEM_NAME STREQUAL "OHOS") + if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm|ARM") + target_include_directories(CC_FFmpeg_API PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/include/OHOS/Armv7/include + ) + target_link_libraries(CC_FFmpeg_API PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Armv7/libavcodec.so.60.3.100 + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Armv7/libavdevice.so.60.1.100 + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Armv7/libavfilter.so.9.3.100 + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Armv7/libavformat.so.60.3.100 + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Armv7/libswresample.so.4.10.100 + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Armv7/libswscale.so.7.1.100 + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Armv7/libavutil.so.58.2.100 + ) + elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64|ARM64") + target_include_directories(CC_FFmpeg_API PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/include/OHOS/Arm64/include + ) + target_link_libraries(CC_FFmpeg_API PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Arm64/libavcodec.so.60.3.100 + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Arm64/libavdevice.so.60.1.100 + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Arm64/libavfilter.so.9.3.100 + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Arm64/libavformat.so.60.3.100 + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Arm64/libswresample.so.4.10.100 + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Arm64/libswscale.so.7.1.100 + ${CMAKE_CURRENT_LIST_DIR}/bin/OHOS/Arm64/libavutil.so.58.2.100 + ) + endif() elseif (UNIX) message(STATUS "FFMPEG Linux") if (CMAKE_SIZEOF_VOID_P EQUAL 8) @@ -46,6 +86,18 @@ elseif (UNIX) ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Arm64/libswresample.so ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Arm64/libswscale.so ) + add_custom_command(TARGET CC_FFmpeg_API POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Arm64/libavcodec.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Arm64/libavdevice.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Arm64/libavfilter.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Arm64/libavformat.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Arm64/libavutil.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Arm64/libswresample.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Arm64/libswscale.so + ${CMAKE_BINARY_DIR}/bin + COMMENT "Copying FFmpeg DLLs to bin directory" + ) elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64|AMD64") message(STATUS "ffmpeg target architecture is X86_64") target_include_directories(CC_FFmpeg_API PUBLIC @@ -60,6 +112,18 @@ elseif (UNIX) ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/x86/libswresample.so ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/x86/libswscale.so ) + add_custom_command(TARGET CC_FFmpeg_API POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/x86/libavcodec.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/x86/libavdevice.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/x86/libavfilter.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/x86/libavformat.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/x86/libavutil.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/x86/libswresample.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/x86/libswscale.so + ${CMAKE_BINARY_DIR}/bin + COMMENT "Copying FFmpeg DLLs to bin directory" + ) endif() else () if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm|ARM") @@ -78,6 +142,20 @@ elseif (UNIX) ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Armv7/libswresample.so.5.3.100 ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Armv7/libswscale.so.8.3.100 ) + add_custom_command(TARGET CC_FFmpeg_API POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Armv7/libavcodec.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Armv7/libavdevice.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Armv7/libavfilter.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Armv7/libavformat.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Armv7/libavutil.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Armv7/libswresample.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Armv7/libpostproc.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Armv7/libswscale.so + ${CMAKE_CURRENT_LIST_DIR}/bin/Linux/Armv7/libx264.so + ${CMAKE_BINARY_DIR}/bin + COMMENT "Copying FFmpeg DLLs to bin directory" + ) else() target_include_directories(CC_FFmpeg_API PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include/Linux/Armv7/include diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/avcodec.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/avcodec.h index a004cccd..77ca8dee 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/avcodec.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/avcodec.h @@ -187,6 +187,17 @@ struct AVCodecParameters; * @{ */ +#if FF_API_BUFFER_MIN_SIZE +/** + * @ingroup lavc_encoding + * minimum encoding buffer size + * Used to avoid some checks during header writing. + * @deprecated Unused: avcodec_receive_packet() does not work + * with preallocated packet buffers. + */ +#define AV_INPUT_BUFFER_MIN_SIZE 16384 +#endif + /** * @ingroup lavc_encoding */ @@ -223,6 +234,15 @@ typedef struct RcOverride{ * Use qpel MC. */ #define AV_CODEC_FLAG_QPEL (1 << 4) +#if FF_API_DROPCHANGED +/** + * Don't output frames whose parameters differ from first + * decoded frame in stream. + * + * @deprecated callers should implement this functionality in their own code + */ +#define AV_CODEC_FLAG_DROPCHANGED (1 << 5) +#endif /** * Request the encoder to output reconstructed frames, i.e.\ frames that would * be produced by decoding the encoded bistream. These frames may be retrieved @@ -495,21 +515,16 @@ typedef struct AVCodecContext { int flags2; /** - * Out-of-band global headers that may be used by some codecs. - * - * - decoding: Should be set by the caller when available (typically from a - * demuxer) before opening the decoder; some decoders require this to be - * set and will fail to initialize otherwise. - * - * The array must be allocated with the av_malloc() family of functions; - * allocated size must be at least AV_INPUT_BUFFER_PADDING_SIZE bytes - * larger than extradata_size. - * - * - encoding: May be set by the encoder in avcodec_open2() (possibly - * depending on whether the AV_CODEC_FLAG_GLOBAL_HEADER flag is set). - * - * After being set, the array is owned by the codec and freed in - * avcodec_free_context(). + * some codecs need / can use extradata like Huffman tables. + * MJPEG: Huffman tables + * rv10: additional flags + * MPEG-4: global headers (they can be in the bitstream or here) + * The allocated memory should be AV_INPUT_BUFFER_PADDING_SIZE bytes larger + * than extradata_size to avoid problems if it is read with the bitstream reader. + * The bytewise contents of extradata must not depend on the architecture or CPU endianness. + * Must be allocated with the av_malloc() family of functions. + * - encoding: Set/allocated/freed by libavcodec. + * - decoding: Set/allocated/freed by user. */ uint8_t *extradata; int extradata_size; @@ -550,6 +565,23 @@ typedef struct AVCodecContext { */ AVRational framerate; +#if FF_API_TICKS_PER_FRAME + /** + * For some codecs, the time base is closer to the field rate than the frame rate. + * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration + * if no telecine is used ... + * + * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2. + * + * @deprecated + * - decoding: Use AVCodecDescriptor.props & AV_CODEC_PROP_FIELDS + * - encoding: Set AVCodecContext.framerate instead + * + */ + attribute_deprecated + int ticks_per_frame; +#endif + /** * Codec delay. * @@ -1616,29 +1648,165 @@ typedef struct AVCodecContext { * See the AV_PROFILE_* defines in defs.h. */ int profile; +#if FF_API_FF_PROFILE_LEVEL + /** @deprecated The following defines are deprecated; use AV_PROFILE_* + * in defs.h instead. */ +#define FF_PROFILE_UNKNOWN -99 +#define FF_PROFILE_RESERVED -100 + +#define FF_PROFILE_AAC_MAIN 0 +#define FF_PROFILE_AAC_LOW 1 +#define FF_PROFILE_AAC_SSR 2 +#define FF_PROFILE_AAC_LTP 3 +#define FF_PROFILE_AAC_HE 4 +#define FF_PROFILE_AAC_HE_V2 28 +#define FF_PROFILE_AAC_LD 22 +#define FF_PROFILE_AAC_ELD 38 +#define FF_PROFILE_MPEG2_AAC_LOW 128 +#define FF_PROFILE_MPEG2_AAC_HE 131 + +#define FF_PROFILE_DNXHD 0 +#define FF_PROFILE_DNXHR_LB 1 +#define FF_PROFILE_DNXHR_SQ 2 +#define FF_PROFILE_DNXHR_HQ 3 +#define FF_PROFILE_DNXHR_HQX 4 +#define FF_PROFILE_DNXHR_444 5 + +#define FF_PROFILE_DTS 20 +#define FF_PROFILE_DTS_ES 30 +#define FF_PROFILE_DTS_96_24 40 +#define FF_PROFILE_DTS_HD_HRA 50 +#define FF_PROFILE_DTS_HD_MA 60 +#define FF_PROFILE_DTS_EXPRESS 70 +#define FF_PROFILE_DTS_HD_MA_X 61 +#define FF_PROFILE_DTS_HD_MA_X_IMAX 62 + + +#define FF_PROFILE_EAC3_DDP_ATMOS 30 + +#define FF_PROFILE_TRUEHD_ATMOS 30 + +#define FF_PROFILE_MPEG2_422 0 +#define FF_PROFILE_MPEG2_HIGH 1 +#define FF_PROFILE_MPEG2_SS 2 +#define FF_PROFILE_MPEG2_SNR_SCALABLE 3 +#define FF_PROFILE_MPEG2_MAIN 4 +#define FF_PROFILE_MPEG2_SIMPLE 5 + +#define FF_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag +#define FF_PROFILE_H264_INTRA (1<<11) // 8+3; constraint_set3_flag + +#define FF_PROFILE_H264_BASELINE 66 +#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED) +#define FF_PROFILE_H264_MAIN 77 +#define FF_PROFILE_H264_EXTENDED 88 +#define FF_PROFILE_H264_HIGH 100 +#define FF_PROFILE_H264_HIGH_10 110 +#define FF_PROFILE_H264_HIGH_10_INTRA (110|FF_PROFILE_H264_INTRA) +#define FF_PROFILE_H264_MULTIVIEW_HIGH 118 +#define FF_PROFILE_H264_HIGH_422 122 +#define FF_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA) +#define FF_PROFILE_H264_STEREO_HIGH 128 +#define FF_PROFILE_H264_HIGH_444 144 +#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244 +#define FF_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA) +#define FF_PROFILE_H264_CAVLC_444 44 + +#define FF_PROFILE_VC1_SIMPLE 0 +#define FF_PROFILE_VC1_MAIN 1 +#define FF_PROFILE_VC1_COMPLEX 2 +#define FF_PROFILE_VC1_ADVANCED 3 + +#define FF_PROFILE_MPEG4_SIMPLE 0 +#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE 1 +#define FF_PROFILE_MPEG4_CORE 2 +#define FF_PROFILE_MPEG4_MAIN 3 +#define FF_PROFILE_MPEG4_N_BIT 4 +#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE 5 +#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION 6 +#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE 7 +#define FF_PROFILE_MPEG4_HYBRID 8 +#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME 9 +#define FF_PROFILE_MPEG4_CORE_SCALABLE 10 +#define FF_PROFILE_MPEG4_ADVANCED_CODING 11 +#define FF_PROFILE_MPEG4_ADVANCED_CORE 12 +#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13 +#define FF_PROFILE_MPEG4_SIMPLE_STUDIO 14 +#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE 15 + +#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 1 +#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 2 +#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION 32768 +#define FF_PROFILE_JPEG2000_DCINEMA_2K 3 +#define FF_PROFILE_JPEG2000_DCINEMA_4K 4 + +#define FF_PROFILE_VP9_0 0 +#define FF_PROFILE_VP9_1 1 +#define FF_PROFILE_VP9_2 2 +#define FF_PROFILE_VP9_3 3 + +#define FF_PROFILE_HEVC_MAIN 1 +#define FF_PROFILE_HEVC_MAIN_10 2 +#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3 +#define FF_PROFILE_HEVC_REXT 4 +#define FF_PROFILE_HEVC_SCC 9 + +#define FF_PROFILE_VVC_MAIN_10 1 +#define FF_PROFILE_VVC_MAIN_10_444 33 + +#define FF_PROFILE_AV1_MAIN 0 +#define FF_PROFILE_AV1_HIGH 1 +#define FF_PROFILE_AV1_PROFESSIONAL 2 + +#define FF_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT 0xc0 +#define FF_PROFILE_MJPEG_HUFFMAN_EXTENDED_SEQUENTIAL_DCT 0xc1 +#define FF_PROFILE_MJPEG_HUFFMAN_PROGRESSIVE_DCT 0xc2 +#define FF_PROFILE_MJPEG_HUFFMAN_LOSSLESS 0xc3 +#define FF_PROFILE_MJPEG_JPEG_LS 0xf7 + +#define FF_PROFILE_SBC_MSBC 1 + +#define FF_PROFILE_PRORES_PROXY 0 +#define FF_PROFILE_PRORES_LT 1 +#define FF_PROFILE_PRORES_STANDARD 2 +#define FF_PROFILE_PRORES_HQ 3 +#define FF_PROFILE_PRORES_4444 4 +#define FF_PROFILE_PRORES_XQ 5 + +#define FF_PROFILE_ARIB_PROFILE_A 0 +#define FF_PROFILE_ARIB_PROFILE_C 1 + +#define FF_PROFILE_KLVA_SYNC 0 +#define FF_PROFILE_KLVA_ASYNC 1 + +#define FF_PROFILE_EVC_BASELINE 0 +#define FF_PROFILE_EVC_MAIN 1 +#endif /** * Encoding level descriptor. * - encoding: Set by user, corresponds to a specific level defined by the * codec, usually corresponding to the profile level, if not specified it - * is set to AV_LEVEL_UNKNOWN. + * is set to FF_LEVEL_UNKNOWN. * - decoding: Set by libavcodec. * See AV_LEVEL_* in defs.h. */ int level; +#if FF_API_FF_PROFILE_LEVEL + /** @deprecated The following define is deprecated; use AV_LEVEL_UNKOWN + * in defs.h instead. */ +#define FF_LEVEL_UNKNOWN -99 +#endif -#if FF_API_CODEC_PROPS /** * Properties of the stream that gets decoded * - encoding: unused * - decoding: set by libavcodec */ - attribute_deprecated unsigned properties; #define FF_CODEC_PROPERTY_LOSSLESS 0x00000001 #define FF_CODEC_PROPERTY_CLOSED_CAPTIONS 0x00000002 #define FF_CODEC_PROPERTY_FILM_GRAIN 0x00000004 -#endif /** * Skip loop filtering for selected frames. @@ -1727,13 +1895,8 @@ typedef struct AVCodecContext { * For SUBTITLE_ASS subtitle type, it should contain the whole ASS * [Script Info] and [V4+ Styles] section, plus the [Events] line and * the Format line following. It shouldn't include any Dialogue line. - * - * - encoding: May be set by the caller before avcodec_open2() to an array - * allocated with the av_malloc() family of functions. - * - decoding: May be set by libavcodec in avcodec_open2(). - * - * After being set, the array is owned by the codec and freed in - * avcodec_free_context(). + * - encoding: Set/allocated/freed by user (before avcodec_open2()) + * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2()) */ int subtitle_header_size; uint8_t *subtitle_header; @@ -2217,6 +2380,24 @@ int avcodec_parameters_to_context(AVCodecContext *codec, */ int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options); +#if FF_API_AVCODEC_CLOSE +/** + * Close a given AVCodecContext and free all the data associated with it + * (but not the AVCodecContext itself). + * + * Calling this function on an AVCodecContext that hasn't been opened will free + * the codec-specific data allocated in avcodec_alloc_context3() with a non-NULL + * codec. Subsequent calls will do nothing. + * + * @deprecated Do not use this function. Use avcodec_free_context() to destroy a + * codec context (either open or closed). Opening and closing a codec context + * multiple times is not supported anymore -- use multiple codec contexts + * instead. + */ +attribute_deprecated +int avcodec_close(AVCodecContext *avctx); +#endif + /** * Free all allocated data in the given subtitle struct. * @@ -2935,8 +3116,8 @@ void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size); void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size); /** - * @return a positive value if s is open (i.e. avcodec_open2() was called on it), - * 0 otherwise. + * @return a positive value if s is open (i.e. avcodec_open2() was called on it + * with no corresponding avcodec_close()), 0 otherwise. */ int avcodec_is_open(AVCodecContext *s); diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/codec.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/codec.h index f509e5d9..f7541ffc 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/codec.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/codec.h @@ -80,6 +80,21 @@ */ #define AV_CODEC_CAP_SMALL_LAST_FRAME (1 << 6) +#if FF_API_SUBFRAMES +/** + * Codec can output multiple frames per AVPacket + * Normally demuxers return one frame at a time, demuxers which do not do + * are connected to a parser to split what they return into proper frames. + * This flag is reserved to the very rare category of codecs which have a + * bitstream that cannot be split into frames without timeconsuming + * operations like full decoding. Demuxers carrying such bitstreams thus + * may return multiple frames in a packet. This has many disadvantages like + * prohibiting stream copy in many cases thus it should only be considered + * as a last resort. + */ +#define AV_CODEC_CAP_SUBFRAMES (1 << 8) +#endif + /** * Codec is experimental and is thus avoided in favor of non experimental * encoders diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/codec_id.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/codec_id.h index 09dff298..0a8d3bed 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/codec_id.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/codec_id.h @@ -206,9 +206,7 @@ enum AVCodecID { AV_CODEC_ID_BMV_VIDEO, AV_CODEC_ID_VBLE, AV_CODEC_ID_DXTORY, -#if FF_API_V408_CODECID AV_CODEC_ID_V410, -#endif AV_CODEC_ID_XWD, AV_CODEC_ID_CDXL, AV_CODEC_ID_XBM, @@ -256,10 +254,8 @@ enum AVCodecID { AV_CODEC_ID_012V, AV_CODEC_ID_AVUI, AV_CODEC_ID_TARGA_Y216, -#if FF_API_V408_CODECID AV_CODEC_ID_V308, AV_CODEC_ID_V408, -#endif AV_CODEC_ID_YUV4, AV_CODEC_ID_AVRN, AV_CODEC_ID_CPIA, @@ -326,10 +322,6 @@ enum AVCodecID { AV_CODEC_ID_RTV1, AV_CODEC_ID_VMIX, AV_CODEC_ID_LEAD, - AV_CODEC_ID_DNXUC, - AV_CODEC_ID_RV60, - AV_CODEC_ID_JPEGXL_ANIM, - AV_CODEC_ID_APV, /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs @@ -424,7 +416,6 @@ enum AVCodecID { AV_CODEC_ID_ADPCM_IMA_MOFLEX, AV_CODEC_ID_ADPCM_IMA_ACORN, AV_CODEC_ID_ADPCM_XMD, - AV_CODEC_ID_ADPCM_IMA_XBOX, /* AMR */ AV_CODEC_ID_AMR_NB = 0x12000, @@ -553,7 +544,6 @@ enum AVCodecID { AV_CODEC_ID_OSQ, AV_CODEC_ID_QOA, AV_CODEC_ID_LC3, - AV_CODEC_ID_G728, /* subtitle codecs */ AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. @@ -583,7 +573,6 @@ enum AVCodecID { AV_CODEC_ID_HDMV_TEXT_SUBTITLE, AV_CODEC_ID_TTML, AV_CODEC_ID_ARIB_CAPTION, - AV_CODEC_ID_IVTV_VBI, /* other specific kind of codecs (generally used for attachments) */ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/defs.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/defs.h index e0df6021..24250f8a 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/defs.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/defs.h @@ -194,14 +194,6 @@ #define AV_PROFILE_EVC_BASELINE 0 #define AV_PROFILE_EVC_MAIN 1 -#define AV_PROFILE_APV_422_10 33 -#define AV_PROFILE_APV_422_12 44 -#define AV_PROFILE_APV_444_10 55 -#define AV_PROFILE_APV_444_12 66 -#define AV_PROFILE_APV_4444_10 77 -#define AV_PROFILE_APV_4444_12 88 -#define AV_PROFILE_APV_400_10 99 - #define AV_LEVEL_UNKNOWN -99 diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/packet.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/packet.h index 71bc2e05..0a280105 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/packet.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/packet.h @@ -356,6 +356,10 @@ enum AVPacketSideDataType { AV_PKT_DATA_NB }; +#if FF_API_QUALITY_FACTOR +#define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS //DEPRECATED +#endif + /** * This structure stores auxiliary information for decoding, presenting, or * otherwise processing the coded stream. It is typically exported by demuxers @@ -364,11 +368,11 @@ enum AVPacketSideDataType { * * Global side data is handled as follows: * - During demuxing, it may be exported through - * @ref AVCodecParameters.coded_side_data "AVStream's codec parameters", which can + * @ref AVStream.codecpar.side_data "AVStream's codec parameters", which can * then be passed as input to decoders through the * @ref AVCodecContext.coded_side_data "decoder context's side data", for * initialization. - * - For muxing, it can be fed through @ref AVCodecParameters.coded_side_data + * - For muxing, it can be fed through @ref AVStream.codecpar.side_data * "AVStream's codec parameters", typically the output of encoders through * the @ref AVCodecContext.coded_side_data "encoder context's side data", for * initialization. @@ -876,13 +880,6 @@ int av_packet_make_writable(AVPacket *pkt); */ void av_packet_rescale_ts(AVPacket *pkt, AVRational tb_src, AVRational tb_dst); -/** - * Allocate an AVContainerFifo instance for AVPacket. - * - * @param flags currently unused - */ -struct AVContainerFifo *av_container_fifo_alloc_avpacket(unsigned flags); - /** * @} */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/vdpau.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/vdpau.h index da77c5da..8021c257 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/vdpau.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/vdpau.h @@ -93,6 +93,28 @@ typedef struct AVVDPAUContext { AVVDPAU_Render2 render2; } AVVDPAUContext; +#if FF_API_VDPAU_ALLOC_GET_SET +/** + * @brief allocation function for AVVDPAUContext + * + * Allows extending the struct without breaking API/ABI + * @deprecated use av_vdpau_bind_context() instead + */ +attribute_deprecated +AVVDPAUContext *av_alloc_vdpaucontext(void); + +/** + * @deprecated render2 is public and can be accessed directly + */ +attribute_deprecated +AVVDPAU_Render2 av_vdpau_hwaccel_get_render2(const AVVDPAUContext *); +/** + * @deprecated render2 is public and can be accessed directly + */ +attribute_deprecated +void av_vdpau_hwaccel_set_render2(AVVDPAUContext *, AVVDPAU_Render2); +#endif + /** * Associate a VDPAU device with a codec context for hardware acceleration. * This function is meant to be called from the get_format() codec callback, @@ -133,6 +155,17 @@ int av_vdpau_bind_context(AVCodecContext *avctx, VdpDevice device, int av_vdpau_get_surface_parameters(AVCodecContext *avctx, VdpChromaType *type, uint32_t *width, uint32_t *height); +#if FF_API_VDPAU_ALLOC_GET_SET +/** + * Allocate an AVVDPAUContext. + * + * @return Newly-allocated AVVDPAUContext or NULL on failure. + * @deprecated use av_vdpau_bind_context() instead + */ +attribute_deprecated +AVVDPAUContext *av_vdpau_alloc_context(void); +#endif + /** @} */ #endif /* AVCODEC_VDPAU_H */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/version.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/version.h index 06631ffa..b6ca025f 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/version.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/version.h @@ -29,8 +29,8 @@ #include "version_major.h" -#define LIBAVCODEC_VERSION_MINOR 4 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MINOR 19 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/version_major.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/version_major.h index 14e49f0e..63df40e9 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/version_major.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavcodec/version_major.h @@ -25,7 +25,7 @@ * Libavcodec version macros. */ -#define LIBAVCODEC_VERSION_MAJOR 62 +#define LIBAVCODEC_VERSION_MAJOR 61 /** * FF_API_* defines may be placed below to indicate public API that will be @@ -37,17 +37,16 @@ * at once through the bump. This improves the git bisect-ability of the change. */ -#define FF_API_INIT_PACKET (LIBAVCODEC_VERSION_MAJOR < 63) +#define FF_API_INIT_PACKET (LIBAVCODEC_VERSION_MAJOR < 62) +#define FF_API_SUBFRAMES (LIBAVCODEC_VERSION_MAJOR < 62) +#define FF_API_TICKS_PER_FRAME (LIBAVCODEC_VERSION_MAJOR < 62) +#define FF_API_DROPCHANGED (LIBAVCODEC_VERSION_MAJOR < 62) -#define FF_API_V408_CODECID (LIBAVCODEC_VERSION_MAJOR < 63) -#define FF_API_CODEC_PROPS (LIBAVCODEC_VERSION_MAJOR < 63) -#define FF_API_EXR_GAMMA (LIBAVCODEC_VERSION_MAJOR < 63) - -// reminder to remove the OMX encoder on next major bump -#define FF_CODEC_OMX (LIBAVCODEC_VERSION_MAJOR < 63) -// reminder to remove Sonic Lossy/Lossless encoders on next major bump -#define FF_CODEC_SONIC_ENC (LIBAVCODEC_VERSION_MAJOR < 63) -// reminder to remove Sonic decoder on next-next major bump -#define FF_CODEC_SONIC_DEC (LIBAVCODEC_VERSION_MAJOR < 63) +#define FF_API_AVFFT (LIBAVCODEC_VERSION_MAJOR < 62) +#define FF_API_FF_PROFILE_LEVEL (LIBAVCODEC_VERSION_MAJOR < 62) +#define FF_API_AVCODEC_CLOSE (LIBAVCODEC_VERSION_MAJOR < 62) +#define FF_API_BUFFER_MIN_SIZE (LIBAVCODEC_VERSION_MAJOR < 62) +#define FF_API_VDPAU_ALLOC_GET_SET (LIBAVCODEC_VERSION_MAJOR < 62) +#define FF_API_QUALITY_FACTOR (LIBAVCODEC_VERSION_MAJOR < 62) #endif /* AVCODEC_VERSION_MAJOR_H */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavdevice/version.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavdevice/version.h index 25befdea..7608a860 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavdevice/version.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavdevice/version.h @@ -29,7 +29,7 @@ #include "version_major.h" -#define LIBAVDEVICE_VERSION_MINOR 0 +#define LIBAVDEVICE_VERSION_MINOR 3 #define LIBAVDEVICE_VERSION_MICRO 100 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavdevice/version_major.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavdevice/version_major.h index 191511cd..f16abb69 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavdevice/version_major.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavdevice/version_major.h @@ -25,7 +25,7 @@ * Libavdevice version macros */ -#define LIBAVDEVICE_VERSION_MAJOR 62 +#define LIBAVDEVICE_VERSION_MAJOR 61 /** * FF_API_* defines may be placed below to indicate public API that will be @@ -33,6 +33,11 @@ * the public API and may change, break or disappear at any time. */ -#define FF_API_ALSA_CHANNELS (LIBAVDEVICE_VERSION_MAJOR < 63) +// reminder to remove the bktr device on next major bump +#define FF_API_BKTR_DEVICE (LIBAVDEVICE_VERSION_MAJOR < 62) +// reminder to remove the opengl device on next major bump +#define FF_API_OPENGL_DEVICE (LIBAVDEVICE_VERSION_MAJOR < 62) +// reminder to remove the sdl2 device on next major bump +#define FF_API_SDL2_DEVICE (LIBAVDEVICE_VERSION_MAJOR < 62) #endif /* AVDEVICE_VERSION_MAJOR_H */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/avfilter.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/avfilter.h index f85929dc..1401577c 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/avfilter.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/avfilter.h @@ -43,6 +43,7 @@ #include "libavutil/dict.h" #include "libavutil/frame.h" #include "libavutil/log.h" +#include "libavutil/samplefmt.h" #include "libavutil/pixfmt.h" #include "libavutil/rational.h" @@ -69,6 +70,7 @@ const char *avfilter_configuration(void); */ const char *avfilter_license(void); +typedef struct AVFilterContext AVFilterContext; typedef struct AVFilterLink AVFilterLink; typedef struct AVFilterPad AVFilterPad; typedef struct AVFilterFormats AVFilterFormats; @@ -96,18 +98,6 @@ const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx); */ enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx); -/** - * Get the hardware frames context of a filter link. - * - * @param link an AVFilterLink - * - * @return a ref-counted copy of the link's hw_frames_ctx field if there is - * a hardware frames context associated with the link or NULL otherwise. - * The returned AVBufferRef needs to be released with av_buffer_unref() - * when it is no longer used. - */ -AVBufferRef* avfilter_link_get_hw_frames_ctx(AVFilterLink *link); - /** * Lists of formats / etc. supported by an end of a link. * @@ -253,6 +243,204 @@ typedef struct AVFilter { * A combination of AVFILTER_FLAG_* */ int flags; + + /***************************************************************** + * All fields below this line are not part of the public API. They + * may not be used outside of libavfilter and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + + /** + * The number of entries in the list of inputs. + */ + uint8_t nb_inputs; + + /** + * The number of entries in the list of outputs. + */ + uint8_t nb_outputs; + + /** + * This field determines the state of the formats union. + * It is an enum FilterFormatsState value. + */ + uint8_t formats_state; + + /** + * Filter pre-initialization function + * + * This callback will be called immediately after the filter context is + * allocated, to allow allocating and initing sub-objects. + * + * If this callback is not NULL, the uninit callback will be called on + * allocation failure. + * + * @return 0 on success, + * AVERROR code on failure (but the code will be + * dropped and treated as ENOMEM by the calling code) + */ + int (*preinit)(AVFilterContext *ctx); + + /** + * Filter initialization function. + * + * This callback will be called only once during the filter lifetime, after + * all the options have been set, but before links between filters are + * established and format negotiation is done. + * + * Basic filter initialization should be done here. Filters with dynamic + * inputs and/or outputs should create those inputs/outputs here based on + * provided options. No more changes to this filter's inputs/outputs can be + * done after this callback. + * + * This callback must not assume that the filter links exist or frame + * parameters are known. + * + * @ref AVFilter.uninit "uninit" is guaranteed to be called even if + * initialization fails, so this callback does not have to clean up on + * failure. + * + * @return 0 on success, a negative AVERROR on failure + */ + int (*init)(AVFilterContext *ctx); + + /** + * Filter uninitialization function. + * + * Called only once right before the filter is freed. Should deallocate any + * memory held by the filter, release any buffer references, etc. It does + * not need to deallocate the AVFilterContext.priv memory itself. + * + * This callback may be called even if @ref AVFilter.init "init" was not + * called or failed, so it must be prepared to handle such a situation. + */ + void (*uninit)(AVFilterContext *ctx); + + /** + * The state of the following union is determined by formats_state. + * See the documentation of enum FilterFormatsState in internal.h. + */ + union { + /** + * Query formats supported by the filter on its inputs and outputs. + * + * This callback is called after the filter is initialized (so the inputs + * and outputs are fixed), shortly before the format negotiation. This + * callback may be called more than once. + * + * This callback must set ::AVFilterLink's + * @ref AVFilterFormatsConfig.formats "outcfg.formats" + * on every input link and + * @ref AVFilterFormatsConfig.formats "incfg.formats" + * on every output link to a list of pixel/sample formats that the filter + * supports on that link. + * For video links, this filter may also set + * @ref AVFilterFormatsConfig.color_spaces "incfg.color_spaces" + * / + * @ref AVFilterFormatsConfig.color_spaces "outcfg.color_spaces" + * and @ref AVFilterFormatsConfig.color_ranges "incfg.color_ranges" + * / + * @ref AVFilterFormatsConfig.color_ranges "outcfg.color_ranges" + * analogously. + * For audio links, this filter must also set + * @ref AVFilterFormatsConfig.samplerates "incfg.samplerates" + * / + * @ref AVFilterFormatsConfig.samplerates "outcfg.samplerates" + * and @ref AVFilterFormatsConfig.channel_layouts "incfg.channel_layouts" + * / + * @ref AVFilterFormatsConfig.channel_layouts "outcfg.channel_layouts" + * analogously. + * + * This callback must never be NULL if the union is in this state. + * + * @return zero on success, a negative value corresponding to an + * AVERROR code otherwise + */ + int (*query_func)(AVFilterContext *); + + /** + * Same as query_func(), except this function writes the results into + * provided arrays. + * + * @param cfg_in array of input format configurations with as many + * members as the filters has inputs (NULL when there are + * no inputs); + * @param cfg_out array of output format configurations with as many + * members as the filters has outputs (NULL when there + * are no outputs); + */ + int (*query_func2)(const AVFilterContext *, + struct AVFilterFormatsConfig **cfg_in, + struct AVFilterFormatsConfig **cfg_out); + /** + * A pointer to an array of admissible pixel formats delimited + * by AV_PIX_FMT_NONE. The generic code will use this list + * to indicate that this filter supports each of these pixel formats, + * provided that all inputs and outputs use the same pixel format. + * + * In addition to that the generic code will mark all inputs + * and all outputs as supporting all color spaces and ranges, as + * long as all inputs and outputs use the same color space/range. + * + * This list must never be NULL if the union is in this state. + * The type of all inputs and outputs of filters using this must + * be AVMEDIA_TYPE_VIDEO. + */ + const enum AVPixelFormat *pixels_list; + /** + * Analogous to pixels, but delimited by AV_SAMPLE_FMT_NONE + * and restricted to filters that only have AVMEDIA_TYPE_AUDIO + * inputs and outputs. + * + * In addition to that the generic code will mark all inputs + * and all outputs as supporting all sample rates and every + * channel count and channel layout, as long as all inputs + * and outputs use the same sample rate and channel count/layout. + */ + const enum AVSampleFormat *samples_list; + /** + * Equivalent to { pix_fmt, AV_PIX_FMT_NONE } as pixels_list. + */ + enum AVPixelFormat pix_fmt; + /** + * Equivalent to { sample_fmt, AV_SAMPLE_FMT_NONE } as samples_list. + */ + enum AVSampleFormat sample_fmt; + } formats; + + int priv_size; ///< size of private data to allocate for the filter + + int flags_internal; ///< Additional flags for avfilter internal use only. + + /** + * Make the filter instance process a command. + * + * @param cmd the command to process, for handling simplicity all commands must be alphanumeric only + * @param arg the argument for the command + * @param res a buffer with size res_size where the filter(s) can return a response. This must not change when the command is not supported. + * @param flags if AVFILTER_CMD_FLAG_FAST is set and the command would be + * time consuming then a filter should treat it like an unsupported command + * + * @returns >=0 on success otherwise an error code. + * AVERROR(ENOSYS) on unsupported commands + */ + int (*process_command)(AVFilterContext *, const char *cmd, const char *arg, char *res, int res_len, int flags); + + /** + * Filter activation function. + * + * Called when any processing is needed from the filter, instead of any + * filter_frame and request_frame on pads. + * + * The function must examine inlinks and outlinks and perform a single + * step of processing. If there is nothing to do, the function must do + * nothing and not return an error. If more steps are or may be + * possible, it must use ff_filter_set_ready() to schedule another + * activation. + */ + int (*activate)(AVFilterContext *ctx); } AVFilter; /** @@ -266,7 +454,7 @@ unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output); #define AVFILTER_THREAD_SLICE (1 << 0) /** An instance of a filter */ -typedef struct AVFilterContext { +struct AVFilterContext { const AVClass *av_class; ///< needed for av_log() and filters common options const AVFilter *filter; ///< the AVFilter of which this is an instance @@ -310,32 +498,12 @@ typedef struct AVFilterContext { */ int nb_threads; -#if FF_API_CONTEXT_PUBLIC - /** - * @deprecated unused - */ - attribute_deprecated struct AVFilterCommand *command_queue; -#endif char *enable_str; ///< enable expression string -#if FF_API_CONTEXT_PUBLIC - /** - * @deprecated unused - */ - attribute_deprecated - void *enable; - /** - * @deprecated unused - */ - double *var_values; -#endif - /** - * MUST NOT be accessed from outside avfilter. - * - * the enabled state from the last expression evaluation - */ - int is_disabled; + void *enable; ///< parsed expression (AVExpr*) + double *var_values; ///< variable values for the enable expression + int is_disabled; ///< the enabled state from the last expression evaluation /** * For filters which will create hardware frames, sets the device the @@ -350,13 +518,12 @@ typedef struct AVFilterContext { */ AVBufferRef *hw_device_ctx; -#if FF_API_CONTEXT_PUBLIC /** - * @deprecated this field should never have been accessed by callers + * Ready status of the filter. + * A non-0 value means that the filter needs activating; + * a higher value suggests a more urgent activation. */ - attribute_deprecated unsigned ready; -#endif /** * Sets the number of extra hardware frames which the filter will @@ -373,7 +540,7 @@ typedef struct AVFilterContext { * configured. */ int extra_hw_frames; -} AVFilterContext; +}; /** * A link between two filters. This contains pointers to the source and @@ -425,9 +592,6 @@ struct AVFilterLink { */ AVRational time_base; - AVFrameSideData **side_data; - int nb_side_data; - /***************************************************************** * All fields below this line are not part of the public API. They * may not be used outside of libavfilter and can be changed and @@ -459,6 +623,20 @@ struct AVFilterLink { int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad); +#if FF_API_LINK_PUBLIC +/** + * @deprecated this function should never be called by users + */ +attribute_deprecated +void avfilter_link_free(AVFilterLink **link); + +/** + * @deprecated this function should never be called by users + */ +attribute_deprecated +int avfilter_config_links(AVFilterContext *filter); +#endif + #define AVFILTER_CMD_FLAG_ONE 1 ///< Stop once a filter understood the command (for target=all for example), fast filters are favored automatically #define AVFILTER_CMD_FLAG_FAST 2 ///< Only execute command when its fast (like a video out that supports contrast adjustment in hw) @@ -667,9 +845,9 @@ AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph, AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, const char *name); /** - * A convenience wrapper that allocates and initializes a filter in a single - * step. The filter instance is created from the filter filt and inited with the - * parameter args. opaque is currently ignored. + * Create and add a filter instance into an existing graph. + * The filter instance is created from the filter filt and inited + * with the parameter args. opaque is currently ignored. * * In case of success put in *filt_ctx the pointer to the created * filter instance, otherwise set *filt_ctx to NULL. @@ -678,12 +856,6 @@ AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, const char *nam * @param graph_ctx the filter graph * @return a negative AVERROR error code in case of failure, a non * negative value otherwise - * - * @warning Since the filter is initialized after this function successfully - * returns, you MUST NOT set any further options on it. If you need to - * do that, call ::avfilter_graph_alloc_filter(), followed by setting - * the options, followed by ::avfilter_init_dict() instead of this - * function. */ int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt, const char *name, const char *args, void *opaque, diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/buffersink.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/buffersink.h index a8435eea..361d6036 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/buffersink.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/buffersink.h @@ -48,20 +48,26 @@ * - av_buffersink_get_channels(), * - av_buffersink_get_ch_layout(), * - av_buffersink_get_sample_rate(). - * - av_buffersink_get_side_data(). * * The layout returned by av_buffersink_get_ch_layout() must de uninitialized * by the caller. * * The format can be constrained by setting options, using av_opt_set() and * related functions with the AV_OPT_SEARCH_CHILDREN flag. - * - pixel_formats (array of pixel formats), - * - colorspaces (array of int), - * - colorranges (array of int), - * - sample_formats (array of sample formats), - * - samplerates (array of int), - * - channel_layouts (array of channel layouts) - * If an option is not set, all corresponding formats are accepted. + * - pix_fmts (int list), + * - color_spaces (int list), + * - color_ranges (int list), + * - sample_fmts (int list), + * - sample_rates (int list), + * - ch_layouts (string), + * - channel_counts (int list), + * - all_channel_counts (bool). + * Most of these options are of type binary, and should be set using + * av_opt_set_int_list() or av_opt_set_bin(). If they are not set, all + * corresponding formats are accepted. + * + * As a special case, if ch_layouts is not set, all valid channel layouts are + * accepted except for UNSPEC layouts, unless all_channel_counts is set. */ /** @@ -123,9 +129,6 @@ int av_buffersink_get_sample_rate (const AVFilterContext *c AVBufferRef * av_buffersink_get_hw_frames_ctx (const AVFilterContext *ctx); -const AVFrameSideData *const *av_buffersink_get_side_data(const AVFilterContext *ctx, - int *nb_side_data); - /** @} */ /** diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/buffersrc.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/buffersrc.h index 2db9b8fb..6f3344f4 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/buffersrc.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/buffersrc.h @@ -120,9 +120,6 @@ typedef struct AVBufferSrcParameters { */ enum AVColorSpace color_space; enum AVColorRange color_range; - - AVFrameSideData **side_data; - int nb_side_data; } AVBufferSrcParameters; /** diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/version.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/version.h index d5a6bc14..4d8f28e5 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/version.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/version.h @@ -31,7 +31,7 @@ #include "version_major.h" -#define LIBAVFILTER_VERSION_MINOR 0 +#define LIBAVFILTER_VERSION_MINOR 4 #define LIBAVFILTER_VERSION_MICRO 100 diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/version_major.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/version_major.h index af6f5983..c5e660ee 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/version_major.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavfilter/version_major.h @@ -27,7 +27,7 @@ * Libavfilter version macros */ -#define LIBAVFILTER_VERSION_MAJOR 11 +#define LIBAVFILTER_VERSION_MAJOR 10 /** * FF_API_* defines may be placed below to indicate public API that will be @@ -35,7 +35,6 @@ * the public API and may change, break or disappear at any time. */ -#define FF_API_BUFFERSINK_OPTS (LIBAVFILTER_VERSION_MAJOR < 12) -#define FF_API_CONTEXT_PUBLIC (LIBAVFILTER_VERSION_MAJOR < 12) +#define FF_API_LINK_PUBLIC (LIBAVFILTER_VERSION_MAJOR < 11) #endif /* AVFILTER_VERSION_MAJOR_H */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavformat/avformat.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavformat/avformat.h index b6c63e22..56c1c802 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavformat/avformat.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavformat/avformat.h @@ -146,8 +146,8 @@ * consumed). The calling program can handle such unrecognized options as it * wishes, e.g. * @code - * const AVDictionaryEntry *e; - * if ((e = av_dict_iterate(options, NULL))) { + * AVDictionaryEntry *e; + * if (e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX)) { * fprintf(stderr, "Option %s not recognized by the demuxer.\n", e->key); * abort(); * } @@ -459,7 +459,7 @@ typedef struct AVProbeData { #define AVPROBE_SCORE_STREAM_RETRY (AVPROBE_SCORE_MAX/4-1) #define AVPROBE_SCORE_EXTENSION 50 ///< score for file extension -#define AVPROBE_SCORE_MIME_BONUS 30 ///< score added for matching mime type +#define AVPROBE_SCORE_MIME 75 ///< score for file mime type #define AVPROBE_SCORE_MAX 100 ///< maximum score #define AVPROBE_PADDING_SIZE 32 ///< extra allocated bytes at the end of the probe buffer @@ -470,7 +470,8 @@ typedef struct AVProbeData { /** * The muxer/demuxer is experimental and should be used with caution. * - * It will not be selected automatically, and must be specified explicitly. + * - demuxers: will not be selected automatically by probing, must be specified + * explicitly. */ #define AVFMT_EXPERIMENTAL 0x0004 #define AVFMT_SHOW_IDS 0x0008 /**< Show format stream IDs numbers. */ @@ -484,6 +485,9 @@ typedef struct AVProbeData { #define AVFMT_NOBINSEARCH 0x2000 /**< Format does not allow to fall back on binary search via read_timestamp */ #define AVFMT_NOGENSEARCH 0x4000 /**< Format does not allow to fall back on generic search */ #define AVFMT_NO_BYTE_SEEK 0x8000 /**< Format does not allow seeking by bytes */ +#if FF_API_ALLOW_FLUSH +#define AVFMT_ALLOW_FLUSH 0x10000 /**< @deprecated: Just send a NULL packet if you want to flush a muxer. */ +#endif #define AVFMT_TS_NONSTRICT 0x20000 /**< Format does not require strictly increasing timestamps, but they must still be monotonic */ @@ -843,6 +847,38 @@ typedef struct AVStream { */ AVPacket attached_pic; +#if FF_API_AVSTREAM_SIDE_DATA + /** + * An array of side data that applies to the whole stream (i.e. the + * container does not allow it to change between packets). + * + * There may be no overlap between the side data in this array and side data + * in the packets. I.e. a given side data is either exported by the muxer + * (demuxing) / set by the caller (muxing) in this array, then it never + * appears in the packets, or the side data is exported / sent through + * the packets (always in the first packet where the value becomes known or + * changes), then it does not appear in this array. + * + * - demuxing: Set by libavformat when the stream is created. + * - muxing: May be set by the caller before avformat_write_header(). + * + * Freed by libavformat in avformat_free_context(). + * + * @deprecated use AVStream's @ref AVCodecParameters.coded_side_data + * "codecpar side data". + */ + attribute_deprecated + AVPacketSideData *side_data; + /** + * The number of elements in the AVStream.side_data array. + * + * @deprecated use AVStream's @ref AVCodecParameters.nb_coded_side_data + * "codecpar side data". + */ + attribute_deprecated + int nb_side_data; +#endif + /** * Flags indicating events happening on the stream, a combination of * AVSTREAM_EVENT_FLAG_*. @@ -1046,19 +1082,6 @@ typedef struct AVStreamGroupTileGrid { * final image before presentation. */ int height; - - /** - * Additional data associated with the grid. - * - * Should be allocated with av_packet_side_data_new() or - * av_packet_side_data_add(), and will be freed by avformat_free_context(). - */ - AVPacketSideData *coded_side_data; - - /** - * Amount of entries in @ref coded_side_data. - */ - int nb_coded_side_data; } AVStreamGroupTileGrid; /** @@ -1434,6 +1457,9 @@ typedef struct AVFormatContext { #define AVFMT_FLAG_BITEXACT 0x0400 #define AVFMT_FLAG_SORT_DTS 0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down) #define AVFMT_FLAG_FAST_SEEK 0x80000 ///< Enable fast, but inaccurate seeks for some formats +#if FF_API_LAVF_SHORTEST +#define AVFMT_FLAG_SHORTEST 0x100000 ///< Stop muxing when the shortest stream stops. +#endif #define AVFMT_FLAG_AUTO_BSF 0x200000 ///< Add bitstream filters as requested by the muxer /** @@ -1869,6 +1895,10 @@ typedef struct AVFormatContext { /** * A callback for closing the streams opened with AVFormatContext.io_open(). * + * Using this is preferred over io_close, because this can return an error. + * Therefore this callback is used instead of io_close by the generic + * libavformat code if io_close is NULL or the default. + * * @param s the format context * @param pb IO context to be closed and freed * @return 0 on success, a negative AVERROR code on failure @@ -1886,6 +1916,29 @@ typedef struct AVFormatContext { int64_t duration_probesize; } AVFormatContext; +/** + * This function will cause global side data to be injected in the next packet + * of each stream as well as after any subsequent seek. + * + * @note global side data is always available in every AVStream's + * @ref AVCodecParameters.coded_side_data "codecpar side data" array, and + * in a @ref AVCodecContext.coded_side_data "decoder's side data" array if + * initialized with said stream's codecpar. + * @see av_packet_side_data_get() + */ +void av_format_inject_global_side_data(AVFormatContext *s); + +#if FF_API_GET_DUR_ESTIMATE_METHOD +/** + * Returns the method used to set ctx->duration. + * + * @return AVFMT_DURATION_FROM_PTS, AVFMT_DURATION_FROM_STREAM, or AVFMT_DURATION_FROM_BITRATE. + * @deprecated duration_estimation_method is public and can be read directly. + */ +attribute_deprecated +enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx); +#endif + /** * @defgroup lavf_core Core functions * @ingroup libavf @@ -2063,6 +2116,57 @@ AVStream *avformat_new_stream(AVFormatContext *s, const struct AVCodec *c); */ int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st); +#if FF_API_AVSTREAM_SIDE_DATA +/** + * Wrap an existing array as stream side data. + * + * @param st stream + * @param type side information type + * @param data the side data array. It must be allocated with the av_malloc() + * family of functions. The ownership of the data is transferred to + * st. + * @param size side information size + * + * @return zero on success, a negative AVERROR code on failure. On failure, + * the stream is unchanged and the data remains owned by the caller. + * @deprecated use av_packet_side_data_add() with the stream's + * @ref AVCodecParameters.coded_side_data "codecpar side data" + */ +attribute_deprecated +int av_stream_add_side_data(AVStream *st, enum AVPacketSideDataType type, + uint8_t *data, size_t size); + +/** + * Allocate new information from stream. + * + * @param stream stream + * @param type desired side information type + * @param size side information size + * + * @return pointer to fresh allocated data or NULL otherwise + * @deprecated use av_packet_side_data_new() with the stream's + * @ref AVCodecParameters.coded_side_data "codecpar side data" + */ +attribute_deprecated +uint8_t *av_stream_new_side_data(AVStream *stream, + enum AVPacketSideDataType type, size_t size); +/** + * Get side information from stream. + * + * @param stream stream + * @param type desired side information type + * @param size If supplied, *size will be set to the size of the side data + * or to zero if the desired side data is not present. + * + * @return pointer to data if present or NULL otherwise + * @deprecated use av_packet_side_data_get() with the stream's + * @ref AVCodecParameters.coded_side_data "codecpar side data" + */ +attribute_deprecated +uint8_t *av_stream_get_side_data(const AVStream *stream, + enum AVPacketSideDataType type, size_t *size); +#endif + AVProgram *av_new_program(AVFormatContext *s, int id); /** @@ -2171,7 +2275,7 @@ int av_probe_input_buffer(AVIOContext *pb, const AVInputFormat **fmt, * which case an AVFormatContext is allocated by this * function and written into ps. * Note that a user-supplied AVFormatContext will be freed - * on failure and its pointer set to NULL. + * on failure. * @param url URL of the stream to open. * @param fmt If non-NULL, this parameter forces a specific input format. * Otherwise the format is autodetected. @@ -2180,8 +2284,7 @@ int av_probe_input_buffer(AVIOContext *pb, const AVInputFormat **fmt, * On return this parameter will be destroyed and replaced with * a dict containing options that were not found. May be NULL. * - * @return 0 on success; on failure: frees ps, sets its pointer to NULL, - * and returns a negative AVERROR. + * @return 0 on success, a negative AVERROR on failure. * * @note If you want to use custom IO, preallocate the format context and set its pb field. */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavformat/version.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavformat/version.h index b32ddb36..70c554c1 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavformat/version.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavformat/version.h @@ -31,8 +31,8 @@ #include "version_major.h" -#define LIBAVFORMAT_VERSION_MINOR 1 -#define LIBAVFORMAT_VERSION_MICRO 101 +#define LIBAVFORMAT_VERSION_MINOR 7 +#define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavformat/version_major.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavformat/version_major.h index 61338d33..7a9b0670 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavformat/version_major.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavformat/version_major.h @@ -29,7 +29,7 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here -#define LIBAVFORMAT_VERSION_MAJOR 62 +#define LIBAVFORMAT_VERSION_MAJOR 61 /** * FF_API_* defines may be placed below to indicate public API that will be @@ -41,9 +41,13 @@ * at once through the bump. This improves the git bisect-ability of the change. * */ -#define FF_API_COMPUTE_PKT_FIELDS2 (LIBAVFORMAT_VERSION_MAJOR < 63) +#define FF_API_COMPUTE_PKT_FIELDS2 (LIBAVFORMAT_VERSION_MAJOR < 62) +#define FF_API_LAVF_SHORTEST (LIBAVFORMAT_VERSION_MAJOR < 62) +#define FF_API_ALLOW_FLUSH (LIBAVFORMAT_VERSION_MAJOR < 62) +#define FF_API_AVSTREAM_SIDE_DATA (LIBAVFORMAT_VERSION_MAJOR < 62) -#define FF_API_INTERNAL_TIMING (LIBAVFORMAT_VERSION_MAJOR < 63) +#define FF_API_GET_DUR_ESTIMATE_METHOD (LIBAVFORMAT_VERSION_MAJOR < 62) +#define FF_API_INTERNAL_TIMING (LIBAVFORMAT_VERSION_MAJOR < 62) #define FF_API_R_FRAME_RATE 1 diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/avassert.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/avassert.h index 8dbdb015..1895fb75 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/avassert.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/avassert.h @@ -31,7 +31,6 @@ #ifdef HAVE_AV_CONFIG_H # include "config.h" #endif -#include "attributes.h" #include "log.h" #include "macros.h" @@ -76,45 +75,4 @@ */ void av_assert0_fpu(void); -/** - * Asserts that are used as compiler optimization hints depending - * upon ASSERT_LEVEL and NBDEBUG. - * - * Undefined behaviour occurs if execution reaches a point marked - * with av_unreachable() or if a condition used with av_assume() - * is false. - * - * The condition used with av_assume() should not have side-effects - * and should be visible to the compiler. - */ -#if defined(ASSERT_LEVEL) ? ASSERT_LEVEL > 0 : !defined(HAVE_AV_CONFIG_H) && !defined(NDEBUG) -#define av_unreachable(msg) \ -do { \ - av_log(NULL, AV_LOG_PANIC, \ - "Reached supposedly unreachable code at %s:%d: %s\n", \ - __FILE__, __LINE__, msg); \ - abort(); \ -} while (0) -#define av_assume(cond) av_assert0(cond) -#else -#if AV_GCC_VERSION_AT_LEAST(4, 5) || AV_HAS_BUILTIN(__builtin_unreachable) -#define av_unreachable(msg) __builtin_unreachable() -#elif defined(_MSC_VER) -#define av_unreachable(msg) __assume(0) -#define av_assume(cond) __assume(cond) -#elif __STDC_VERSION__ >= 202311L -#include -#define av_unreachable(msg) unreachable() -#else -#define av_unreachable(msg) ((void)0) -#endif - -#ifndef av_assume -#define av_assume(cond) do { \ - if (!(cond)) \ - av_unreachable(); \ -} while (0) -#endif -#endif - #endif /* AVUTIL_AVASSERT_H */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/avconfig.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/avconfig.h index c289fbb5..8558b350 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/avconfig.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/avconfig.h @@ -2,5 +2,5 @@ #ifndef AVUTIL_AVCONFIG_H #define AVUTIL_AVCONFIG_H #define AV_HAVE_BIGENDIAN 0 -#define AV_HAVE_FAST_UNALIGNED 1 +#define AV_HAVE_FAST_UNALIGNED 0 #endif /* AVUTIL_AVCONFIG_H */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/avutil.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/avutil.h index c8ae114a..d2900dcb 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/avutil.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/avutil.h @@ -41,6 +41,7 @@ * @li @ref lavd "libavdevice" special devices muxing/demuxing library * @li @ref lavu "libavutil" common utility library * @li @ref lswr "libswresample" audio resampling, format conversion and mixing + * @li @ref lpp "libpostproc" post processing library * @li @ref libsws "libswscale" color conversion and scaling library * * @section ffmpeg_versioning Versioning and compatibility @@ -313,7 +314,6 @@ static inline void *av_x_if_null(const void *p, const void *x) return (void *)(intptr_t)(p ? p : x); } -#if FF_API_OPT_INT_LIST /** * Compute the length of an integer list. * @@ -322,7 +322,6 @@ static inline void *av_x_if_null(const void *p, const void *x) * @param list pointer to the list * @return length of the list, in elements, not counting the terminator */ -attribute_deprecated unsigned av_int_list_length_for_size(unsigned elsize, const void *list, uint64_t term) av_pure; @@ -335,7 +334,6 @@ unsigned av_int_list_length_for_size(unsigned elsize, */ #define av_int_list_length(list, term) \ av_int_list_length_for_size(sizeof(*(list)), list, term) -#endif /** * Return the fractional representation of the internal time base. diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/channel_layout.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/channel_layout.h index b82d07eb..3a96c2d9 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/channel_layout.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/channel_layout.h @@ -45,7 +45,7 @@ */ enum AVChannel { - /// Invalid channel index + ///< Invalid channel index AV_CHAN_NONE = -1, AV_CHAN_FRONT_LEFT, AV_CHAN_FRONT_RIGHT, @@ -84,9 +84,6 @@ enum AVChannel { AV_CHAN_TOP_SURROUND_LEFT, ///< +110 degrees, Lvs, TpLS AV_CHAN_TOP_SURROUND_RIGHT, ///< -110 degrees, Rvs, TpRS - AV_CHAN_BINAURAL_LEFT = 61, - AV_CHAN_BINAURAL_RIGHT, - /** Channel is empty can be safely skipped. */ AV_CHAN_UNUSED = 0x200, @@ -206,8 +203,6 @@ enum AVChannelOrder { #define AV_CH_SIDE_SURROUND_RIGHT (1ULL << AV_CHAN_SIDE_SURROUND_RIGHT ) #define AV_CH_TOP_SURROUND_LEFT (1ULL << AV_CHAN_TOP_SURROUND_LEFT ) #define AV_CH_TOP_SURROUND_RIGHT (1ULL << AV_CHAN_TOP_SURROUND_RIGHT ) -#define AV_CH_BINAURAL_LEFT (1ULL << AV_CHAN_BINAURAL_LEFT ) -#define AV_CH_BINAURAL_RIGHT (1ULL << AV_CHAN_BINAURAL_RIGHT ) /** * @} @@ -240,20 +235,17 @@ enum AVChannelOrder { #define AV_CH_LAYOUT_7POINT1 (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) #define AV_CH_LAYOUT_7POINT1_WIDE (AV_CH_LAYOUT_5POINT1|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) #define AV_CH_LAYOUT_7POINT1_WIDE_BACK (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) -#define AV_CH_LAYOUT_5POINT1POINT2 (AV_CH_LAYOUT_5POINT1|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT) #define AV_CH_LAYOUT_5POINT1POINT2_BACK (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT) #define AV_CH_LAYOUT_OCTAGONAL (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT) #define AV_CH_LAYOUT_CUBE (AV_CH_LAYOUT_QUAD|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT) -#define AV_CH_LAYOUT_5POINT1POINT4_BACK (AV_CH_LAYOUT_5POINT1POINT2|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT) +#define AV_CH_LAYOUT_5POINT1POINT4_BACK (AV_CH_LAYOUT_5POINT1POINT2_BACK|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT) #define AV_CH_LAYOUT_7POINT1POINT2 (AV_CH_LAYOUT_7POINT1|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT) #define AV_CH_LAYOUT_7POINT1POINT4_BACK (AV_CH_LAYOUT_7POINT1POINT2|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT) #define AV_CH_LAYOUT_7POINT2POINT3 (AV_CH_LAYOUT_7POINT1POINT2|AV_CH_TOP_BACK_CENTER|AV_CH_LOW_FREQUENCY_2) #define AV_CH_LAYOUT_9POINT1POINT4_BACK (AV_CH_LAYOUT_7POINT1POINT4_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) -#define AV_CH_LAYOUT_9POINT1POINT6 (AV_CH_LAYOUT_9POINT1POINT4_BACK|AV_CH_TOP_SIDE_LEFT|AV_CH_TOP_SIDE_RIGHT) #define AV_CH_LAYOUT_HEXADECAGONAL (AV_CH_LAYOUT_OCTAGONAL|AV_CH_WIDE_LEFT|AV_CH_WIDE_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT) -#define AV_CH_LAYOUT_BINAURAL (AV_CH_BINAURAL_LEFT|AV_CH_BINAURAL_RIGHT) #define AV_CH_LAYOUT_STEREO_DOWNMIX (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT) -#define AV_CH_LAYOUT_22POINT2 (AV_CH_LAYOUT_9POINT1POINT6|AV_CH_BACK_CENTER|AV_CH_LOW_FREQUENCY_2|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_CENTER|AV_CH_TOP_BACK_CENTER|AV_CH_BOTTOM_FRONT_CENTER|AV_CH_BOTTOM_FRONT_LEFT|AV_CH_BOTTOM_FRONT_RIGHT) +#define AV_CH_LAYOUT_22POINT2 (AV_CH_LAYOUT_7POINT1POINT4_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER|AV_CH_BACK_CENTER|AV_CH_LOW_FREQUENCY_2|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_CENTER|AV_CH_TOP_SIDE_LEFT|AV_CH_TOP_SIDE_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_BOTTOM_FRONT_CENTER|AV_CH_BOTTOM_FRONT_LEFT|AV_CH_BOTTOM_FRONT_RIGHT) #define AV_CH_LAYOUT_7POINT1_TOP_BACK AV_CH_LAYOUT_5POINT1POINT2_BACK @@ -417,7 +409,6 @@ typedef struct AVChannelLayout { #define AV_CHANNEL_LAYOUT_7POINT1 AV_CHANNEL_LAYOUT_MASK(8, AV_CH_LAYOUT_7POINT1) #define AV_CHANNEL_LAYOUT_7POINT1_WIDE AV_CHANNEL_LAYOUT_MASK(8, AV_CH_LAYOUT_7POINT1_WIDE) #define AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK AV_CHANNEL_LAYOUT_MASK(8, AV_CH_LAYOUT_7POINT1_WIDE_BACK) -#define AV_CHANNEL_LAYOUT_5POINT1POINT2 AV_CHANNEL_LAYOUT_MASK(8, AV_CH_LAYOUT_5POINT1POINT2) #define AV_CHANNEL_LAYOUT_5POINT1POINT2_BACK AV_CHANNEL_LAYOUT_MASK(8, AV_CH_LAYOUT_5POINT1POINT2_BACK) #define AV_CHANNEL_LAYOUT_OCTAGONAL AV_CHANNEL_LAYOUT_MASK(8, AV_CH_LAYOUT_OCTAGONAL) #define AV_CHANNEL_LAYOUT_CUBE AV_CHANNEL_LAYOUT_MASK(8, AV_CH_LAYOUT_CUBE) @@ -426,9 +417,7 @@ typedef struct AVChannelLayout { #define AV_CHANNEL_LAYOUT_7POINT1POINT4_BACK AV_CHANNEL_LAYOUT_MASK(12, AV_CH_LAYOUT_7POINT1POINT4_BACK) #define AV_CHANNEL_LAYOUT_7POINT2POINT3 AV_CHANNEL_LAYOUT_MASK(12, AV_CH_LAYOUT_7POINT2POINT3) #define AV_CHANNEL_LAYOUT_9POINT1POINT4_BACK AV_CHANNEL_LAYOUT_MASK(14, AV_CH_LAYOUT_9POINT1POINT4_BACK) -#define AV_CHANNEL_LAYOUT_9POINT1POINT6 AV_CHANNEL_LAYOUT_MASK(16, AV_CH_LAYOUT_9POINT1POINT6) #define AV_CHANNEL_LAYOUT_HEXADECAGONAL AV_CHANNEL_LAYOUT_MASK(16, AV_CH_LAYOUT_HEXADECAGONAL) -#define AV_CHANNEL_LAYOUT_BINAURAL AV_CHANNEL_LAYOUT_MASK(2, AV_CH_LAYOUT_BINAURAL) #define AV_CHANNEL_LAYOUT_STEREO_DOWNMIX AV_CHANNEL_LAYOUT_MASK(2, AV_CH_LAYOUT_STEREO_DOWNMIX) #define AV_CHANNEL_LAYOUT_22POINT2 AV_CHANNEL_LAYOUT_MASK(24, AV_CH_LAYOUT_22POINT2) diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/cpu.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/cpu.h index 5ef5da58..ba6c234e 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/cpu.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/cpu.h @@ -72,8 +72,6 @@ #define AV_CPU_FLAG_VFP_VM (1 << 7) ///< VFPv2 vector mode, deprecated in ARMv7-A and unavailable in various CPUs implementations #define AV_CPU_FLAG_DOTPROD (1 << 8) #define AV_CPU_FLAG_I8MM (1 << 9) -#define AV_CPU_FLAG_SVE (1 <<10) -#define AV_CPU_FLAG_SVE2 (1 <<11) #define AV_CPU_FLAG_SETEND (1 <<16) #define AV_CPU_FLAG_MMI (1 << 0) @@ -101,9 +99,6 @@ #define AV_CPU_FLAG_RV_MISALIGNED (1 <<10) ///< Fast misaligned accesses #define AV_CPU_FLAG_RVB (1 <<11) ///< B (bit manipulations) -// WASM extensions -#define AV_CPU_FLAG_SIMD128 (1 << 0) - /** * Return the flags which specify extensions supported by the CPU. * The returned value is affected by av_force_cpu_flags() if that was used diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/csp.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/csp.h index 9b74c631..73bce52b 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/csp.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/csp.h @@ -81,12 +81,8 @@ typedef struct AVColorPrimariesDesc { } AVColorPrimariesDesc; /** - * Function pointer representing a double -> double transfer function that - * performs either an OETF transfer function, or alternatively an inverse EOTF - * function (in particular, for SMPTE ST 2084 / PQ). This function inputs - * linear light, and outputs gamma encoded light. - * - * See ITU-T H.273 for more information. + * Function pointer representing a double -> double transfer function that performs + * an EOTF transfer inversion. This function outputs linear light. */ typedef double (*av_csp_trc_function)(double); @@ -147,44 +143,6 @@ double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic trc); */ av_csp_trc_function av_csp_trc_func_from_id(enum AVColorTransferCharacteristic trc); -/** - * Returns the mathematical inverse of the corresponding TRC function. - */ -av_csp_trc_function av_csp_trc_func_inv_from_id(enum AVColorTransferCharacteristic trc); - -/** - * Function pointer representing an ITU EOTF transfer for a given reference - * display configuration. - * - * @param Lw The white point luminance of the display, in nits (cd/m^2). - * @param Lb The black point luminance of the display, in nits (cd/m^2). - */ -typedef void (*av_csp_eotf_function)(double Lw, double Lb, double c[3]); - -/** - * Returns the ITU EOTF corresponding to a given TRC. This converts from the - * signal level [0,1] to the raw output display luminance in nits (cd/m^2). - * This is done per channel in RGB space, except for AVCOL_TRC_SMPTE428, which - * assumes CIE XYZ in- and output. - * - * @return A pointer to the function implementing the given TRC, or NULL if no - * such function is defined. - * - * @note In general, the resulting function is defined (wherever possible) for - * out-of-range values, even though these values do not have a physical - * meaning on the given display. Users should clamp inputs (or outputs) - * if this behavior is not desired. - * - * This is also the case for functions like PQ, which are defined over an - * absolute signal range independent of the target display capabilities. - */ -av_csp_eotf_function av_csp_itu_eotf(enum AVColorTransferCharacteristic trc); - -/** - * Returns the mathematical inverse of the corresponding EOTF. - */ -av_csp_eotf_function av_csp_itu_eotf_inv(enum AVColorTransferCharacteristic trc); - /** * @} */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/dict.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/dict.h index 654e7c35..713c9e36 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/dict.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/dict.h @@ -82,7 +82,6 @@ #define AV_DICT_APPEND 32 /**< If the entry already exists, append to it. Note that no delimiter is added, the strings are simply concatenated. */ #define AV_DICT_MULTIKEY 64 /**< Allow to store several equal keys in the dictionary */ -#define AV_DICT_DEDUP 128 /**< If inserting a value that already exists for a key, do nothing. Only relevant with AV_DICT_MULTIKEY. */ /** * @} */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/ffversion.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/ffversion.h index 0dd58433..48f04a6a 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/ffversion.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/ffversion.h @@ -1,5 +1,5 @@ /* Automatically generated by version.sh, do not manually edit! */ #ifndef AVUTIL_FFVERSION_H #define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "N-120057-g7d38486975-20250628" +#define FFMPEG_VERSION "7.1.1" #endif /* AVUTIL_FFVERSION_H */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/film_grain_params.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/film_grain_params.h index 7e8d3337..ccacab88 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/film_grain_params.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/film_grain_params.h @@ -136,6 +136,43 @@ typedef struct AVFilmGrainH274Params { */ int model_id; +#if FF_API_H274_FILM_GRAIN_VCS + /** + * TODO: On this ABI bump, please also re-order the fields in + * AVFilmGrainParams (see below) + */ + + /** + * Specifies the bit depth used for the luma component. + * + * @deprecated use AVFilmGrainParams.bit_depth_luma. + */ + attribute_deprecated + int bit_depth_luma; + + /** + * Specifies the bit depth used for the chroma components. + * + * @deprecated use AVFilmGrainParams.bit_depth_chroma. + */ + attribute_deprecated + int bit_depth_chroma; + + /** + * Specifies the video signal characteristics. + * + * @deprecated use AVFilmGrainParams.color_{range,primaries,trc,space}. + */ + attribute_deprecated + enum AVColorRange color_range; + attribute_deprecated + enum AVColorPrimaries color_primaries; + attribute_deprecated + enum AVColorTransferCharacteristic color_trc; + attribute_deprecated + enum AVColorSpace color_space; +#endif + /** * Specifies the blending mode used to blend the simulated film grain * with the decoded images. @@ -212,6 +249,18 @@ typedef struct AVFilmGrainParams { */ uint64_t seed; + /** + * Additional fields may be added both here and in any structure included. + * If a codec's film grain structure differs slightly over another + * codec's, fields within may change meaning depending on the type. + * + * TODO: Move this to the end of the structure, at the next ABI bump. + */ + union { + AVFilmGrainAOMParams aom; + AVFilmGrainH274Params h274; + } codec; + /** * Intended display resolution. May be 0 if the codec does not specify * any restrictions. @@ -238,15 +287,6 @@ typedef struct AVFilmGrainParams { int bit_depth_luma; int bit_depth_chroma; - /** - * Additional fields may be added both here and in any structure included. - * If a codec's film grain structure differs slightly over another - * codec's, fields within may change meaning depending on the type. - */ - union { - AVFilmGrainAOMParams aom; - AVFilmGrainH274Params h274; - } codec; } AVFilmGrainParams; /** diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/frame.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/frame.h index 8493233b..f7806566 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/frame.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/frame.h @@ -283,27 +283,6 @@ enum AVSideDataProps { * a single side data array. */ AV_SIDE_DATA_PROP_MULTI = (1 << 1), - - /** - * Side data depends on the video dimensions. Side data with this property - * loses its meaning when rescaling or cropping the image, unless - * either recomputed or adjusted to the new resolution. - */ - AV_SIDE_DATA_PROP_SIZE_DEPENDENT = (1 << 2), - - /** - * Side data depends on the video color space. Side data with this property - * loses its meaning when changing the video color encoding, e.g. by - * adapting to a different set of primaries or transfer characteristics. - */ - AV_SIDE_DATA_PROP_COLOR_DEPENDENT = (1 << 3), - - /** - * Side data depends on the channel layout. Side data with this property - * loses its meaning when downmixing or upmixing, unless either recomputed - * or adjusted to the new layout. - */ - AV_SIDE_DATA_PROP_CHANNEL_DEPENDENT = (1 << 4), }; /** @@ -496,6 +475,16 @@ typedef struct AVFrame { */ int format; +#if FF_API_FRAME_KEY + /** + * 1 -> keyframe, 0-> not + * + * @deprecated Use AV_FRAME_FLAG_KEY instead + */ + attribute_deprecated + int key_frame; +#endif + /** * Picture type of the frame. */ @@ -567,6 +556,32 @@ typedef struct AVFrame { */ int repeat_pict; +#if FF_API_INTERLACED_FRAME + /** + * The content of the picture is interlaced. + * + * @deprecated Use AV_FRAME_FLAG_INTERLACED instead + */ + attribute_deprecated + int interlaced_frame; + + /** + * If the content is interlaced, is top field displayed first. + * + * @deprecated Use AV_FRAME_FLAG_TOP_FIELD_FIRST instead + */ + attribute_deprecated + int top_field_first; +#endif + +#if FF_API_PALETTE_HAS_CHANGED + /** + * Tell user application that palette has changed from previous frame. + */ + attribute_deprecated + int palette_has_changed; +#endif + /** * Sample rate of the audio data. */ @@ -636,14 +651,6 @@ typedef struct AVFrame { * is interlaced. */ #define AV_FRAME_FLAG_TOP_FIELD_FIRST (1 << 4) -/** - * A decoder can use this flag to mark frames which were originally encoded losslessly. - * - * For coding bitstream formats which support both lossless and lossy - * encoding, it is sometimes possible for a decoder to determine which method - * was used when the bitsream was encoded. - */ -#define AV_FRAME_FLAG_LOSSLESS (1 << 5) /** * @} */ @@ -680,6 +687,18 @@ typedef struct AVFrame { */ int64_t best_effort_timestamp; +#if FF_API_FRAME_PKT + /** + * reordered pos from the last AVPacket that has been input into the decoder + * - encoding: unused + * - decoding: Read by user. + * @deprecated use AV_CODEC_FLAG_COPY_OPAQUE to pass through arbitrary user + * data from packets to frames + */ + attribute_deprecated + int64_t pkt_pos; +#endif + /** * metadata. * - encoding: Set by user. @@ -700,6 +719,20 @@ typedef struct AVFrame { #define FF_DECODE_ERROR_CONCEALMENT_ACTIVE 4 #define FF_DECODE_ERROR_DECODE_SLICES 8 +#if FF_API_FRAME_PKT + /** + * size of the corresponding packet containing the compressed + * frame. + * It is set to a negative value if unknown. + * - encoding: unused + * - decoding: set by libavcodec, read by user. + * @deprecated use AV_CODEC_FLAG_COPY_OPAQUE to pass through arbitrary user + * data from packets to frames + */ + attribute_deprecated + int pkt_size; +#endif + /** * For hwaccel-format frames, this should be a reference to the * AVHWFramesContext describing the frame. @@ -739,13 +772,17 @@ typedef struct AVFrame { */ /** - * RefStruct reference for internal use by a single libav* library. + * AVBufferRef for internal use by a single libav* library. * Must not be used to transfer data between libraries. * Has to be NULL when ownership of the frame leaves the respective library. * - * Code outside the FFmpeg libs must never check or change private_ref. + * Code outside the FFmpeg libs should never check or change the contents of the buffer ref. + * + * FFmpeg calls av_buffer_unref() on it when the frame is unreferenced. + * av_frame_copy_props() calls create a new reference with av_buffer_ref() + * for the target frame's private_ref field. */ - void *private_ref; + AVBufferRef *private_ref; /** * Channel layout of the audio data. @@ -850,10 +887,9 @@ void av_frame_move_ref(AVFrame *dst, AVFrame *src); * cases. * * @param frame frame in which to store the new buffers. - * @param align Required buffer size and data pointer alignment. If equal to 0, - * alignment will be chosen automatically for the current CPU. - * It is highly recommended to pass 0 here unless you know what - * you are doing. + * @param align Required buffer size alignment. If equal to 0, alignment will be + * chosen automatically for the current CPU. It is highly + * recommended to pass 0 here unless you know what you are doing. * * @return 0 on success, a negative AVERROR on error. */ @@ -1027,11 +1063,6 @@ void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd); * Applies only for side data types without the AV_SIDE_DATA_PROP_MULTI prop. */ #define AV_FRAME_SIDE_DATA_FLAG_REPLACE (1 << 1) -/** - * Create a new reference to the passed in buffer instead of taking ownership - * of it. - */ -#define AV_FRAME_SIDE_DATA_FLAG_NEW_REF (1 << 2) /** * Add new side data entry to an array. @@ -1137,14 +1168,6 @@ const AVFrameSideData *av_frame_side_data_get(AVFrameSideData * const *sd, */ void av_frame_side_data_remove(AVFrameSideData ***sd, int *nb_sd, enum AVFrameSideDataType type); - -/** - * Remove and free all side data instances that match any of the given - * side data properties. (See enum AVSideDataProps) - */ -void av_frame_side_data_remove_by_props(AVFrameSideData ***sd, int *nb_sd, - int props); - /** * @} */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/hdr_dynamic_vivid_metadata.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/hdr_dynamic_vivid_metadata.h index a9d4797f..4524a815 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/hdr_dynamic_vivid_metadata.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/hdr_dynamic_vivid_metadata.h @@ -168,6 +168,60 @@ typedef struct AVHDRVividColorToneMappingParams { */ int three_Spline_num; +#if FF_API_HDR_VIVID_THREE_SPLINE + /** + * The mode of three Spline. the value shall be in the range + * of 0 to 3, inclusive. + * @deprecated Use three_spline instead + */ + attribute_deprecated + int three_Spline_TH_mode; + + /** + * three_Spline_TH_enable_MB is in the range of 0.0 to 1.0, inclusive + * and in multiples of 1.0/255. + * @deprecated Use three_spline instead + */ + attribute_deprecated + AVRational three_Spline_TH_enable_MB; + + /** + * 3Spline_TH_enable of three Spline. + * The value shall be in the range of 0.0 to 1.0, inclusive. + * and in multiples of 1.0/4095. + * @deprecated Use three_spline instead + */ + attribute_deprecated + AVRational three_Spline_TH_enable; + + /** + * 3Spline_TH_Delta1 of three Spline. + * The value shall be in the range of 0.0 to 0.25, inclusive, + * and in multiples of 0.25/1023. + * @deprecated Use three_spline instead + */ + attribute_deprecated + AVRational three_Spline_TH_Delta1; + + /** + * 3Spline_TH_Delta2 of three Spline. + * The value shall be in the range of 0.0 to 0.25, inclusive, + * and in multiples of 0.25/1023. + * @deprecated Use three_spline instead + */ + attribute_deprecated + AVRational three_Spline_TH_Delta2; + + /** + * 3Spline_enable_Strength of three Spline. + * The value shall be in the range of 0.0 to 1.0, inclusive, + * and in multiples of 1.0/255. + * @deprecated Use three_spline instead + */ + attribute_deprecated + AVRational three_Spline_enable_Strength; +#endif + AVHDRVivid3SplineParams three_spline[2]; } AVHDRVividColorToneMappingParams; diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/hwcontext.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/hwcontext.h index 96042ba1..bac30deb 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/hwcontext.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/hwcontext.h @@ -38,7 +38,6 @@ enum AVHWDeviceType { AV_HWDEVICE_TYPE_MEDIACODEC, AV_HWDEVICE_TYPE_VULKAN, AV_HWDEVICE_TYPE_D3D12VA, - AV_HWDEVICE_TYPE_AMF, }; /** diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/hwcontext_vulkan.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/hwcontext_vulkan.h index 6ab74579..2688a475 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/hwcontext_vulkan.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/hwcontext_vulkan.h @@ -197,6 +197,11 @@ typedef enum AVVkFrameFlags { * device and tiling during av_hwframe_ctx_init(). */ AV_VK_FRAME_FLAG_NONE = (1ULL << 0), +#if FF_API_VULKAN_CONTIGUOUS_MEMORY + /* DEPRECATED: does nothing. Replaced by multiplane images. */ + AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY = (1ULL << 1), +#endif + /* Disables multiplane images. * This is required to export/import images from CUDA. */ AV_VK_FRAME_FLAG_DISABLE_MULTIPLANE = (1ULL << 2), diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/iamf.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/iamf.h index 2ed7b0f2..1fa73893 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/iamf.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/iamf.h @@ -493,14 +493,10 @@ typedef struct AVIAMFSubmixElement { enum AVIAMFSubmixLayoutType { /** * The layout follows the loudspeaker sound system convention of ITU-2051-3. - * @ref AVIAMFSubmixLayout.sound_system must be set. */ AV_IAMF_SUBMIX_LAYOUT_TYPE_LOUDSPEAKERS = 2, /** * The layout is binaural. - * - * @note @ref AVIAMFSubmixLayout.sound_system may be set to - * AV_CHANNEL_LAYOUT_BINAURAL to simplify API usage, but it's not mandatory. */ AV_IAMF_SUBMIX_LAYOUT_TYPE_BINAURAL = 3, }; @@ -518,9 +514,9 @@ typedef struct AVIAMFSubmixLayout { /** * Channel layout matching one of Sound Systems A to J of ITU-2051-3, plus - * 7.1.2ch, 3.1.2ch, and binaural. - * If layout_type is not AV_IAMF_SUBMIX_LAYOUT_TYPE_LOUDSPEAKERS or - * AV_IAMF_SUBMIX_LAYOUT_TYPE_BINAURAL, this field is undefined. + * 7.1.2ch and 3.1.2ch + * If layout_type is not AV_IAMF_SUBMIX_LAYOUT_TYPE_LOUDSPEAKERS, this field + * is undefined. */ AVChannelLayout sound_system; /** diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/log.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/log.h index ac5b08b6..ab7ceabe 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/log.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/log.h @@ -37,7 +37,6 @@ typedef enum { AV_CLASS_CATEGORY_BITSTREAM_FILTER, AV_CLASS_CATEGORY_SWSCALER, AV_CLASS_CATEGORY_SWRESAMPLER, - AV_CLASS_CATEGORY_HWDEVICE, AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT = 40, AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, @@ -47,15 +46,6 @@ typedef enum { AV_CLASS_CATEGORY_NB ///< not part of ABI/API }AVClassCategory; -enum AVClassStateFlags { - /** - * Object initialization has finished and it is now in the 'runtime' stage. - * This affects e.g. what options can be set on the object (only - * AV_OPT_FLAG_RUNTIME_PARAM options can be set on initialized objects). - */ - AV_CLASS_STATE_INITIALIZED = (1 << 0), -}; - #define AV_IS_INPUT_DEVICE(category) \ (((category) == AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT) || \ ((category) == AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT) || \ @@ -87,9 +77,7 @@ typedef struct AVClass { const char* (*item_name)(void* ctx); /** - * An array of options for the structure or NULL. - * When non-NULL, the array must be terminated by an option with a NULL - * name. + * a pointer to the first option specified in the class if any or NULL * * @see av_set_default_options() */ @@ -97,50 +85,43 @@ typedef struct AVClass { /** * LIBAVUTIL_VERSION with which this structure was created. - * This is used to allow fields to be added to AVClass without requiring - * major version bumps everywhere. + * This is used to allow fields to be added without requiring major + * version bumps everywhere. */ int version; /** - * Offset in the structure where the log level offset is stored. The log - * level offset is an int added to the log level for logging with this - * object as the context. - * - * 0 means there is no such variable. + * Offset in the structure where log_level_offset is stored. + * 0 means there is no such variable */ int log_level_offset_offset; /** * Offset in the structure where a pointer to the parent context for * logging is stored. For example a decoder could pass its AVCodecContext - * to eval as such a parent context, which an ::av_log() implementation + * to eval as such a parent context, which an av_log() implementation * could then leverage to display the parent context. - * - * When the pointer is NULL, or this offset is zero, the object is assumed - * to have no parent. + * The offset can be NULL. */ int parent_log_context_offset; /** - * Category used for visualization (like color). - * - * Only used when ::get_category() is NULL. Use this field when all - * instances of this class have the same category, use ::get_category() - * otherwise. + * Category used for visualization (like color) + * This is only set if the category is equal for all objects using this class. + * available since version (51 << 16 | 56 << 8 | 100) */ AVClassCategory category; /** - * Callback to return the instance category. Use this callback when - * different instances of this class may have different categories, - * ::category otherwise. + * Callback to return the category. + * available since version (51 << 16 | 59 << 8 | 100) */ AVClassCategory (*get_category)(void* ctx); /** * Callback to return the supported/allowed ranges. + * available since version (52.12) */ int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags); @@ -158,22 +139,11 @@ typedef struct AVClass { * @return AVClass for the next AVOptions-enabled child or NULL if there are * no more such children. * - * @note The difference between ::child_next() and ::child_class_iterate() - * is that ::child_next() iterates over _actual_ children of an - * _existing_ object instance, while ::child_class_iterate() iterates - * over the classes of all _potential_ children of any possible - * instance of this class. + * @note The difference between child_next and this is that child_next + * iterates over _already existing_ objects, while child_class_iterate + * iterates over _all possible_ children. */ const struct AVClass* (*child_class_iterate)(void **iter); - - /** - * When non-zero, offset in the object to an unsigned int holding object - * state flags, a combination of AVClassStateFlags values. The flags are - * updated by the object to signal its state to the generic code. - * - * Added in version 59.41.100. - */ - int state_flags_offset; } AVClass; /** @@ -407,16 +377,6 @@ int av_log_format_line2(void *ptr, int level, const char *fmt, va_list vl, */ #define AV_LOG_PRINT_LEVEL 2 -/** - * Include system time in log output. - */ -#define AV_LOG_PRINT_TIME 4 - -/** - * Include system date and time in log output. - */ -#define AV_LOG_PRINT_DATETIME 8 - void av_log_set_flags(int arg); int av_log_get_flags(void); diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/opt.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/opt.h index d3136792..be189f76 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/opt.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/opt.h @@ -886,7 +886,6 @@ int av_opt_set_chlayout(void *obj, const char *name, const AVChannelLayout *layo */ int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags); -#if FF_API_OPT_INT_LIST /** * Set a binary option to an integer list. * @@ -902,7 +901,6 @@ int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, in AVERROR(EINVAL) : \ av_opt_set_bin(obj, name, (const uint8_t *)(val), \ av_int_list_length(val, term) * sizeof(*(val)), flags)) -#endif /** * Add, replace, or remove elements for an array option. Which of these @@ -1071,7 +1069,6 @@ int av_opt_eval_q (void *obj, const AVOption *o, const char *val, AVRational * @} */ -#if FF_API_OPT_PTR /** * Gets a pointer to the requested field in a struct. * This function allows accessing a struct even when its fields are moved or @@ -1079,12 +1076,8 @@ int av_opt_eval_q (void *obj, const AVOption *o, const char *val, AVRational * * @returns a pointer to the field, it can be cast to the correct type and read * or written to. - * - * @deprecated direct access to AVOption-exported fields is not supported */ -attribute_deprecated void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name); -#endif /** * Check if given option is set to its default value. diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/pixfmt.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/pixfmt.h index bf1b8ed0..a7f50e16 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/pixfmt.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/pixfmt.h @@ -398,12 +398,12 @@ enum AVPixelFormat { AV_PIX_FMT_P416BE, ///< interleaved chroma YUV 4:4:4, 48bpp, big-endian AV_PIX_FMT_P416LE, ///< interleaved chroma YUV 4:4:4, 48bpp, little-endian - AV_PIX_FMT_VUYA, ///< packed VUYA 4:4:4:4, 32bpp (1 Cr & Cb sample per 1x1 Y & A samples), VUYAVUYA... + AV_PIX_FMT_VUYA, ///< packed VUYA 4:4:4, 32bpp, VUYAVUYA... AV_PIX_FMT_RGBAF16BE, ///< IEEE-754 half precision packed RGBA 16:16:16:16, 64bpp, RGBARGBA..., big-endian AV_PIX_FMT_RGBAF16LE, ///< IEEE-754 half precision packed RGBA 16:16:16:16, 64bpp, RGBARGBA..., little-endian - AV_PIX_FMT_VUYX, ///< packed VUYX 4:4:4:4, 32bpp, Variant of VUYA where alpha channel is left undefined + AV_PIX_FMT_VUYX, ///< packed VUYX 4:4:4, 32bpp, Variant of VUYA where alpha channel is left undefined AV_PIX_FMT_P012LE, ///< like NV12, with 12bpp per component, data in the high bits, zeros in the low bits, little-endian AV_PIX_FMT_P012BE, ///< like NV12, with 12bpp per component, data in the high bits, zeros in the low bits, big-endian @@ -439,55 +439,6 @@ enum AVPixelFormat { */ AV_PIX_FMT_D3D12, - AV_PIX_FMT_AYUV, ///< packed AYUV 4:4:4:4, 32bpp (1 Cr & Cb sample per 1x1 Y & A samples), AYUVAYUV... - - AV_PIX_FMT_UYVA, ///< packed UYVA 4:4:4:4, 32bpp (1 Cr & Cb sample per 1x1 Y & A samples), UYVAUYVA... - - AV_PIX_FMT_VYU444, ///< packed VYU 4:4:4, 24bpp (1 Cr & Cb sample per 1x1 Y), VYUVYU... - - AV_PIX_FMT_V30XBE, ///< packed VYUX 4:4:4 like XV30, 32bpp, (msb)10V 10Y 10U 2X(lsb), big-endian - AV_PIX_FMT_V30XLE, ///< packed VYUX 4:4:4 like XV30, 32bpp, (msb)10V 10Y 10U 2X(lsb), little-endian - - AV_PIX_FMT_RGBF16BE, ///< IEEE-754 half precision packed RGB 16:16:16, 48bpp, RGBRGB..., big-endian - AV_PIX_FMT_RGBF16LE, ///< IEEE-754 half precision packed RGB 16:16:16, 48bpp, RGBRGB..., little-endian - - AV_PIX_FMT_RGBA128BE, ///< packed RGBA 32:32:32:32, 128bpp, RGBARGBA..., big-endian - AV_PIX_FMT_RGBA128LE, ///< packed RGBA 32:32:32:32, 128bpp, RGBARGBA..., little-endian - - AV_PIX_FMT_RGB96BE, ///< packed RGBA 32:32:32, 96bpp, RGBRGB..., big-endian - AV_PIX_FMT_RGB96LE, ///< packed RGBA 32:32:32, 96bpp, RGBRGB..., little-endian - - AV_PIX_FMT_Y216BE, ///< packed YUV 4:2:2 like YUYV422, 32bpp, big-endian - AV_PIX_FMT_Y216LE, ///< packed YUV 4:2:2 like YUYV422, 32bpp, little-endian - - AV_PIX_FMT_XV48BE, ///< packed XVYU 4:4:4, 64bpp, big-endian, variant of Y416 where alpha channel is left undefined - AV_PIX_FMT_XV48LE, ///< packed XVYU 4:4:4, 64bpp, little-endian, variant of Y416 where alpha channel is left undefined - - AV_PIX_FMT_GBRPF16BE, ///< IEEE-754 half precision planer GBR 4:4:4, 48bpp, big-endian - AV_PIX_FMT_GBRPF16LE, ///< IEEE-754 half precision planer GBR 4:4:4, 48bpp, little-endian - AV_PIX_FMT_GBRAPF16BE, ///< IEEE-754 half precision planar GBRA 4:4:4:4, 64bpp, big-endian - AV_PIX_FMT_GBRAPF16LE, ///< IEEE-754 half precision planar GBRA 4:4:4:4, 64bpp, little-endian - - AV_PIX_FMT_GRAYF16BE, ///< IEEE-754 half precision Y, 16bpp, big-endian - AV_PIX_FMT_GRAYF16LE, ///< IEEE-754 half precision Y, 16bpp, little-endian - - /** - * HW acceleration through AMF. data[0] contain AMFSurface pointer - */ - AV_PIX_FMT_AMF_SURFACE, - - AV_PIX_FMT_GRAY32BE, ///< Y , 32bpp, big-endian - AV_PIX_FMT_GRAY32LE, ///< Y , 32bpp, little-endian - - AV_PIX_FMT_YAF32BE, ///< IEEE-754 single precision packed YA, 32 bits gray, 32 bits alpha, 64bpp, big-endian - AV_PIX_FMT_YAF32LE, ///< IEEE-754 single precision packed YA, 32 bits gray, 32 bits alpha, 64bpp, little-endian - - AV_PIX_FMT_YAF16BE, ///< IEEE-754 half precision packed YA, 16 bits gray, 16 bits alpha, 32bpp, big-endian - AV_PIX_FMT_YAF16LE, ///< IEEE-754 half precision packed YA, 16 bits gray, 16 bits alpha, 32bpp, little-endian - - AV_PIX_FMT_GBRAP32BE, ///< planar GBRA 4:4:4:4 128bpp, big-endian - AV_PIX_FMT_GBRAP32LE, ///< planar GBRA 4:4:4:4 128bpp, little-endian - AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; @@ -509,7 +460,6 @@ enum AVPixelFormat { #define AV_PIX_FMT_GRAY12 AV_PIX_FMT_NE(GRAY12BE, GRAY12LE) #define AV_PIX_FMT_GRAY14 AV_PIX_FMT_NE(GRAY14BE, GRAY14LE) #define AV_PIX_FMT_GRAY16 AV_PIX_FMT_NE(GRAY16BE, GRAY16LE) -#define AV_PIX_FMT_GRAY32 AV_PIX_FMT_NE(GRAY32BE, GRAY32LE) #define AV_PIX_FMT_YA16 AV_PIX_FMT_NE(YA16BE, YA16LE) #define AV_PIX_FMT_RGB48 AV_PIX_FMT_NE(RGB48BE, RGB48LE) #define AV_PIX_FMT_RGB565 AV_PIX_FMT_NE(RGB565BE, RGB565LE) @@ -549,24 +499,17 @@ enum AVPixelFormat { #define AV_PIX_FMT_GBRAP12 AV_PIX_FMT_NE(GBRAP12BE, GBRAP12LE) #define AV_PIX_FMT_GBRAP14 AV_PIX_FMT_NE(GBRAP14BE, GBRAP14LE) #define AV_PIX_FMT_GBRAP16 AV_PIX_FMT_NE(GBRAP16BE, GBRAP16LE) -#define AV_PIX_FMT_GBRAP32 AV_PIX_FMT_NE(GBRAP32BE, GBRAP32LE) #define AV_PIX_FMT_BAYER_BGGR16 AV_PIX_FMT_NE(BAYER_BGGR16BE, BAYER_BGGR16LE) #define AV_PIX_FMT_BAYER_RGGB16 AV_PIX_FMT_NE(BAYER_RGGB16BE, BAYER_RGGB16LE) #define AV_PIX_FMT_BAYER_GBRG16 AV_PIX_FMT_NE(BAYER_GBRG16BE, BAYER_GBRG16LE) #define AV_PIX_FMT_BAYER_GRBG16 AV_PIX_FMT_NE(BAYER_GRBG16BE, BAYER_GRBG16LE) -#define AV_PIX_FMT_GBRPF16 AV_PIX_FMT_NE(GBRPF16BE, GBRPF16LE) -#define AV_PIX_FMT_GBRAPF16 AV_PIX_FMT_NE(GBRAPF16BE, GBRAPF16LE) #define AV_PIX_FMT_GBRPF32 AV_PIX_FMT_NE(GBRPF32BE, GBRPF32LE) #define AV_PIX_FMT_GBRAPF32 AV_PIX_FMT_NE(GBRAPF32BE, GBRAPF32LE) -#define AV_PIX_FMT_GRAYF16 AV_PIX_FMT_NE(GRAYF16BE, GRAYF16LE) #define AV_PIX_FMT_GRAYF32 AV_PIX_FMT_NE(GRAYF32BE, GRAYF32LE) -#define AV_PIX_FMT_YAF16 AV_PIX_FMT_NE(YAF16BE, YAF16LE) -#define AV_PIX_FMT_YAF32 AV_PIX_FMT_NE(YAF32BE, YAF32LE) - #define AV_PIX_FMT_YUVA420P9 AV_PIX_FMT_NE(YUVA420P9BE , YUVA420P9LE) #define AV_PIX_FMT_YUVA422P9 AV_PIX_FMT_NE(YUVA422P9BE , YUVA422P9LE) #define AV_PIX_FMT_YUVA444P9 AV_PIX_FMT_NE(YUVA444P9BE , YUVA444P9LE) @@ -588,11 +531,8 @@ enum AVPixelFormat { #define AV_PIX_FMT_Y210 AV_PIX_FMT_NE(Y210BE, Y210LE) #define AV_PIX_FMT_Y212 AV_PIX_FMT_NE(Y212BE, Y212LE) -#define AV_PIX_FMT_Y216 AV_PIX_FMT_NE(Y216BE, Y216LE) #define AV_PIX_FMT_XV30 AV_PIX_FMT_NE(XV30BE, XV30LE) #define AV_PIX_FMT_XV36 AV_PIX_FMT_NE(XV36BE, XV36LE) -#define AV_PIX_FMT_XV48 AV_PIX_FMT_NE(XV48BE, XV48LE) -#define AV_PIX_FMT_V30X AV_PIX_FMT_NE(V30XBE, V30XLE) #define AV_PIX_FMT_X2RGB10 AV_PIX_FMT_NE(X2RGB10BE, X2RGB10LE) #define AV_PIX_FMT_X2BGR10 AV_PIX_FMT_NE(X2BGR10BE, X2BGR10LE) @@ -603,15 +543,11 @@ enum AVPixelFormat { #define AV_PIX_FMT_P216 AV_PIX_FMT_NE(P216BE, P216LE) #define AV_PIX_FMT_P416 AV_PIX_FMT_NE(P416BE, P416LE) -#define AV_PIX_FMT_RGBF16 AV_PIX_FMT_NE(RGBF16BE, RGBF16LE) #define AV_PIX_FMT_RGBAF16 AV_PIX_FMT_NE(RGBAF16BE, RGBAF16LE) #define AV_PIX_FMT_RGBF32 AV_PIX_FMT_NE(RGBF32BE, RGBF32LE) #define AV_PIX_FMT_RGBAF32 AV_PIX_FMT_NE(RGBAF32BE, RGBAF32LE) -#define AV_PIX_FMT_RGB96 AV_PIX_FMT_NE(RGB96BE, RGB96LE) -#define AV_PIX_FMT_RGBA128 AV_PIX_FMT_NE(RGBA128BE, RGBA128LE) - /** * Chromaticity coordinates of the source primaries. * These values match the ones defined by ISO/IEC 23091-2_2019 subclause 8.1 and ITU-T H.273. diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/version.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/version.h index 2979f802..753f85b9 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/version.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libavutil/version.h @@ -78,8 +78,8 @@ * @{ */ -#define LIBAVUTIL_VERSION_MAJOR 60 -#define LIBAVUTIL_VERSION_MINOR 3 +#define LIBAVUTIL_VERSION_MAJOR 59 +#define LIBAVUTIL_VERSION_MINOR 39 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ @@ -105,11 +105,16 @@ * @{ */ -#define FF_API_MOD_UINTP2 (LIBAVUTIL_VERSION_MAJOR < 61) -#define FF_API_RISCV_FD_ZBA (LIBAVUTIL_VERSION_MAJOR < 61) -#define FF_API_VULKAN_FIXED_QUEUES (LIBAVUTIL_VERSION_MAJOR < 61) -#define FF_API_OPT_INT_LIST (LIBAVUTIL_VERSION_MAJOR < 61) -#define FF_API_OPT_PTR (LIBAVUTIL_VERSION_MAJOR < 61) +#define FF_API_HDR_VIVID_THREE_SPLINE (LIBAVUTIL_VERSION_MAJOR < 60) +#define FF_API_FRAME_PKT (LIBAVUTIL_VERSION_MAJOR < 60) +#define FF_API_INTERLACED_FRAME (LIBAVUTIL_VERSION_MAJOR < 60) +#define FF_API_FRAME_KEY (LIBAVUTIL_VERSION_MAJOR < 60) +#define FF_API_PALETTE_HAS_CHANGED (LIBAVUTIL_VERSION_MAJOR < 60) +#define FF_API_VULKAN_CONTIGUOUS_MEMORY (LIBAVUTIL_VERSION_MAJOR < 60) +#define FF_API_H274_FILM_GRAIN_VCS (LIBAVUTIL_VERSION_MAJOR < 60) +#define FF_API_MOD_UINTP2 (LIBAVUTIL_VERSION_MAJOR < 60) +#define FF_API_RISCV_FD_ZBA (LIBAVUTIL_VERSION_MAJOR < 60) +#define FF_API_VULKAN_FIXED_QUEUES (LIBAVUTIL_VERSION_MAJOR < 60) /** * @} diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswresample/version.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswresample/version.h index 70302309..d1795b55 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswresample/version.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswresample/version.h @@ -30,7 +30,7 @@ #include "version_major.h" -#define LIBSWRESAMPLE_VERSION_MINOR 0 +#define LIBSWRESAMPLE_VERSION_MINOR 3 #define LIBSWRESAMPLE_VERSION_MICRO 100 #define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswresample/version_major.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswresample/version_major.h index 4e0bc0ab..dd13f2bb 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswresample/version_major.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswresample/version_major.h @@ -26,6 +26,6 @@ * Libswresample version macros */ -#define LIBSWRESAMPLE_VERSION_MAJOR 6 +#define LIBSWRESAMPLE_VERSION_MAJOR 5 #endif /* SWRESAMPLE_VERSION_MAJOR_H */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswscale/swscale.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswscale/swscale.h index b04aa182..e575695c 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswscale/swscale.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswscale/swscale.h @@ -1,5 +1,4 @@ /* - * Copyright (C) 2024 Niklas Haas * Copyright (C) 2001-2011 Michael Niedermayer * * This file is part of FFmpeg. @@ -62,308 +61,60 @@ const char *swscale_configuration(void); */ const char *swscale_license(void); -/** - * Get the AVClass for SwsContext. It can be used in combination with - * AV_OPT_SEARCH_FAKE_OBJ for examining options. - * - * @see av_opt_find(). - */ -const AVClass *sws_get_class(void); - -/****************************** - * Flags and quality settings * - ******************************/ - -typedef enum SwsDither { - SWS_DITHER_NONE = 0, /* disable dithering */ - SWS_DITHER_AUTO, /* auto-select from preset */ - SWS_DITHER_BAYER, /* ordered dither matrix */ - SWS_DITHER_ED, /* error diffusion */ - SWS_DITHER_A_DITHER, /* arithmetic addition */ - SWS_DITHER_X_DITHER, /* arithmetic xor */ - SWS_DITHER_NB, /* not part of the ABI */ -} SwsDither; - -typedef enum SwsAlphaBlend { - SWS_ALPHA_BLEND_NONE = 0, - SWS_ALPHA_BLEND_UNIFORM, - SWS_ALPHA_BLEND_CHECKERBOARD, - SWS_ALPHA_BLEND_NB, /* not part of the ABI */ -} SwsAlphaBlend; - -typedef enum SwsFlags { - /** - * Scaler selection options. Only one may be active at a time. - */ - SWS_FAST_BILINEAR = 1 << 0, ///< fast bilinear filtering - SWS_BILINEAR = 1 << 1, ///< bilinear filtering - SWS_BICUBIC = 1 << 2, ///< 2-tap cubic B-spline - SWS_X = 1 << 3, ///< experimental - SWS_POINT = 1 << 4, ///< nearest neighbor - SWS_AREA = 1 << 5, ///< area averaging - SWS_BICUBLIN = 1 << 6, ///< bicubic luma, bilinear chroma - SWS_GAUSS = 1 << 7, ///< gaussian approximation - SWS_SINC = 1 << 8, ///< unwindowed sinc - SWS_LANCZOS = 1 << 9, ///< 3-tap sinc/sinc - SWS_SPLINE = 1 << 10, ///< cubic Keys spline - - /** - * Return an error on underspecified conversions. Without this flag, - * unspecified fields are defaulted to sensible values. - */ - SWS_STRICT = 1 << 11, - - /** - * Emit verbose log of scaling parameters. - */ - SWS_PRINT_INFO = 1 << 12, - - /** - * Perform full chroma upsampling when upscaling to RGB. - * - * For example, when converting 50x50 yuv420p to 100x100 rgba, setting this flag - * will scale the chroma plane from 25x25 to 100x100 (4:4:4), and then convert - * the 100x100 yuv444p image to rgba in the final output step. - * - * Without this flag, the chroma plane is instead scaled to 50x100 (4:2:2), - * with a single chroma sample being re-used for both of the horizontally - * adjacent RGBA output pixels. - */ - SWS_FULL_CHR_H_INT = 1 << 13, - - /** - * Perform full chroma interpolation when downscaling RGB sources. - * - * For example, when converting a 100x100 rgba source to 50x50 yuv444p, setting - * this flag will generate a 100x100 (4:4:4) chroma plane, which is then - * downscaled to the required 50x50. - * - * Without this flag, the chroma plane is instead generated at 50x100 (dropping - * every other pixel), before then being downscaled to the required 50x50 - * resolution. - */ - SWS_FULL_CHR_H_INP = 1 << 14, - - /** - * Force bit-exact output. This will prevent the use of platform-specific - * optimizations that may lead to slight difference in rounding, in favor - * of always maintaining exact bit output compatibility with the reference - * C code. - * - * Note: It is recommended to set both of these flags simultaneously. - */ - SWS_ACCURATE_RND = 1 << 18, - SWS_BITEXACT = 1 << 19, - - /** - * Deprecated flags. - */ - SWS_DIRECT_BGR = 1 << 15, ///< This flag has no effect - SWS_ERROR_DIFFUSION = 1 << 23, ///< Set `SwsContext.dither` instead -} SwsFlags; - -typedef enum SwsIntent { - SWS_INTENT_PERCEPTUAL = 0, ///< Perceptual tone mapping - SWS_INTENT_RELATIVE_COLORIMETRIC = 1, ///< Relative colorimetric clipping - SWS_INTENT_SATURATION = 2, ///< Saturation mapping - SWS_INTENT_ABSOLUTE_COLORIMETRIC = 3, ///< Absolute colorimetric clipping - SWS_INTENT_NB, ///< not part of the ABI -} SwsIntent; - -/*********************************** - * Context creation and management * - ***********************************/ - -/** - * Main external API structure. New fields can be added to the end with - * minor version bumps. Removal, reordering and changes to existing fields - * require a major version bump. sizeof(SwsContext) is not part of the ABI. - */ -typedef struct SwsContext { - const AVClass *av_class; - - /** - * Private data of the user, can be used to carry app specific stuff. - */ - void *opaque; - - /** - * Bitmask of SWS_*. See `SwsFlags` for details. - */ - unsigned flags; - - /** - * Extra parameters for fine-tuning certain scalers. - */ - double scaler_params[2]; - - /** - * How many threads to use for processing, or 0 for automatic selection. - */ - int threads; - - /** - * Dither mode. - */ - SwsDither dither; - - /** - * Alpha blending mode. See `SwsAlphaBlend` for details. - */ - SwsAlphaBlend alpha_blend; - - /** - * Use gamma correct scaling. - */ - int gamma_flag; - - /** - * Deprecated frame property overrides, for the legacy API only. - * - * Ignored by sws_scale_frame() when used in dynamic mode, in which - * case all properties are instead taken from the frame directly. - */ - int src_w, src_h; ///< Width and height of the source frame - int dst_w, dst_h; ///< Width and height of the destination frame - int src_format; ///< Source pixel format - int dst_format; ///< Destination pixel format - int src_range; ///< Source is full range - int dst_range; ///< Destination is full range - int src_v_chr_pos; ///< Source vertical chroma position in luma grid / 256 - int src_h_chr_pos; ///< Source horizontal chroma position - int dst_v_chr_pos; ///< Destination vertical chroma position - int dst_h_chr_pos; ///< Destination horizontal chroma position - - /** - * Desired ICC intent for color space conversions. - */ - int intent; - - /* Remember to add new fields to graph.c:opts_equal() */ -} SwsContext; - -/** - * Allocate an empty SwsContext and set its fields to default values. - */ -SwsContext *sws_alloc_context(void); - -/** - * Free the context and everything associated with it, and write NULL - * to the provided pointer. - */ -void sws_free_context(SwsContext **ctx); - -/*************************** - * Supported frame formats * - ***************************/ - -/** - * Test if a given pixel format is supported. - * - * @param output If 0, test if compatible with the source/input frame; - * otherwise, with the destination/output frame. - * @param format The format to check. - * - * @return A positive integer if supported, 0 otherwise. - */ -int sws_test_format(enum AVPixelFormat format, int output); - -/** - * Test if a given color space is supported. - * - * @param output If 0, test if compatible with the source/input frame; - * otherwise, with the destination/output frame. - * @param colorspace The colorspace to check. - * - * @return A positive integer if supported, 0 otherwise. - */ -int sws_test_colorspace(enum AVColorSpace colorspace, int output); - -/** - * Test if a given set of color primaries is supported. - * - * @param output If 0, test if compatible with the source/input frame; - * otherwise, with the destination/output frame. - * @param primaries The color primaries to check. - * - * @return A positive integer if supported, 0 otherwise. - */ -int sws_test_primaries(enum AVColorPrimaries primaries, int output); - -/** - * Test if a given color transfer function is supported. - * - * @param output If 0, test if compatible with the source/input frame; - * otherwise, with the destination/output frame. - * @param trc The color transfer function to check. - * - * @return A positive integer if supported, 0 otherwise. - */ -int sws_test_transfer(enum AVColorTransferCharacteristic trc, int output); - -/** - * Helper function to run all sws_test_* against a frame, as well as testing - * the basic frame properties for sanity. Ignores irrelevant properties - for - * example, AVColorSpace is not checked for RGB frames. - */ -int sws_test_frame(const AVFrame *frame, int output); - -/** - * Like `sws_scale_frame`, but without actually scaling. It will instead - * merely initialize internal state that *would* be required to perform the - * operation, as well as returning the correct error code for unsupported - * frame combinations. - * - * @param ctx The scaling context. - * @param dst The destination frame to consider. - * @param src The source frame to consider. - * @return 0 on success, a negative AVERROR code on failure. - */ -int sws_frame_setup(SwsContext *ctx, const AVFrame *dst, const AVFrame *src); - -/******************** - * Main scaling API * - ********************/ - -/** - * Check if a given conversion is a noop. Returns a positive integer if - * no operation needs to be performed, 0 otherwise. - */ -int sws_is_noop(const AVFrame *dst, const AVFrame *src); - -/** - * Scale source data from `src` and write the output to `dst`. - * - * This function can be used directly on an allocated context, without setting - * up any frame properties or calling `sws_init_context()`. Such usage is fully - * dynamic and does not require reallocation if the frame properties change. - * - * Alternatively, this function can be called on a context that has been - * explicitly initialized. However, this is provided only for backwards - * compatibility. In this usage mode, all frame properties must be correctly - * set at init time, and may no longer change after initialization. - * - * @param ctx The scaling context. - * @param dst The destination frame. The data buffers may either be already - * allocated by the caller or left clear, in which case they will - * be allocated by the scaler. The latter may have performance - * advantages - e.g. in certain cases some (or all) output planes - * may be references to input planes, rather than copies. - * @param src The source frame. If the data buffers are set to NULL, then - * this function behaves identically to `sws_frame_setup`. - * @return >= 0 on success, a negative AVERROR code on failure. - */ -int sws_scale_frame(SwsContext *c, AVFrame *dst, const AVFrame *src); - -/************************* - * Legacy (stateful) API * - *************************/ +/* values for the flags, the stuff on the command line is different */ +#define SWS_FAST_BILINEAR 1 +#define SWS_BILINEAR 2 +#define SWS_BICUBIC 4 +#define SWS_X 8 +#define SWS_POINT 0x10 +#define SWS_AREA 0x20 +#define SWS_BICUBLIN 0x40 +#define SWS_GAUSS 0x80 +#define SWS_SINC 0x100 +#define SWS_LANCZOS 0x200 +#define SWS_SPLINE 0x400 #define SWS_SRC_V_CHR_DROP_MASK 0x30000 #define SWS_SRC_V_CHR_DROP_SHIFT 16 #define SWS_PARAM_DEFAULT 123456 +#define SWS_PRINT_INFO 0x1000 + +//the following 3 flags are not completely implemented + +/** + * Perform full chroma upsampling when upscaling to RGB. + * + * For example, when converting 50x50 yuv420p to 100x100 rgba, setting this flag + * will scale the chroma plane from 25x25 to 100x100 (4:4:4), and then convert + * the 100x100 yuv444p image to rgba in the final output step. + * + * Without this flag, the chroma plane is instead scaled to 50x100 (4:2:2), + * with a single chroma sample being re-used for both of the horizontally + * adjacent RGBA output pixels. + */ +#define SWS_FULL_CHR_H_INT 0x2000 + +/** + * Perform full chroma interpolation when downscaling RGB sources. + * + * For example, when converting a 100x100 rgba source to 50x50 yuv444p, setting + * this flag will generate a 100x100 (4:4:4) chroma plane, which is then + * downscaled to the required 50x50. + * + * Without this flag, the chroma plane is instead generated at 50x100 (dropping + * every other pixel), before then being downscaled to the required 50x50 + * resolution. + */ +#define SWS_FULL_CHR_H_INP 0x4000 + +#define SWS_DIRECT_BGR 0x8000 + +#define SWS_ACCURATE_RND 0x40000 +#define SWS_BITEXACT 0x80000 +#define SWS_ERROR_DIFFUSION 0x800000 + #define SWS_MAX_REDUCE_CUTOFF 0.002 #define SWS_CS_ITU709 1 @@ -399,6 +150,8 @@ typedef struct SwsFilter { SwsVector *chrV; } SwsFilter; +struct SwsContext; + /** * Return a positive value if pix_fmt is a supported input format, 0 * otherwise. @@ -418,25 +171,27 @@ int sws_isSupportedOutput(enum AVPixelFormat pix_fmt); */ int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt); +/** + * Allocate an empty SwsContext. This must be filled and passed to + * sws_init_context(). For filling see AVOptions, options.c and + * sws_setColorspaceDetails(). + */ +struct SwsContext *sws_alloc_context(void); + /** * Initialize the swscaler context sws_context. * - * This function is considered deprecated, and provided only for backwards - * compatibility with sws_scale() and sws_start_frame(). The preferred way to - * use libswscale is to set all frame properties correctly and call - * sws_scale_frame() directly, without explicitly initializing the context. - * * @return zero or positive value on success, a negative value on * error */ av_warn_unused_result -int sws_init_context(SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter); +int sws_init_context(struct SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter); /** * Free the swscaler context swsContext. * If swsContext is NULL, then does nothing. */ -void sws_freeContext(SwsContext *swsContext); +void sws_freeContext(struct SwsContext *swsContext); /** * Allocate and return an SwsContext. You need it to perform @@ -459,16 +214,15 @@ void sws_freeContext(SwsContext *swsContext); * @note this function is to be removed after a saner alternative is * written */ -SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, - int dstW, int dstH, enum AVPixelFormat dstFormat, - int flags, SwsFilter *srcFilter, - SwsFilter *dstFilter, const double *param); +struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, + int dstW, int dstH, enum AVPixelFormat dstFormat, + int flags, SwsFilter *srcFilter, + SwsFilter *dstFilter, const double *param); /** * Scale the image slice in srcSlice and put the resulting scaled * slice in the image in dst. A slice is a sequence of consecutive - * rows in an image. Requires a context that has been previously - * been initialized with sws_init_context(). + * rows in an image. * * Slices have to be provided in sequential order, either in * top-bottom or bottom-top order. If slices are provided in @@ -491,15 +245,31 @@ SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, * the destination image * @return the height of the output slice */ -int sws_scale(SwsContext *c, const uint8_t *const srcSlice[], +int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]); +/** + * Scale source data from src and write the output to dst. + * + * This is merely a convenience wrapper around + * - sws_frame_start() + * - sws_send_slice(0, src->height) + * - sws_receive_slice(0, dst->height) + * - sws_frame_end() + * + * @param c The scaling context + * @param dst The destination frame. See documentation for sws_frame_start() for + * more details. + * @param src The source frame. + * + * @return 0 on success, a negative AVERROR code on failure + */ +int sws_scale_frame(struct SwsContext *c, AVFrame *dst, const AVFrame *src); + /** * Initialize the scaling process for a given pair of source/destination frames. * Must be called before any calls to sws_send_slice() and sws_receive_slice(). - * Requires a context that has been previously been initialized with - * sws_init_context(). * * This function will retain references to src and dst, so they must both use * refcounted buffers (if allocated by the caller, in case of dst). @@ -522,7 +292,7 @@ int sws_scale(SwsContext *c, const uint8_t *const srcSlice[], * * @see sws_frame_end() */ -int sws_frame_start(SwsContext *c, AVFrame *dst, const AVFrame *src); +int sws_frame_start(struct SwsContext *c, AVFrame *dst, const AVFrame *src); /** * Finish the scaling process for a pair of source/destination frames previously @@ -532,7 +302,7 @@ int sws_frame_start(SwsContext *c, AVFrame *dst, const AVFrame *src); * * @param c The scaling context */ -void sws_frame_end(SwsContext *c); +void sws_frame_end(struct SwsContext *c); /** * Indicate that a horizontal slice of input data is available in the source @@ -546,7 +316,7 @@ void sws_frame_end(SwsContext *c); * * @return a non-negative number on success, a negative AVERROR code on failure. */ -int sws_send_slice(SwsContext *c, unsigned int slice_start, +int sws_send_slice(struct SwsContext *c, unsigned int slice_start, unsigned int slice_height); /** @@ -566,19 +336,18 @@ int sws_send_slice(SwsContext *c, unsigned int slice_start, * output can be produced * another negative AVERROR code on other kinds of scaling failure */ -int sws_receive_slice(SwsContext *c, unsigned int slice_start, +int sws_receive_slice(struct SwsContext *c, unsigned int slice_start, unsigned int slice_height); /** - * Get the alignment required for slices. Requires a context that has been - * previously been initialized with sws_init_context(). + * Get the alignment required for slices * * @param c The scaling context * @return alignment required for output slices requested with sws_receive_slice(). * Slice offsets and sizes passed to sws_receive_slice() must be * multiples of the value returned from this function. */ -unsigned int sws_receive_slice_alignment(const SwsContext *c); +unsigned int sws_receive_slice_alignment(const struct SwsContext *c); /** * @param c the scaling context @@ -593,7 +362,7 @@ unsigned int sws_receive_slice_alignment(const SwsContext *c); * @return A negative error code on error, non negative otherwise. * If `LIBSWSCALE_VERSION_MAJOR < 7`, returns -1 if not supported. */ -int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], +int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation); @@ -601,7 +370,7 @@ int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], * @return A negative error code on error, non negative otherwise. * If `LIBSWSCALE_VERSION_MAJOR < 7`, returns -1 if not supported. */ -int sws_getColorspaceDetails(SwsContext *c, int **inv_table, +int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation); @@ -646,11 +415,11 @@ void sws_freeFilter(SwsFilter *filter); * Be warned that srcFilter and dstFilter are not checked, they * are assumed to remain the same. */ -SwsContext *sws_getCachedContext(SwsContext *context, int srcW, int srcH, - enum AVPixelFormat srcFormat, int dstW, int dstH, - enum AVPixelFormat dstFormat, int flags, - SwsFilter *srcFilter, SwsFilter *dstFilter, - const double *param); +struct SwsContext *sws_getCachedContext(struct SwsContext *context, + int srcW, int srcH, enum AVPixelFormat srcFormat, + int dstW, int dstH, enum AVPixelFormat dstFormat, + int flags, SwsFilter *srcFilter, + SwsFilter *dstFilter, const double *param); /** * Convert an 8-bit paletted frame into a frame with a color depth of 32 bits. @@ -676,6 +445,14 @@ void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pix */ void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette); +/** + * Get the AVClass for swsContext. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + */ +const AVClass *sws_get_class(void); + /** * @} */ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswscale/version.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswscale/version.h index 148efd83..51eb013a 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswscale/version.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswscale/version.h @@ -28,7 +28,7 @@ #include "version_major.h" -#define LIBSWSCALE_VERSION_MINOR 0 +#define LIBSWSCALE_VERSION_MINOR 3 #define LIBSWSCALE_VERSION_MICRO 100 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ diff --git a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswscale/version_major.h b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswscale/version_major.h index 0dc50792..fd259f95 100644 --- a/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswscale/version_major.h +++ b/CC_SDK/Environment/FFmpeg/include/Linux/Armv7/include/libswscale/version_major.h @@ -24,7 +24,7 @@ * swscale version macros */ -#define LIBSWSCALE_VERSION_MAJOR 9 +#define LIBSWSCALE_VERSION_MAJOR 8 /** * FF_API_* defines may be placed below to indicate public API that will be diff --git a/CC_SDK/Environment/FFmpeg/src/CCMP3.cpp b/CC_SDK/Environment/FFmpeg/src/CCMP3.cpp index 28ad8415..0ec0341c 100644 --- a/CC_SDK/Environment/FFmpeg/src/CCMP3.cpp +++ b/CC_SDK/Environment/FFmpeg/src/CCMP3.cpp @@ -8,14 +8,39 @@ CTL::MP3Header::MP3Header(const char *filename) { CTL::MP3Header::~MP3Header() { if (codec_ctx) { + AVPacket empty_pkt = {nullptr}; + empty_pkt.data = nullptr; + empty_pkt.size = 0; + empty_pkt.stream_index = audio_stream_index; + + // 刷新解码器 + avcodec_send_packet(codec_ctx, &empty_pkt); + av_packet_unref(&empty_pkt); + + // 处理剩余帧(可选) + AVFrame* frame = av_frame_alloc(); + while (avcodec_receive_frame(codec_ctx, frame) >= 0) { + av_frame_unref(frame); + } + av_frame_free(&frame); avcodec_free_context(&codec_ctx); codec_ctx = nullptr; } - avformat_close_input(&format_ctx); - format_ctx = nullptr; + if (format_ctx) { + avformat_close_input(&format_ctx); + format_ctx = nullptr; + } } void CTL::MP3Header::Init(const char *filename) { + if (format_ctx || codec_ctx || codec_params) { + avcodec_free_context(&codec_ctx); + codec_ctx = nullptr; + avformat_close_input(&format_ctx); + format_ctx = nullptr; + avcodec_parameters_free(&codec_params); + codec_params = nullptr; + } FILE* file = nullptr; #ifdef _WIN32 SetConsoleOutputCP(65001); @@ -127,6 +152,10 @@ void CTL::MP3Header::Init(const char *filename) { } } +void CTL::MP3Header::SetLevelLog(int level) { + av_log_set_level(level); +} + AVFormatContext * CTL::MP3Header::GetFormatContext() const { return format_ctx; } @@ -145,32 +174,21 @@ int CTL::MP3Header::GetAudioStreamIndex() const { std::vector> CTL::MP3Header::ExtractMP3Frames() { std::vector> allFrames; - - // 确保已初始化格式上下文 - if (!format_ctx) { - std::cerr << "Format context not initialized" << std::endl; - return allFrames; - } - - // 分配AVPacket AVPacket* packet = av_packet_alloc(); if (!packet) { std::cerr << "Failed to allocate packet" << std::endl; return allFrames; } - // 读取每一帧 while (av_read_frame(format_ctx, packet) >= 0) { - // 只处理音频流 - if (packet->stream_index == audio_stream_index && packet->size > 0) { - // 创建一个新的vector存储当前帧数据 + if (packet->stream_index == audio_stream_index) { std::vector frameData(packet->data, packet->data + packet->size); allFrames.push_back(std::move(frameData)); } - av_packet_unref(packet); + av_packet_unref(packet); // 仅在循环内释放 } - av_packet_free(&packet); + av_packet_free(&packet); // 循环结束后统一释放 return allFrames; } @@ -192,6 +210,7 @@ int CTL::MP3Header::GetFrameLength(const int audio_stream_index) const { } av_seek_frame(format_ctx, audio_stream_index, 0, AVSEEK_FLAG_BACKWARD); + av_packet_unref(packet); av_packet_free(&packet); // 新增:释放packet内存 return total_frames; @@ -285,6 +304,7 @@ CTL::PCM CTL::MP3Frame::DecodeAudioFrames(const MP3Header* header,const PCM_Form int out_linesize = 0; if (av_samples_alloc(out_data, &out_linesize, format.Channels, max_out_samples, out_sample_fmt, 0) < 0) { + av_freep(&out_data[0]); swr_free(&swr); continue; } @@ -308,7 +328,11 @@ CTL::PCM CTL::MP3Frame::DecodeAudioFrames(const MP3Header* header,const PCM_Form // 释放重采样器和输出缓冲区 av_freep(&out_data[0]); - swr_free(&swr); + swr_close(swr); + if (swr) { + swr_free(&swr); // 显式释放 SwrContext + swr = nullptr; + } } } diff --git a/CC_SDK/Environment/FFmpeg/src/CCMP3.h b/CC_SDK/Environment/FFmpeg/src/CCMP3.h index 3accfb98..69f64515 100644 --- a/CC_SDK/Environment/FFmpeg/src/CCMP3.h +++ b/CC_SDK/Environment/FFmpeg/src/CCMP3.h @@ -39,6 +39,7 @@ namespace CTL { explicit MP3Header(const char* filename); ~MP3Header(); void Init(const char* filename); + static void SetLevelLog(int level); [[nodiscard]] AVFormatContext* GetFormatContext() const; [[nodiscard]] AVCodecParameters* GetCodecParameters() const; [[nodiscard]] AVCodecContext* GetAVCodecContext() const; diff --git a/CC_SDK/Environment/cppp-reiconv/CMakeLists.txt b/CC_SDK/Environment/cppp-reiconv/CMakeLists.txt index 5e962677..c4ca3013 100644 --- a/CC_SDK/Environment/cppp-reiconv/CMakeLists.txt +++ b/CC_SDK/Environment/cppp-reiconv/CMakeLists.txt @@ -121,11 +121,24 @@ install(FILES "${output_includedir}/cppp/reiconv.hpp.inst" RENAME "cppp/reiconv.hpp" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ) -file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +if (CMAKE_HOST_WIN32) + file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + add_custom_command(TARGET libcppp-reiconv.shared POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ + ${CMAKE_BINARY_DIR}/bin + COMMENT "Copying libcppp-reiconv.shared library to bin directory" + ) +else () + set(BIN_DIR "${CMAKE_BINARY_DIR}/bin") + file(TO_NATIVE_PATH "${BIN_DIR}" NATIVE_BIN_DIR) -add_custom_command(TARGET libcppp-reiconv.static POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - $ - ${CMAKE_BINARY_DIR}/bin - COMMENT "Copying libcppp-reiconv.static library to bin directory" -) \ No newline at end of file + add_custom_command(TARGET libcppp-reiconv.shared POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "${NATIVE_BIN_DIR}" + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "$" + "${NATIVE_BIN_DIR}" + COMMENT "Copying library..." + VERBATIM + ) +endif () \ No newline at end of file diff --git a/CC_SDK/Environment/libdatachannel/deps/plog/CMakeLists.txt b/CC_SDK/Environment/libdatachannel/deps/plog/CMakeLists.txt index 57c1f518..3de1e68b 100644 --- a/CC_SDK/Environment/libdatachannel/deps/plog/CMakeLists.txt +++ b/CC_SDK/Environment/libdatachannel/deps/plog/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.0...3.5) project(plog VERSION 1.1.10 LANGUAGES CXX) diff --git a/CC_SDK/Environment/libdatachannel/deps/usrsctp/CMakeLists.txt b/CC_SDK/Environment/libdatachannel/deps/usrsctp/CMakeLists.txt index 3fc4ec6a..16a2cd18 100644 --- a/CC_SDK/Environment/libdatachannel/deps/usrsctp/CMakeLists.txt +++ b/CC_SDK/Environment/libdatachannel/deps/usrsctp/CMakeLists.txt @@ -30,7 +30,7 @@ # project(usrsctplib C) -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.0...3.5) # Debug build type as default if (NOT CMAKE_BUILD_TYPE) diff --git a/CC_SDK/Environment/libdatachannel/deps/usrsctp/programs/http_client_upcall.c b/CC_SDK/Environment/libdatachannel/deps/usrsctp/programs/http_client_upcall.c index 04221c25..c3e57993 100644 --- a/CC_SDK/Environment/libdatachannel/deps/usrsctp/programs/http_client_upcall.c +++ b/CC_SDK/Environment/libdatachannel/deps/usrsctp/programs/http_client_upcall.c @@ -73,6 +73,10 @@ char request[512]; typedef char* caddr_t; #endif +#if defined (__OHOS__) + +#endif + #define BUFFERSIZE (1<<16) static void handle_upcall(struct socket *sock, void *arg, int flgs) @@ -112,6 +116,10 @@ static void handle_upcall(struct socket *sock, void *arg, int flgs) } else { #ifdef _WIN32 _write(_fileno(stdout), buf, (unsigned int)n); +#elif __OHOS__ + if (fwrite(buf, 1, n, stdout) != (size_t)n) { + perror("fwrite"); + } #else if (write(fileno(stdout), buf, n) < 0) { perror("write"); diff --git a/CC_SDK/Environment/libdatachannel/deps/usrsctp/programs/programs_helper.h b/CC_SDK/Environment/libdatachannel/deps/usrsctp/programs/programs_helper.h index 97a47101..866401c3 100644 --- a/CC_SDK/Environment/libdatachannel/deps/usrsctp/programs/programs_helper.h +++ b/CC_SDK/Environment/libdatachannel/deps/usrsctp/programs/programs_helper.h @@ -28,6 +28,9 @@ #ifndef __PROGRAMS_HELPER_H__ #define __PROGRAMS_HELPER_H__ + + + #ifndef _WIN32 #define SCTP_PACKED __attribute__((packed)) #else @@ -35,6 +38,13 @@ #define SCTP_PACKED #endif +#if defined (__OHOS__) +#include "_bab_tpyes_t.h" +#include "stdint.h" +#include +#include +#endif + struct sctp_chunk_header { uint8_t chunk_type; /* chunk type */ uint8_t chunk_flags; /* chunk flags */ diff --git a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/_bab_tpyes_t.h b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/_bab_tpyes_t.h index 8f8d2d81..7c3af8d7 100644 --- a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/_bab_tpyes_t.h +++ b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/_bab_tpyes_t.h @@ -4,6 +4,7 @@ typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; +//typedef unsigned long size_t; #pragma push_macro("u_long") #undef u_long typedef unsigned long u_long; @@ -17,6 +18,29 @@ typedef unsigned long long u_int64; #endif /* _BSDTYPES_DEFINED */ +#ifdef __OHOS__ +#include "sys/time.h" +typedef char* caddr_t; +#ifndef timersub +#define timersub(s,t,a) (void) ( (a)->tv_sec = (s)->tv_sec - (t)->tv_sec, \ + ((a)->tv_usec = (s)->tv_usec - (t)->tv_usec) < 0 && \ + ((a)->tv_usec += 1000000, (a)->tv_sec--) ) +#endif // timersub + +#ifndef timercmp +#define timercmp(s,t,op) ((s)->tv_sec == (t)->tv_sec ? \ + (s)->tv_usec op (t)->tv_usec : (s)->tv_sec op (t)->tv_sec) +#endif // timercmp + +#ifndef timeradd +#define timeradd(s,t,a) (void) ( (a)->tv_sec = (s)->tv_sec + (t)->tv_sec, \ + ((a)->tv_usec = (s)->tv_usec + (t)->tv_usec) >= 1000000 && \ + ((a)->tv_usec -= 1000000, (a)->tv_sec++) ) +#endif // timeradd + +#endif // __OHOS__ + + #if defined (__LP64__) && defined (u_long) typedef unsigned __LONG32 u_long; diff --git a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_asconf.c b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_asconf.c index 5d9edd3e..7a6faba6 100644 --- a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_asconf.c +++ b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_asconf.c @@ -1,37 +1,3 @@ -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. - * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * a) Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * b) Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - * c) Neither the name of Cisco Systems, Inc. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - #include #include #include @@ -42,35 +8,14 @@ #include #include -/* - * debug flags: - * SCTP_DEBUG_ASCONF1: protocol info, general info and errors - * SCTP_DEBUG_ASCONF2: detailed info - */ -/* - * RFC 5061 - * - * An ASCONF parameter queue exists per asoc which holds the pending address - * operations. Lists are updated upon receipt of ASCONF-ACK. - * - * A restricted_addrs list exists per assoc to hold local addresses that are - * not (yet) usable by the assoc as a source address. These addresses are - * either pending an ASCONF operation (and exist on the ASCONF parameter - * queue), or they are permanently restricted (the peer has returned an - * ERROR indication to an ASCONF(ADD), or the peer does not support ASCONF). - * - * Deleted addresses are always immediately removed from the lists as they will - * (shortly) no longer exist in the kernel. We send ASCONFs as a courtesy, - * only if allowed. - */ -/* - * ASCONF parameter processing. - * response_required: set if a reply is required (eg. SUCCESS_REPORT). - * returns a mbuf to an "error" response parameter or NULL/"success" if ok. - * FIX: allocating this many mbufs on the fly is pretty inefficient... - */ +#if defined (__OHOS__) +#include "_bab_tpyes_t.h" +#include +#include "user_queue.h" // 确保 TAILQ_HEAD 等宏被正确定义 +#endif + static struct mbuf * sctp_asconf_success_response(uint32_t id) { diff --git a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_indata.c b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_indata.c index 91980d3a..f38d9036 100644 --- a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_indata.c +++ b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_indata.c @@ -53,6 +53,11 @@ #if defined(__FreeBSD__) && !defined(__Userspace__) #include #endif + +#if defined (__OHOS__) +#include "../_bab_tpyes_t.h" +#endif + /* * NOTES: On the outbound side of things I need to check the sack timer to * see if I should generate a sack into the chunk queue (if I have data to diff --git a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_os_userspace.h b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_os_userspace.h index 493ae026..ef7b78b6 100644 --- a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_os_userspace.h +++ b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_os_userspace.h @@ -41,6 +41,7 @@ * We will place them in userspace stack build directory. */ + #include #if defined(_WIN32) @@ -298,6 +299,16 @@ typedef pthread_cond_t userland_cond_t; typedef pthread_t userland_thread_t; #endif +#if defined (__OHOS__) +#define IFNAMSIZ 64 +#include "_bab_tpyes_t.h" +#include "stdint.h" +#if !defined(_WIN32) && !defined(__native_client__) +#include // 确保在此处包含 +#endif +#include +#endif + #if defined(_WIN32) || defined(__native_client__) #define IFNAMSIZ 64 @@ -360,11 +371,16 @@ struct udphdr { uint16_t uh_sum; }; +#if !defined(__OHOS__) struct iovec { size_t len; char *buf; }; +#define iov_base buf +#define iov_len len +#endif + #define iov_base buf #define iov_len len @@ -461,7 +477,7 @@ struct sx {int dummy;}; * userspace as well? */ /* on FreeBSD, this results in a redefintion of struct route */ /* #include */ -#if !defined(_WIN32) && !defined(__native_client__) +#if !defined(_WIN32) && !defined(__native_client__) && !defined(__OHOS__) #include #include #include diff --git a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_output.c b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_output.c index 85b78864..1e8a49ad 100644 --- a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_output.c +++ b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_output.c @@ -80,6 +80,10 @@ #endif #endif +#if defined (__OHOS__) +#include "../_bab_tpyes_t.h" +#endif + #define SCTP_MAX_GAPS_INARRAY 4 struct sack_track { uint8_t right_edge; /* mergable on the right edge */ diff --git a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_pcb.h b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_pcb.h index 5298afc2..92e717c9 100644 --- a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_pcb.h +++ b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_pcb.h @@ -50,6 +50,10 @@ LIST_HEAD(sctp_ifalist, sctp_ifa); TAILQ_HEAD(sctp_readhead, sctp_queued_to_read); TAILQ_HEAD(sctp_streamhead, sctp_stream_queue_pending); +#if defined (__OHOS__) +#include "sctp_os_userspace.h" +#endif + #include #include diff --git a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_timer.c b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_timer.c index 497f2f0b..f9d65a50 100644 --- a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_timer.c +++ b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/netinet/sctp_timer.c @@ -57,6 +57,10 @@ #endif #endif +#if defined (__OHOS__) +#include "../_bab_tpyes_t.h" +#endif + void sctp_audit_retranmission_queue(struct sctp_association *asoc) { @@ -622,11 +626,18 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb, } if (stcb->asoc.prsctp_supported && PR_SCTP_TTL_ENABLED(chk->flags)) { /* Is it expired? */ -#if !(defined(__FreeBSD__) && !defined(__Userspace__)) - if (timercmp(&now, &chk->rec.data.timetodrop, >)) { +#if defined (__OHOS__) && 0 + if ((now.tv_sec > chk->rec.data.timetodrop.tv_sec) || + (now.tv_sec == chk->rec.data.timetodrop.tv_sec && + now.tv_usec > chk->rec.data.timetodrop.tv_usec)) { #else - if (timevalcmp(&now, &chk->rec.data.timetodrop, >)) { + #if !(defined(__FreeBSD__) && !defined(__Userspace__)) + if (timercmp(&now, &chk->rec.data.timetodrop, >)) { + #else + if (timevalcmp(&now, &chk->rec.data.timetodrop, >)) { + #endif #endif + /* Yes so drop it */ if (chk->data) { (void)sctp_release_pr_sctp_chunk(stcb, diff --git a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/user_malloc.h b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/user_malloc.h index c588e094..6996e6cc 100644 --- a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/user_malloc.h +++ b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/user_malloc.h @@ -52,6 +52,10 @@ #include #endif +#if defined (__OHOS__) +#include "_bab_tpyes_t.h" +#endif + #define MINALLOCSIZE UMA_SMALLEST_UNIT /* diff --git a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/user_socketvar.h b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/user_socketvar.h index e8eccc7f..d80fe5c6 100644 --- a/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/user_socketvar.h +++ b/CC_SDK/Environment/libdatachannel/deps/usrsctp/usrsctplib/user_socketvar.h @@ -33,11 +33,20 @@ #ifndef _USER_SOCKETVAR_H_ #define _USER_SOCKETVAR_H_ + + #if defined(__APPLE__) #include #include #endif +#if defined (__OHOS__) +#include "_bab_tpyes_t.h" +#include "netinet/sctp_os_userspace.h" +#include "user_malloc.h" +#include "user_queue.h" +#endif + /* #include */ /*__Userspace__ alternative?*/ /* for struct selinfo */ /* #include was 0 byte file */ /* #include was 0 byte file */ diff --git a/CC_SDK/Environment/libdatachannel/src/impl/utils.cpp b/CC_SDK/Environment/libdatachannel/src/impl/utils.cpp index ea5f10d4..4b25b6f0 100644 --- a/CC_SDK/Environment/libdatachannel/src/impl/utils.cpp +++ b/CC_SDK/Environment/libdatachannel/src/impl/utils.cpp @@ -155,7 +155,7 @@ void thread_set_name_self(const char *name) { HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); if (kernel32 != nullptr) { auto pSetThreadDescription = - (pfnSetThreadDescription)GetProcAddress(kernel32, "SetThreadDescription"); + reinterpret_cast(GetProcAddress(kernel32, "SetThreadDescription")); if (pSetThreadDescription != nullptr) { pSetThreadDescription(GetCurrentThread(), wname.c_str()); } diff --git a/CC_SDK/Include/CCServlet/CCHttpClient.h b/CC_SDK/Include/CCServlet/CCHttpClient.h index ec07532a..e31386c0 100644 --- a/CC_SDK/Include/CCServlet/CCHttpClient.h +++ b/CC_SDK/Include/CCServlet/CCHttpClient.h @@ -3,7 +3,7 @@ #pragma once // 包含必要的头文件 -#include "CCSocket.h" +#include "../Module/Comm/Socket/CCSocket.h" #include "CCJSONObject.h" #include "CCString.h" #include diff --git a/CC_SDK/Include/CCServlet/CCRequest.h b/CC_SDK/Include/CCServlet/CCRequest.h index 11362c47..f579525b 100644 --- a/CC_SDK/Include/CCServlet/CCRequest.h +++ b/CC_SDK/Include/CCServlet/CCRequest.h @@ -19,7 +19,7 @@ // 定义请求和响应的缓冲区大小以及文件缓冲区的最大值 #define CC_R_BUFFER_SIZE 1 #define CC_S_BUFFER_SIZE 1024 -// #define File_Buffer_Max 4096 +#define File_Buffer_Max 4096 namespace CTL { // 请求数据结构体,用于存储HTTP请求的相关信息 @@ -51,7 +51,7 @@ namespace CTL { CORS* cors = nullptr; // SSL对象指针 SSL* ssl = nullptr; - int File_Buffer_Max = 4096; + // int File_Buffer_Max = 4096; bool IsFileUploadSize = true; public: /** @@ -90,7 +90,7 @@ namespace CTL { * 获取JSON对象 * @return JSON对象 */ - CTL::JSONObject GetJson(); + CTL::JSONObject GetJson() const; /** * 获取媒体文件 diff --git a/CC_SDK/Include/CCServlet/CCResponse.h b/CC_SDK/Include/CCServlet/CCResponse.h index 67003bce..cd3ec702 100644 --- a/CC_SDK/Include/CCServlet/CCResponse.h +++ b/CC_SDK/Include/CCServlet/CCResponse.h @@ -147,7 +147,7 @@ namespace CTL { * @param size 缓冲区大小。 * @return 如果数据发送成功返回 true,否则返回 false。 */ - bool WriteSSLResponse(SSL* ssl, const char* buffer, size_t size); + int WriteSSLResponse(SSL* ssl, const char* buffer, size_t size); private: /// 文件头信息映射表。 @@ -164,6 +164,8 @@ namespace CTL { /// SSL 对象。 SSL* ssl = nullptr; + + bool m_status = false; }; } diff --git a/CC_SDK/Include/CCServlet/CCWebServlet.h b/CC_SDK/Include/CCServlet/CCWebServlet.h index 1f5bcb5d..5942704d 100644 --- a/CC_SDK/Include/CCServlet/CCWebServlet.h +++ b/CC_SDK/Include/CCServlet/CCWebServlet.h @@ -63,6 +63,7 @@ namespace CTL { // 设置请求头缓冲区大小 unsigned int ReadHBuff = 4096; IPVX IPvx = IPV4; + bool source_map_ = false; public: // 构造函数 WebServlet(); @@ -73,7 +74,7 @@ namespace CTL { // 初始化服务器 bool Init(const String& address,int Port,bool ChokeUp = true); // 设置 WebSocket 配置 - bool SetWebSocket(const WebSocket& ws); + bool SetWebSocket(const WebSocketBind& bind); // 初始化 SSL 配置 bool InitSSL(); // 加载 SSL 证书 @@ -82,10 +83,8 @@ namespace CTL { bool LoadSSLKey(const CTL::String &KeyPath, const CTL::String &Passwd) const; // 加载 SSL 客户端验证证书 bool LoadSSLVerify(const CTL::String& CA_Path) const; - // 运行服务器,支持 WebSocket - int Running(const WebSocket& ws,bool InitStaticFlag = true); // 运行服务器 - int Running(bool InitStaticFlag = true); + int Running(bool Ws = false,bool InitStaticFlag = true); // 停止服务器 void Stop(); // 添加静态资源路径 请填写相对路径 @@ -97,7 +96,7 @@ namespace CTL { // 设置 CORS 配置 void SetWebCORS(const CORS& cors); // 获取 WebSocket 对象 - WebSocket& GetWebSocket(); + WebSocket* GetWebSocket(); // 设置请求超时时间 void SetTimeout(unsigned long MS); // 设置接收数据头缓冲区大小 @@ -110,6 +109,7 @@ namespace CTL { void InitStatic(); // 设置最大文件上传数量 static void SetMaxConcurrentFileUploads(int Num); + void SetSourceMap(bool flag); private: // 打印消息 void MessagePrint(const CTL::String& str); @@ -142,12 +142,7 @@ namespace CTL { void ErrorHandling(CTL::Socket& client,Request& request,SSL* ssl = nullptr); String FormatRequest(const String& str); }; - // 实现 Running 成员函数,初始化 WebSocket 并设置 WebSocketFlag 标志,然后调用 Running() 启动服务器 - inline int WebServlet::Running(const WebSocket& ws,bool InitStaticFlag) { - m_WebSocket.Init(ws,this->ssl_ctx); - WebSocketFlag = true; - return Running(InitStaticFlag); - } + } #endif diff --git a/CC_SDK/Include/DataModule/NetSqlite.h b/CC_SDK/Include/DataModule/NetSqlite.h index 6f543784..8117b6e1 100644 --- a/CC_SDK/Include/DataModule/NetSqlite.h +++ b/CC_SDK/Include/DataModule/NetSqlite.h @@ -29,7 +29,6 @@ namespace CTL { //-------------------------------------------------------------------------------------------------------------- SQLite3 m_Sqlite; WebServlet m_Socket; - WebSocket m_WebSocket; CTL::Map m_Sqlite_List_User; bool Flag = false; String m_User = ""; diff --git a/CC_SDK/Include/Module/Comm/CCEpoll.h b/CC_SDK/Include/Module/Comm/CCEpoll.h index 5ec176ae..abcd7815 100644 --- a/CC_SDK/Include/Module/Comm/CCEpoll.h +++ b/CC_SDK/Include/Module/Comm/CCEpoll.h @@ -1,7 +1,7 @@ #ifndef CC_EPOLL_H_ #define CC_EPOLL_H_ #define MAX_EVENTS 1024 -#include "CCSocket.h" +#include "Socket/CCSocket.h" diff --git a/CC_SDK/Include/Module/Comm/CCNetwork.h b/CC_SDK/Include/Module/Comm/CCNetwork.h index 5b4061f6..352a0d66 100644 --- a/CC_SDK/Include/Module/Comm/CCNetwork.h +++ b/CC_SDK/Include/Module/Comm/CCNetwork.h @@ -1,7 +1,7 @@ #ifndef CC_NETWORK_H #define CC_NETWORK_H -#include "CCSocket.h" +#include "Socket/CCSocket.h" #include "CC.h" /** diff --git a/CC_SDK/Include/Module/Comm/WebRTC/CCWebRTC.h b/CC_SDK/Include/Module/Comm/WebRTC/CCWebRTC.h index bae1c0f6..01531151 100644 --- a/CC_SDK/Include/Module/Comm/WebRTC/CCWebRTC.h +++ b/CC_SDK/Include/Module/Comm/WebRTC/CCWebRTC.h @@ -1,21 +1,105 @@ #ifndef CC_WEBRTC_H #define CC_WEBRTC_H -#include "CCWCTool.h" +#include +#include +#include +#include "CCByteArray.h" +#include +#include "CCJSONObject.h" namespace CTL { + enum DataType { + Text = 0, + Binary + }; + struct RTCData { + std::string message; + ByteArray byteArray; + DataType type; + }; + struct ICECandidate { + JSON_TYPE_INTRUSIVE(ICECandidate, candidate, sdpMid, sdpMLineIndex); + std::string candidate; + std::string sdpMid; + int sdpMLineIndex; + }; class WebRTC { public: - WebRTC() = default; + // 回调函数类型定义 + using OnMessageCallback = std::function; + using OnConnectionCallback = std::function; + using OnDataChannelOpen = std::function; + using OnDataChannelClose = std::function; + using OnErrorCallback = std::function; + using LocalDescription = std::function; + using OnIceCandidateCallback = std::function; + static void Init(); + static void Release(); + WebRTC(); ~WebRTC(); - //-------------------------------------------------------------------------------------------------------------- - //-------------------------------------------------------------------------------------------------------------- + // 初始化PeerConnection + bool Initialize(); + + // 创建Offer + std::string CreateOffer(); + + // 设置远程描述 + bool SetRemoteDescription(const std::string& sdp, const std::string& type) const; + + // 设置本地描述 + bool SetLocalDescription(const std::string& sdp, const std::string& type) const; + + // 创建Answer + std::string CreateAnswer() const; + + // 添加ICE候选 + bool AddIceCandidate(const std::string& candidate, const std::string& mid) const; + + // 创建数据通道 + bool CreateDataChannel(const std::string& label); + + // 数据通道是否打开 + bool IsDataChannelOpen() const; + + // 连接状态 + bool IsConnected() const; + + // 检查是否已关闭 + bool IsClosed() const; + + // 发送消息 + bool SendText(const std::string& message) const; + bool SendBinary(void *data, int size) const; + bool SendByteArray(const ByteArray& data) const; + + void Close(); + + // 设置回调函数 + void SetOnMessageCallback(const OnMessageCallback& callback); + void SetOnDataChannelOpen(const OnDataChannelOpen& callback); + void SetOnDataChannelClose(const OnDataChannelClose& callback); + void SetOnConnectionCallback(const OnConnectionCallback& callback); + void SetOnErrorCallback(const OnErrorCallback& callback); + void SetOnIceCandidateCallback(const OnIceCandidateCallback& callback); + void SetOnLocalDescriptionCallback(const LocalDescription& callback); + private: + std::shared_ptr m_peerConnection; + std::shared_ptr m_dataChannel; + OnMessageCallback m_onMessageCallback; + OnDataChannelOpen m_onDataChannelOpen; + OnDataChannelClose m_onDataChannelClose; + OnConnectionCallback m_onConnectionCallback; + OnErrorCallback m_onErrorCallback; + OnIceCandidateCallback m_onIceCandidateCallback; + LocalDescription m_onLocalDescriptionCallback; + + void SetupPeerConnection(); + void SetupDataChannelMessage(const rtc::message_variant &data) const; }; } - - #endif diff --git a/CC_SDK/Include/Module/Comm/WebSocket/CCWebSocket.h b/CC_SDK/Include/Module/Comm/WebSocket/CCWebSocket.h index cccccf35..734cb748 100644 --- a/CC_SDK/Include/Module/Comm/WebSocket/CCWebSocket.h +++ b/CC_SDK/Include/Module/Comm/WebSocket/CCWebSocket.h @@ -12,6 +12,8 @@ #include #include #include "CCTimer.h" +#include "TL/Map.h" +#include "TL/Queue.h" // WebSocket 类格式的回调函数宏定义 #define CC_WSFunClass(Fun) [this](auto && PH1) { Fun(std::forward(PH1)); } @@ -33,6 +35,8 @@ namespace CTL{ int ID = -1; // 客户端 ID int m_count = 0; String URL_Path = "/"; + bool m_status = false; + mutable std::mutex m_mutex_id; public: /** * 获取 WebSocket 数据包 @@ -143,9 +147,9 @@ namespace CTL{ * @param ssl SSL 对象指针 * @param buffer 要发送的数据 * @param size 数据大小 - * @return 发送是否成功 + * @return 发送结果标志 */ - static bool WriteSSLResponse(SSL* ssl, const char* buffer, size_t size); + static int WriteSSLResponse(SSL* ssl, const char* buffer, size_t size); /** * 关闭与客户端或服务端的连接 @@ -165,18 +169,12 @@ namespace CTL{ void StateReset(); /** - * + * * @return 获取Ping心跳个数 */ int GetStatus() const; - /** - * - * @return 获取Ping心跳个数 - */ - int GetStatus(); - /** * 设置客户端路由 * @param path 设置路由 @@ -188,15 +186,32 @@ namespace CTL{ * @return 返回路由字符串 */ String GetURLPath(); + + /** + * 获取是否正在发送数据 + * @return 返回结果 + */ + bool GetSendStatus() const; }; /** * WebSocket 服务器类 * 用于创建和管理 WebSocket 服务器,处理客户端连接和消息 */ - class WebSocket { + using RequestFunc = std::function; + class WebSocketBind { + public: + WebSocketBind() = default; + CTL::String URL = ""; + RequestFunc OnOpenFun; + RequestFunc OnCloseFun; + RequestFunc OnMessageFun; + RequestFunc OnPingFun; + RequestFunc OnPongFun; + RequestFunc OnErrorFun; + }; + class WebSocket { + mutable std::shared_mutex m_mutex_t; public: - // 请求处理函数类型 - using RequestFunc = std::function; /** * 初始化 WebSocket 服务器 @@ -209,11 +224,16 @@ namespace CTL{ /** * 复制初始化 WebSocket 服务器 - * @param ws 要复制的 WebSocket 对象 - * @param ssl_ctx SSL 上下文 + * @param bind 绑定对象 * @return 初始化是否成功 */ - bool Init(const WebSocket& ws,SSL_CTX* ssl_ctx = nullptr); + bool Init(const WebSocketBind& bind); + + /** + * 设置 SSL + * @param ssl_ctx_t SSL_CTX 对象指针 + */ + void SetSSL(SSL_CTX* ssl_ctx_t); /** * 运行 WebSocket 服务器 @@ -245,23 +265,17 @@ namespace CTL{ void ProcessingClientRequests(CTL::Socket& client,CC_EP_EV &ev,const CTL::String& Data,SSL* ssl = nullptr); /** - * 获取所有客户端信息 - * @return 包含所有客户端信息的映射 + * 获取所有客户端ID列表 + * @return 包含所有客户端ID的列表 */ - CCMap GetClientAll(); - - /** - * 获取所有客户端信息列表 - * @return 包含所有客户端信息的列表 - */ - CCList GetClientListAll(); + CCVector GetClientListAll(); /** * 根据 ID 获取客户端信息 * @param ID 客户端 ID * @return 对应的 WebSocketInfo 对象 */ - WebSocketInfo GetClient(int ID); + WebSocketInfo* GetClient(int ID); /** * 初始化 SSL @@ -331,15 +345,7 @@ namespace CTL{ * * @return Ping心跳间隔 */ - unsigned long GetTimingTime() const { - return m_timer_count; - } - - /** - * - * @return Ping心跳间隔 - */ - unsigned long GetTimingTime() { + unsigned long GetTimingTime() const { return m_timer_count; } @@ -350,9 +356,14 @@ namespace CTL{ void SettingPing(const bool PingUp) { Tick_m = PingUp; } + + /** + * 初始化WebSocket服务 + */ + void InitService(); protected: CTL::Socket m_sock; // 服务器 Socket - Epoll m_epoll; // Epoll 对象 + Epoll m_epoll; // Epoll 对象 CC_EP_EV events[MAX_EVENTS]{}; // 事件数组 bool ServerFlag = true,Client = false,ClientOK = false,Tick_m = true; // 标志位 ThreadPool M_S_POOl{}; // 线程池 @@ -365,11 +376,11 @@ namespace CTL{ CCMap URL_Ping_Fun; // URL Ping回调函数映射 CCMap URL_Pong_Fun; // URL Pong回调函数映射 CCMap URLS; // URL 标志位映射 - CCMap Clients; // 客户端信息映射 - CCMutex m_mutex; // 共享互斥锁 + Map Clients; // 客户端信息映射 + // CCMutex m_mutex; // 共享互斥锁 SSL_CTX* ssl_ctx = nullptr; // SSL 上下文 Timer m_timer; // 定时器 - unsigned long m_timer_count = 60; + unsigned long m_timer_count = 120; private: // 接受客户端连接 void AcceptingClient(); @@ -398,19 +409,13 @@ namespace CTL{ * 添加客户端 * @param ws 要添加的 WebSocketInfo 对象 */ - void AddClient(const WebSocketInfo &ws); - - /** - * 更新客户端 - * @param ws 客户端信息 - */ - void UpClient(const WebSocketInfo &ws); + void AddClient(WebSocketInfo* ws); /** * 删除客户端 * @param ws 要删除的 WebSocketInfo 对象 */ - void DeleteClient(const WebSocketInfo &ws); + void DeleteClient(const int ID); /** * 创建新的 SSL 对象 diff --git a/CC_SDK/Include/Module/File/CCFIleInStream.h b/CC_SDK/Include/Module/File/CCFIleInStream.h index 2dcd2a3b..ed0c030d 100644 --- a/CC_SDK/Include/Module/File/CCFIleInStream.h +++ b/CC_SDK/Include/Module/File/CCFIleInStream.h @@ -3,21 +3,34 @@ #include "CC.h" using CCInStream = std::ifstream; -class CCFileInStream:public CCInStream -{ -public: - using std::ifstream::basic_ifstream; -public: - static CTL::String ReadFileDataAll(const CTL::String& filename); - static CCVector ReadBinaryFile(const CTL::String& filename); - static bool ReadData(CCFileInStream &file,CTL::String &line); - bool ReadData(CTL::ByteArray &data,size_t size = 1024); -private: +namespace CTL { + class FileInputStream final :public CCInStream{ + public: -protected: + private: + public: + using std::ifstream::basic_ifstream; + FileInputStream(); + explicit FileInputStream(const CTL::String& filename, std::ios_base::openmode mode = std::ios::in); + explicit FileInputStream(const std::FILE* file); + static CTL::String ReadFileDataAll(const CTL::String& filename); + static CCVector ReadBinaryFile(const CTL::String& filename); + static CTL::ByteArray ReadFileData(const CTL::String& filename); + static bool ReadData(FileInputStream &file,CTL::String &line); + bool ReadData(CTL::ByteArray &data,size_t size = 1024); + int read(); + int read(char* buffer, size_t size); + int read(CTL::ByteArray& buffer); + int read(CTL::ByteArray& buffer, size_t offset, size_t length); + long skip(long n); + int available(); + protected: -}; + }; +} + +typedef CTL::FileInputStream CCFileInStream; #endif diff --git a/CC_SDK/Include/Module/File/CCFile.h b/CC_SDK/Include/Module/File/CCFile.h index 4f83f4ef..4b4f2357 100644 --- a/CC_SDK/Include/Module/File/CCFile.h +++ b/CC_SDK/Include/Module/File/CCFile.h @@ -20,6 +20,7 @@ struct CCFileInfo size_t Size{}; // 文件大小 bool IsDirectory{}; // 是否为目录 time_t LastWriteTime; + CTL::String Path; }; // 命名空间别名,用于简化std::filesystem的使用 @@ -78,18 +79,22 @@ private: #endif // 将时间点转换为指定格式的字符串 static time_t to_string(const CC_FS::file_time_type& time) { -// #if __cplusplus >= 202002L // 检查是否支持C++20 -// auto sysTime = std::chrono::clock_cast(time); -// #else // 兼容C++17及以下版本 -// const auto fileTimeSinceEpoch = time.time_since_epoch(); -// auto systemClockDuration = std::chrono::duration_cast(fileTimeSinceEpoch); -// auto sysTime = std::chrono::time_point(systemClockDuration); -// #endif - const auto fileTimeSinceEpoch = time.time_since_epoch(); - auto systemClockDuration = std::chrono::duration_cast(fileTimeSinceEpoch); - auto sysTime = std::chrono::time_point(systemClockDuration); - const auto in_time_t = std::chrono::system_clock::to_time_t(sysTime); - return in_time_t; +#if __cplusplus >= 202002L // C++20及以上版本 + // C++20提供了更直接的转换方法 + auto sysTime = std::chrono::clock_cast(time); + return std::chrono::system_clock::to_time_t(sysTime); +#elif __cplusplus >= 201703L // C++17版本 + // 对于C++17,需要手动转换 + auto systemTime = std::chrono::time_point_cast( + time - CC_FS::file_time_type::clock::now() + std::chrono::system_clock::now() + ); + return std::chrono::system_clock::to_time_t(systemTime); +#else // 更早的C++版本 + // 备用方案 + auto duration = time.time_since_epoch(); + auto secs = std::chrono::duration_cast(duration); + return secs.count(); +#endif } // 删除文件,这是Delete函数的辅助函数 bool deleteFile() const; diff --git a/CC_SDK/Include/Module/File/CCFileOutStream.h b/CC_SDK/Include/Module/File/CCFileOutStream.h index 00b61ab1..a4f6fb6b 100644 --- a/CC_SDK/Include/Module/File/CCFileOutStream.h +++ b/CC_SDK/Include/Module/File/CCFileOutStream.h @@ -3,23 +3,44 @@ #include "CC.h" using CCOutStream = std::ofstream; -class CCFileOutStream:public CCOutStream -{ -private: - inline static std::mutex M_mutexs; -public: - using std::ofstream::basic_ofstream; - CCFileOutStream() = default; - CCFileOutStream(CTL::String Path,openmode mode); - static void WriteFile(const CTL::String& filename, const CTL::String& content,openmode mode = std::ios::out | std::ios::binary); - static void Append(const CTL::String& filename, const std::vector& data,openmode mode = std::ios::app | std::ios::binary); - static void Append(const CTL::String& filename, CTL::String data,openmode mode = std::ios::app | std::ios::binary); +namespace CTL { + class FileOutStream final : public CCOutStream{ + inline static std::map mutexMap; + inline static std::mutex mapMutex; // 保护 mutexMap 的互斥量 + String m_filename; // 存储文件名 + std::vector m_buffer; + public: + using std::ofstream::basic_ofstream; + FileOutStream() = default; + FileOutStream(CTL::String& Path,openmode mode); + // 构造函数 - 指定文件路径 + explicit FileOutStream(CTL::String& filename, bool append = false); + ~FileOutStream() override; + // 写入单个字节 + void write(unsigned char byte); + // 写入字节数组 + void write(const std::vector& data); + void write(const char* data, size_t size); + // 写入部分字节数组 + void write(const std::vector& data, size_t offset, size_t length); + void setBuffer(const size_t size); + //-------------------------------------------------------------------------------------------------------------- + static void WriteFile(const CTL::String& filename, const CTL::String& content,openmode mode = std::ios::out | std::ios::binary); + static void WriteFile(const CTL::String &filename, void* content, size_t size); + static void Append(const CTL::String& filename, const std::vector& data,openmode mode = std::ios::app | std::ios::binary); + static void Append(const CTL::String& filename, CTL::String data,openmode mode = std::ios::app | std::ios::binary); + static void Append(const CTL::String& filename, CTL::ByteArray& data,openmode mode = std::ios::app | std::ios::binary); + static void Append(const CTL::String& filename, void* content, size_t size); + static void WriteAt(const CTL::String& filename, size_t position, const char* data, size_t size); + //-------------------------------------------------------------------------------------------------------------- + private: + // 获取文件名 + const String& getFilename() const { return m_filename; } + }; +} -private: - -}; - +typedef CTL::FileOutStream CCFileOutStream; #endif diff --git a/CC_SDK/Include/Module/File/CCLogger.h b/CC_SDK/Include/Module/File/CCLogger.h index 9907007b..7a66bca4 100644 --- a/CC_SDK/Include/Module/File/CCLogger.h +++ b/CC_SDK/Include/Module/File/CCLogger.h @@ -1,7 +1,10 @@ #ifndef CC_LOGGER_H #define CC_LOGGER_H + #include "CC.h" #include "CCTimer.h" +#include "CCJSONObject.h" +#include "TL/Map.h" namespace CTL { /** @@ -14,8 +17,20 @@ namespace CTL { Error, Fatal }; + struct LogParentFile { + JSON_TYPE_INTRUSIVE(LogParentFile,Name,Date); + String Name = ""; + String Date = ""; + String File_Path = ""; + }; + struct LogFile_t { + JSON_TYPE_INTRUSIVE(LogFile_t,Name,Date,Size); + String Name; + size_t Size = 0; + String Date = ""; + }; class Logger { - String Root_Folder_Path = "./"; + String Root_Folder_Path = "./logs"; String m_log_file_name; String m_log_file_dir; Logger_Level m_level = Logger_Level::Debug; @@ -26,6 +41,8 @@ namespace CTL { int is_save_cond_ = 7; Timer m_log_thread; CCMutex _mutex_; + Map m_log_map; + String CurrentDate = ""; public: Logger(); ~Logger(); @@ -58,27 +75,27 @@ namespace CTL { * 日志输出 Debug等级 * @param fmt 日志内容 */ - void Debug(const char* fmt,...); + void Debug(const String& fmt); /** * 日志输出 Info等级 * @param fmt 日志内容 */ - void Info(const char* fmt,...); + void Info(const String& fmt); /** * 日志输出 Warning等级 * @param fmt 日志内容 */ - void Warning(const char* fmt,...); + void Warning(const String& fmt); /** * 日志输出 Error等级 * @param fmt 日志内容 */ - void Error(const char* fmt,...); + void Error(const String& fmt); /** * 日志输出 Fatal等级 * @param fmt 日志内容 */ - void Fatal(const char* fmt,...); + void Fatal(const String& fmt); /** * 日志输出 * @param level 日志等级 @@ -95,6 +112,73 @@ namespace CTL { * 停止日志线程 */ void Stop(); + /** + * 判断是否闰年 + * @return 是否闰年 + */ + static bool isLeapYear(int year); + /** + * 计算从公元元年到指定日期的总天数 + * @return 总天数 + */ + int dateToDays(int year, int month, int day); + /** + * 解析日期字符串为年月日 + * @param dateStr 日期字符串 2025-03-01 + * @param year 年 + * @param month 月 + * @param day 日 + */ + void parseDateString(const std::string& dateStr, int& year, int& month, int& day); + /** + * 计算两个日期之间的天数差 + * @param date1 日期1 + * @param date2 日期2 + * @return 天数差 + */ + int calculateDaysDifference(const std::string& date1, const std::string& date2); + /** + * 获取日志列表 + * @return 日志列表 + */ + CCVector GetLogs(); + /** + * 获取日志文件列表 + * @param Date 日志日期 + * @return 日志文件列表 + */ + CCVector GetLogFiles(const String& Date); + /** + * 获取当前日志文件夹 + * @return 日志文件夹 + */ + String GetCurrentFolder() const; + /** + * 获取当前日期 + * @return 当前日期 + */ + String GetCurrentDate() const; + /** + * 获取日志文件 + * @param Date 日志日期 + * @param fileName 日志文件名 + * @return 日志文件 + */ + String GetLogFile(const String& Date, const String& fileName); + /** + * 获取日志 + * @param Date 日志日期 + * @param fileName 日志文件名 + * @return 日志 + */ + String GetLog(const String& Date, const String& fileName); + /** + * 删除日志文件 + * @param Date 日志日期 + * @param fileName 日志文件名 + * @return 是否删除成功 + */ + bool DeleteLog(const String& Date, const String& fileName); private: void Log2(Logger_Level level, const String& message); bool LogWriting(const String& message); @@ -107,14 +191,15 @@ namespace CTL { bool CompareDateDifference(const String& dateStr1, const String& dateStr2, int days); String GetsTheCurrentLogFile(); void CloseWrite(); + int daysBetweenDates(const std::string& date1, const std::string& date2); }; } -#define CC_Logger_Debug(LoggerObj,m) LoggerObj.LogOutput(CTL::Logger_Level::Debug,m, __FILE__, __LINE__) -#define CC_Logger_Info(LoggerObj,m) LoggerObj.LogOutput(CTL::Logger_Level::Info,m, __FILE__, __LINE__) -#define CC_Logger_Warning(LoggerObj,m) LoggerObj.LogOutput(CTL::Logger_Level::Warning,m, __FILE__, __LINE__) -#define CC_Logger_Error(LoggerObj,m) LoggerObj.LogOutput(CTL::Logger_Level::Error,m, __FILE__, __LINE__) -#define CC_Logger_Fatal(LoggerObj,m) LoggerObj.LogOutput(CTL::Logger_Level::Fatal,m, __FILE__, __LINE__) +#define CC_Logger_Debug(LoggerObj,m,...) LoggerObj.LogOutput(CTL::Logger_Level::Debug,m, __FILE__, __LINE__) +#define CC_Logger_Info(LoggerObj,m,...) LoggerObj.LogOutput(CTL::Logger_Level::Info,m, __FILE__, __LINE__) +#define CC_Logger_Warning(LoggerObj,m,...) LoggerObj.LogOutput(CTL::Logger_Level::Warning,m, __FILE__, __LINE__) +#define CC_Logger_Error(LoggerObj,m,...) LoggerObj.LogOutput(CTL::Logger_Level::Error,m, __FILE__, __LINE__) +#define CC_Logger_Fatal(LoggerObj,m,...) LoggerObj.LogOutput(CTL::Logger_Level::Fatal,m, __FILE__, __LINE__) #endif diff --git a/CC_SDK/Include/Module/IO/CCProcess.h b/CC_SDK/Include/Module/IO/CCProcess.h index e601e42e..6cd9b625 100644 --- a/CC_SDK/Include/Module/IO/CCProcess.h +++ b/CC_SDK/Include/Module/IO/CCProcess.h @@ -1,28 +1,52 @@ -#ifndef CCPROCESS_H -#define CCPROCESS_H +#ifndef CC_PROCESS_H +#define CC_PROCESS_H #include "CC.h" +#ifdef _WIN32 +#include "windows.h" +#elif __linux__ + +#endif + #define CC_PROCESS_MAX_BUFFER_SIZE 1024 -#define Process_Read_Error "-1_-1_-" + +#ifdef _WIN32 + +#elif __linux__ + +#endif namespace CTL{ - class Process - { - private: - FILE* pipe = nullptr; - std::queue CommandQueues; +#ifdef _WIN32 + +#elif __linux__ + +#endif + class Process{ std::queue ReadBuffer; + String ExeName; + String Working; bool Flag = false; +#ifdef _WIN32 + HANDLE hReadPipe{}, hWritePipe{}; + SECURITY_ATTRIBUTES sa{}; + PROCESS_INFORMATION pi{}; +#elif __linux__ + int pipefd[2]{}; + pid_t pid{}; +#endif public: Process() = default; - Process(Process& p); - void AddCommand(const String& Command); - void Start(); + Process(const Process& p); + void Command(const String& CommandExe); + void SetWorking(const String& WorkPath); + bool Start(bool isolation = false); void Stop(); - String ReadLineBuffer(); - bool IsRunning(); + [[nodiscard]] ByteArray ReadLineBuffer() const; + [[nodiscard]] bool IsRunning() const; static void Execute(const String& Command); + static void StopProcess(String& Name); private: public: diff --git a/CC_SDK/Include/Module/IO/CCThread.h b/CC_SDK/Include/Module/IO/CCThread.h index 03aa2cfd..fb1ad02a 100644 --- a/CC_SDK/Include/Module/IO/CCThread.h +++ b/CC_SDK/Include/Module/IO/CCThread.h @@ -1,7 +1,8 @@ -#ifndef __CCThread__ -#define __CCThread__ +#ifndef CC_Thread_ +#define CC_Thread_ -#include "../../basic/CC.h" +#include "CC.h" +#include "TL/Map.h" // 禁用Visual Studio的警告信息 #pragma warning(disable : 4996) @@ -52,13 +53,13 @@ namespace CTL { std::mutex mutex_; bool interrupt_flag; }; - class Thread_V { + class Thread_Integration { public: - virtual ~Thread_V() = default; + virtual ~Thread_Integration() = default; void Start(); void Stop(); void Wait(); - bool Sign() const; + [[nodiscard]] bool Sign() const; virtual void Run() = 0; private: void running(); @@ -69,12 +70,11 @@ namespace CTL { * @class Thread * @brief 线程管理类,用于创建和控制线程 */ - class Thread - { + class Thread{ public: // 默认构造函数 - Thread() = default; - Thread(const Thread&& other); + Thread(); + Thread(const Thread&& other) noexcept ; // 移动构造函数 Thread(const Thread& other); /** @@ -114,26 +114,34 @@ namespace CTL { template bool Start(Func &&fun, Args &&...args); /** - * @brief 启动线程并执行任务,任务完成后线程自动分离 + * @brief 启动线程并执行任务,任务完成后线程 */ void Start(){ - if (task) { + if (task && !Flag) { Flag = true; - Thread_m = std::thread(task); - Thread_m.detach(); + Thread_m = new std::thread(task); + } + } + /** + * @brief 启动线程并执行任务,任务完成后线程自动分离 + */ + void StartDetach() { + if (task && !Flag) { + Flag = true; + Thread_m = new std::thread(task); + Thread_m->detach(); } } /** * @brief 启动线程并执行任务,等待任务完成 */ void RunWait() { - if (task) { + if (task && !Flag) { Flag = true; - Thread_m = std::thread(task); - Thread_m.join(); + Thread_m = new std::thread(task); + Thread_m->join(); } } - // 停止线程 void Stop(); /** * @brief 检查线程是否正在执行任务 @@ -157,17 +165,25 @@ namespace CTL { * @brief 获取线程对象的引用 * @return std::thread& 线程对象的引用 */ - std::thread& GetThread(); + [[nodiscard]] std::thread* GetThread() const; /** * @brief 获取线程的标识符 * @return std::thread::id 线程的标识符 */ [[nodiscard]] std::thread::id GetThreadId() const; + /** + * @brief 设置线程是否安全退出标志 + * @param Flag 安全退出标志 + */ + static void SetSafeExit(const bool Flag); protected: - - private: - std::thread Thread_m; // 线程对象 - std::function task; // 线程任务 + inline static std::mutex thread_mutex_t; + inline static Map CC_thread_Map_t; + inline static bool SafeExit = true; + static int AssignID(); + int threadID = -1; + std::thread* Thread_m = nullptr; // 线程对象 + std::function task{}; // 线程任务 bool Flag = false; // 线程状态标志 }; } @@ -182,6 +198,9 @@ namespace CTL { */ template CTL::Thread::Thread(Func &&fun, Args &&...args) { + std::unique_lock lock(thread_mutex_t); + this->threadID = AssignID(); + CC_thread_Map_t.put(threadID, this); SetThread(fun, args...); } @@ -197,7 +216,7 @@ CTL::Thread::Thread(Func &&fun, Args &&...args) { */ template bool CTL::Thread::SetThread(Func &&fun, Args &&...args) { - if (Thread_m.joinable()) { + if (Thread_m && Thread_m->joinable()) { return false; } task = std::bind(std::forward(fun), std::forward(args)...); @@ -216,7 +235,7 @@ bool CTL::Thread::SetThread(Func &&fun, Args &&...args) { */ template bool CTL::Thread::Start(Func &&fun, Args &&...args) { - if (Thread_m.joinable()) { + if (Thread_m && Thread_m->joinable()) { return false; } task = std::bind(std::forward(fun), std::forward(args)...); diff --git a/CC_SDK/Include/Module/IO/CCThreadPool.h b/CC_SDK/Include/Module/IO/CCThreadPool.h index d419f3f0..b9054f2a 100644 --- a/CC_SDK/Include/Module/IO/CCThreadPool.h +++ b/CC_SDK/Include/Module/IO/CCThreadPool.h @@ -15,18 +15,18 @@ namespace CTL { */ class ThreadPool { private: - size_t m_corePoolSize; // 核心线程池大小 - size_t m_maximumPoolSize; // 最大线程池大小 - int m_keepAliveTime; // 线程存活时间 - std::atomic m_isStop; // 使用 atomic 确保线程安全,表示线程池是否停止 - std::atomic m_C_threadPool; // 使用 atomic 确保线程安全,表示当前线程池中的线程数 - std::atomic T_PoolSize; // 使用 atomic 确保线程安全,表示当前线程池中的线程数 - std::atomic E_PoolSize; // 使用 atomic 确保线程安全,表示当前额外线程数 - std::atomic T_CorePoolSize; // 使用 atomic 确保线程安全,表示当前核心线程数 - std::mutex m_mutex; // 互斥锁,用于保护共享资源 - std::condition_variable m_condition; // 条件变量,用于线程间通信 - std::queue> m_taskQueue; // 任务队列,存储待执行的任务 - std::vector m_thread; // 使用标准库的 std::thread,存储线程池中的线程 + size_t m_corePoolSize{}; // 核心线程池大小 + size_t m_maximumPoolSize{}; // 最大线程池大小 + int m_keepAliveTime{}; // 线程存活时间 + std::atomic m_isStop{}; // 使用 atomic 确保线程安全,表示线程池是否停止 + std::atomic m_C_threadPool{}; // 使用 atomic 确保线程安全,表示当前线程池中的线程数 + std::atomic T_PoolSize{}; // 使用 atomic 确保线程安全,表示当前线程池中的线程数 + std::atomic E_PoolSize{}; // 使用 atomic 确保线程安全,表示当前额外线程数 + std::atomic T_CorePoolSize{}; // 使用 atomic 确保线程安全,表示当前核心线程数 + std::mutex m_mutex{}; // 互斥锁,用于保护共享资源 + std::condition_variable m_condition{}; // 条件变量,用于线程间通信 + std::queue> m_taskQueue{}; // 任务队列,存储待执行的任务 + std::vector m_thread{}; // 使用标准库的 std::thread,存储线程池中的线程 public: ThreadPool(); // 默认构造函数 @@ -37,7 +37,7 @@ namespace CTL { * @param maximumPoolSize 最大线程池大小,默认为1024 * @param keepAliveTime 线程存活时间,默认为1000毫秒 */ - explicit ThreadPool(size_t corePoolSize, size_t maximumPoolSize = 1024, int keepAliveTime = 1000) + explicit ThreadPool(const size_t corePoolSize, size_t maximumPoolSize = 1024, int keepAliveTime = 1000) : m_corePoolSize(corePoolSize), m_maximumPoolSize(maximumPoolSize), m_keepAliveTime(keepAliveTime), m_isStop(false), m_C_threadPool(0), T_PoolSize(0), E_PoolSize(0), T_CorePoolSize(0) { InitStart(corePoolSize, maximumPoolSize, keepAliveTime); @@ -64,27 +64,27 @@ namespace CTL { * 获取当前活动线程数 * @return 当前活动线程数 */ - int GetActiveThread(); + int GetActiveThread() const; /** * 获取最大线程池大小 * @return 最大线程池大小 */ - int GetMaxPoolSize(); + int GetMaxPoolSize() const; /** * 获取核心线程池大小 * @return 核心线程池大小 */ - int GetCorePoolSize(); + int GetCorePoolSize() const; /** * 获取线程存活时间 * @return 线程存活时间 */ - int GetTimeout(); + int GetTimeout() const; /** * 获取当前活动的额外线程数 * @return 当前活动的额外线程数 */ - int GetActiveExtraThread(); + int GetActiveExtraThread() const; private: /** diff --git a/CC_SDK/Include/Module/Window/CCApplication.h b/CC_SDK/Include/Module/Window/CCApplication.h index 4e1fb9a8..a08065a9 100644 --- a/CC_SDK/Include/Module/Window/CCApplication.h +++ b/CC_SDK/Include/Module/Window/CCApplication.h @@ -4,7 +4,6 @@ #include "CCThread.h" #include "CCSystem.h" - namespace CTL { struct AppParameter_t{ int argc = 0; @@ -22,12 +21,24 @@ namespace CTL { AppParameter_t GetParameter(); //-------------------------------------------------------------------------------------------------------------- static void Signal(Function&& func); + static void SetCloseFun(Function&& func); + static bool IsSingleInstance(); + static void ReleaseLock(); //-------------------------------------------------------------------------------------------------------------- private: AppParameter_t Parameter{}; void* App = nullptr; inline static CCQueue> M_SignalQueues; + inline static Function func_Close; inline static CCMutex M_Mutex; + inline static bool SingleInstance_t = false; +#ifdef _WIN32 + inline static HANDLE mutex_handle{0}; + inline static const String mutex_name = "Global\\" + CTL::System::GetAppName(); +#else + inline static int SingleInstance::lock_fd = -1; + inline static const CTL::String lock_file_path = CTL::String("/tmp/myapp.lock"); +#endif }; } diff --git a/CC_SDK/Include/Module/Window/CCSystem.h b/CC_SDK/Include/Module/Window/CCSystem.h index 62fcd23b..ef82acad 100644 --- a/CC_SDK/Include/Module/Window/CCSystem.h +++ b/CC_SDK/Include/Module/Window/CCSystem.h @@ -2,24 +2,11 @@ #define CC_SysTem_H #include "basic/CC.h" -#include "CCFile.h" #ifdef _WIN32 -#include "Windows.h" -#include -#include -#include -#include -#include + #elif __linux__ -#include -#include -#include -#include -#include -#include -#include -#include + #endif namespace CTL{ @@ -46,7 +33,8 @@ namespace CTL{ static CTL::String ApplicationDirPath(); static void Exit(int code = 0); static void Execute(const CTL::String& cmd); - static void Println(const char* fmt,...); + template + static void Println(const char* fmt, Args... args); static void Println(const CTL::String& str); static void ReleaseProcessHeap(); static unsigned int GetPhysicalCores(); @@ -67,6 +55,16 @@ namespace CTL{ static bool SetFileReadPermission(const std::string& filePath); #endif }; + + template + void System::Println(const char *fmt, Args... args) { + const std::string str = CC::format(fmt,args...); + #ifdef CC_OHOS_ + OH_LOG_Print(LOG_APP, LOG_INFO, 0x0728, "CC_SDK", "%{public}s",str.c_str()); + #else + CC::Println(str); + #endif + } } #endif diff --git a/CC_SDK/Include/TL/AutoDestruct.h b/CC_SDK/Include/TL/AutoDestruct.h index 840d6451..2c6a82e4 100644 --- a/CC_SDK/Include/TL/AutoDestruct.h +++ b/CC_SDK/Include/TL/AutoDestruct.h @@ -1,6 +1,8 @@ #ifndef SDK_TL_AUTODESTRUCT_H #define SDK_TL_AUTODESTRUCT_H +#include "iostream" + namespace CTL{ template class AutoDestruct{ @@ -11,6 +13,10 @@ namespace CTL{ m_ptr = std::move(ptr); } } + AutoDestruct(AutoDestruct&& other) noexcept { + this->m_ptr = other.m_ptr; + other.m_ptr = nullptr; + } ~AutoDestruct(){ if (m_ptr) { delete m_ptr; @@ -24,6 +30,12 @@ namespace CTL{ const T* Get() const{ return m_ptr; } + T* get(){ + return m_ptr; + } + const T* get() const{ + return m_ptr; + } explicit operator bool() const { return m_ptr != nullptr; } @@ -33,6 +45,16 @@ namespace CTL{ T* operator->() const { return m_ptr; // 假设 ptr 是内部 Term* } + AutoDestruct& operator=(T* ptr){ + delete m_ptr; + m_ptr = ptr; + return *this; + } + AutoDestruct& operator=(AutoDestruct&& rhs) noexcept { + m_ptr = rhs.m_ptr; + rhs.m_ptr = nullptr; + return *this; + } //-------------------------------------------------------------------------------------------------------------- private: T* m_ptr = nullptr; diff --git a/CC_SDK/Include/basic/CC.h b/CC_SDK/Include/basic/CC.h index 8ba9c762..90f877a6 100644 --- a/CC_SDK/Include/basic/CC.h +++ b/CC_SDK/Include/basic/CC.h @@ -47,9 +47,16 @@ #endif - +#if __OHOS__ +#pragma warning(push) +#pragma warning(disable: -Wformat-security) +// 或者对于 GCC/Clang +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-security" +#endif #define CCVar auto +#define C_Auto const auto using StdString = std::string; typedef std::exception CCException; typedef std::ostream OStream; @@ -194,6 +201,16 @@ public: %% 百分号 */ [[nodiscard]] std::string Format(const std::string& format = "%Y-%M-%d %H:%M:%S") const; + // 解析格式 "yyyy-MM-dd HH:mm:ss" + static CCTimeInfo parseTimeString(const std::string& timeStr); + // 将时间字符串解析为 time_t + static time_t parseTimeString_t(const std::string& timeStr); + // 将 time_t 转换为格式化字符串 + static std::string formatTime(time_t time); + // 计算时间加上秒数后的结果 + static std::string addSecondsToTime(const std::string& timeStr, int seconds); + // 检查当前时间是否是新的一天 + static bool IsNewDay(); // 比较时间信息 bool operator==(const CCTimeInfo& other) const; // 比较时间是否晚于指定的时间信息 @@ -202,11 +219,29 @@ public: bool operator<(const CCTimeInfo& other) const; // 比叫时间与指定时间的差值 int operator-(const CCTimeInfo& other) const; + /** + * 判断是否闰年 + * @return 是否闰年 + */ + static bool isLeapYear(int year); + /** + * 计算从公元元年到指定日期的总天数 + * @return 总天数 + */ + static int dateToDays(int year, int month, int day); + /** + * 计算两个日期之间的天数差 + * @param date1 日期1 + * @param date2 日期2 + * @return 天数差 + */ + static int calculateDaysDifference(const std::string& date1, const std::string& date2); private: // 静态函数,用于获取星期几 static int GetWeek(int week); // 存储时间信息的变量 - CCTimeInfo GetTimeInfo; + CCTimeInfo GetTimeInfo{}; + inline static std::string LastCheckedDate = ""; public: }; @@ -216,38 +251,76 @@ class CC{ public: typedef int RIos; public: - static StdString format(const char* fmt, ...) { - va_list args; - va_start(args, fmt); - // 计算格式化后字符串的长度 - va_list argsCopy; - va_copy(argsCopy, args); - const int length = std::vsnprintf(nullptr, 0, fmt, argsCopy); - va_end(argsCopy); + template + static void format_one_arg(std::string& result, T&& value) { + size_t pos = result.find("{}"); + if (pos != std::string::npos) { + std::string replacement; + if constexpr (std::is_same_v, const char*> || + std::is_same_v, char*>) { + replacement = value ? value : "null"; + } else if constexpr (std::is_arithmetic_v>) { + // 对于算术类型,明确指定类型 + if constexpr (std::is_integral_v> && !std::is_same_v, bool>) { + replacement = CC::to_String(static_cast(value)); + } else if constexpr (std::is_floating_point_v>) { + replacement = CC::to_String(static_cast(value)); + } else if constexpr (std::is_same_v, bool>) { + replacement = CC::to_String(static_cast(value)); + } + } else { + // 对于其他类型,假设对象有 to_String 方法 + replacement = CC::to_String(value); + } + result.replace(pos, 2, replacement); + } + } + static std::string format_braces_template(std::string fmt_str) { + return fmt_str; + } + template + static std::string format_braces_template(std::string fmt_str, T&& first, Rest&&... rest) { + format_one_arg(fmt_str, std::forward(first)); + if constexpr (sizeof...(rest) > 0) { + return format_braces_template(fmt_str, std::forward(rest)...); + } + return fmt_str; + } + template + static std::string format_braces_template(std::string fmt_str, T&& first) { + format_one_arg(fmt_str, std::forward(first)); + return fmt_str; + } + template + static StdString format(const char* fmt, Args... args) { + std::string fmt_str = fmt; + if (fmt_str.find("{}") != std::string::npos) { + return format_braces_template(fmt_str, args...); + } + const int length = std::snprintf(nullptr, 0, fmt, args...); + if (length <= 0) { + return fmt_str; // 格式化失败,返回原始格式字符串 + } + // 分配足够的空间来存储格式化后的字符串 - const auto buffer = new char[length + 1]; - std::vsnprintf(buffer, length + 1, fmt, args); - va_end(args); - // 创建 CCString 对象并释放缓冲区 - StdString result(buffer); - delete[] buffer; + std::string result(length, '\0'); + std::snprintf(&result[0], length + 1, fmt, args...); return result; } // 设置程序关闭时的回调函数 - template - static void SetCloseFun(T && obj,Args&&... args) { - CloseFun = std::bind(std::forward(obj), std::forward(args)...); + inline static void SetCloseFun(const std::function& obj) { + CloseFun = obj; } // 将整数转换为字符串 - static StdString to_String(int v){ + static StdString to_String(const int v){ return std::to_string(v); } // 将双精度浮点数转换为字符串 - static StdString to_String(double v){ + static StdString to_String(const double v){ return std::to_string(v); } // 将布尔值转换为字符串 - static StdString to_String(bool v){ + static StdString to_String(const bool v){ return v ? "true" : "false"; } // 将C风格字符串转换为StdString @@ -262,6 +335,21 @@ public: static StdString to_String(void* v){ return std::to_string((size_t)v); } + static StdString to_String(const CTL::Byte v){ + return std::to_string(v.get()); + } + static StdString to_String(const long v){ + return std::to_string(v); + } + static StdString to_String(const long unsigned int& v){ + return std::to_string(v); + } + static StdString to_String(const long long v){ + return std::to_string(v); + } + static StdString to_String(const long double v){ + return std::to_string(v); + } // 打印输出,不换行 template static void Print(const T& v,const char* Color = RESET){ @@ -383,9 +471,6 @@ public: signal(SIGINT, CTL::SignalHandler); // Ctrl+C signal(SIGTERM, CTL::SignalHandler); // 终止请求 #if __linux__ - -#elif _WIN32 - #endif #ifndef CC_LOGO_NO CC::CC_Print_Logo(); @@ -1006,6 +1091,12 @@ public: }; +#if __OHOS__ +#pragma warning(pop) +// 或者对于 GCC/Clang +#pragma GCC diagnostic pop +#endif + #endif inline CCAppInit_ CCAppInit; diff --git a/CC_SDK/Include/basic/CCByte.h b/CC_SDK/Include/basic/CCByte.h index 2c2ba6b1..c2366f12 100644 --- a/CC_SDK/Include/basic/CCByte.h +++ b/CC_SDK/Include/basic/CCByte.h @@ -1,5 +1,5 @@ -#ifndef CCBYTE_H -#define CCBYTE_H +#ifndef CC_BYTE_H +#define CC_BYTE_H #include #include @@ -7,178 +7,180 @@ namespace CTL { class Byte { -private: - uint8_t value; // 存储单个字节的数据 -public: - // 构造函数 - Byte(const uint8_t& val = 0) : value(val) {} - Byte(const char& c) { - value = c; - } - Byte(const int& val) { - value = val; - } - // 获取当前字节的值 - [[nodiscard]] uint8_t get() const { - return value; - } - // 设置当前字节的值 - void set(uint8_t val) { - value = val; - } - // 按位与操作 - Byte operator&(const Byte& other) const { - return Byte(value & other.value); - } - // 按位或操作 - Byte operator|(const Byte& other) const { - return Byte(value | other.value); - } - // 按位异或操作 - Byte operator^(const Byte& other) const { - return Byte(value ^ other.value); - } - // 按位取反操作 - Byte operator~() const { - return Byte(~value); - } - // 左移操作 - Byte operator<<(int n) const { - return Byte(value << n); - } - // 右移操作 - Byte operator>>(int n) const { - return Byte(value >> n); - } - bool operator==(const Byte& other) const { - return value == other.value; - } - bool operator!=(const Byte& other) const { - return value != other.value; - } - bool operator<(const Byte& other) const { - return value < other.value; - } - bool operator>(const Byte& other) const { - return value > other.value; - } - bool operator<=(const Byte& other) const { - return value <= other.value; - } - bool operator>=(const Byte& other) const { - return value >= other.value; - } - bool operator==(const int& other) const { - return value == other; - } - bool operator!=(const int& other) const { - return value != other; - } - bool operator<(const int& other) const { - return value < other; - } - bool operator>(const int& other) const { - return value > other; - } - bool operator<=(const int& other) const { - return value <= other; - } - bool operator>=(const int& other) const { - return value >= other; - } - Byte& operator=(const Byte& other) = default; - Byte& operator=(uint8_t val) { - value = val; - return *this; - } - Byte operator++() { - ++value; - return *this; - } - Byte operator++(int) { - Byte temp = *this; - ++value; - return temp; - } - Byte operator--() { - --value; - return *this; - } - Byte operator--(int) { - Byte temp = *this; - --value; - return temp; - } - Byte operator+=(const Byte& other) { - value += other.value; - return *this; - } - Byte operator-=(const Byte& other) { - value -= other.value; - return *this; - } - Byte operator*=(const Byte& other) { - value *= other.value; - return *this; - } - Byte operator/=(const Byte& other) { - value /= other.value; - return *this; - } - Byte operator%=(const Byte& other) { - value %= other.value; - return *this; - } - Byte operator<<=(int n) { - value <<= n; - return *this; - } - Byte operator>>=(int n) { - value >>= n; - return *this; - } - operator uint8_t() const { - return value; - } - operator uint8_t() { - return value; - } - operator char() const { - return value; - } - operator char() { - return value; - } - // 提供显式的转换操作符 - operator int() const { - return static_cast(value); - } - operator int() { - return static_cast(value); - } - // 输出字节的二进制表示 - friend std::ostream& operator<<(std::ostream& os, const Byte& byte) { - for (int i = 7; i >= 0; --i) { - os << ((byte.value >> i) & 1); + uint8_t value; // 存储单个字节的数据 + public: + // 构造函数 + Byte(const uint8_t& val = 0) : value(val) {} + Byte(const char& c) { + value = c; } - return os; - } - friend std::istream& operator>>(std::istream& is, Byte& byte) { - uint8_t val; - is >> val; - byte.value = val; - return is; - } - static Byte* fromCString(const char* cstr) { - size_t length = strlen(cstr); - auto* bytes = new Byte[length + 1]; - for (size_t i = 0; i < length; ++i) { - bytes[i] = cstr[i]; + Byte(const int& val) { + value = val; } - bytes[length] = '\0'; - return bytes; - } -}; + Byte(const size_t& val) { + value = val; + } + // 获取当前字节的值 + [[nodiscard]] uint8_t get() const { + return value; + } + // 设置当前字节的值 + void set(const uint8_t val) { + value = val; + } + // 按位与操作 + Byte operator&(const Byte& other) const { + return Byte(value & other.value); + } + // 按位或操作 + Byte operator|(const Byte& other) const { + return Byte(value | other.value); + } + // 按位异或操作 + Byte operator^(const Byte& other) const { + return Byte(value ^ other.value); + } + // 按位取反操作 + Byte operator~() const { + return Byte(~value); + } + // 左移操作 + Byte operator<<(int n) const { + return Byte(value << n); + } + // 右移操作 + Byte operator>>(int n) const { + return Byte(value >> n); + } + bool operator==(const Byte& other) const { + return value == other.value; + } + bool operator!=(const Byte& other) const { + return value != other.value; + } + bool operator<(const Byte& other) const { + return value < other.value; + } + bool operator>(const Byte& other) const { + return value > other.value; + } + bool operator<=(const Byte& other) const { + return value <= other.value; + } + bool operator>=(const Byte& other) const { + return value >= other.value; + } + bool operator==(const int& other) const { + return value == other; + } + bool operator!=(const int& other) const { + return value != other; + } + bool operator<(const int& other) const { + return value < other; + } + bool operator>(const int& other) const { + return value > other; + } + bool operator<=(const int& other) const { + return value <= other; + } + bool operator>=(const int& other) const { + return value >= other; + } + Byte& operator=(const Byte& other) = default; + Byte& operator=(uint8_t val) { + value = val; + return *this; + } + Byte operator++() { + ++value; + return *this; + } + Byte operator++(int) { + Byte temp = *this; + ++value; + return temp; + } + Byte operator--() { + --value; + return *this; + } + Byte operator--(int) { + Byte temp = *this; + --value; + return temp; + } + Byte operator+=(const Byte& other) { + value += other.value; + return *this; + } + Byte operator-=(const Byte& other) { + value -= other.value; + return *this; + } + Byte operator*=(const Byte& other) { + value *= other.value; + return *this; + } + Byte operator/=(const Byte& other) { + value /= other.value; + return *this; + } + Byte operator%=(const Byte& other) { + value %= other.value; + return *this; + } + Byte operator<<=(int n) { + value <<= n; + return *this; + } + Byte operator>>=(int n) { + value >>= n; + return *this; + } + operator uint8_t() const { + return value; + } + operator uint8_t() { + return value; + } + operator char() const { + return value; + } + operator char() { + return value; + } + // 提供显式的转换操作符 + operator int() const { + return static_cast(value); + } + operator int() { + return static_cast(value); + } + // 输出字节的二进制表示 + friend std::ostream& operator<<(std::ostream& os, const Byte& byte) { + for (int i = 7; i >= 0; --i) { + os << ((byte.value >> i) & 1); + } + return os; + } + friend std::istream& operator>>(std::istream& is, Byte& byte) { + uint8_t val; + is >> val; + byte.value = val; + return is; + } + static Byte* fromCString(const char* cstr) { + size_t length = strlen(cstr); + auto* bytes = new Byte[length + 1]; + for (size_t i = 0; i < length; ++i) { + bytes[i] = cstr[i]; + } + bytes[length] = '\0'; + return bytes; + } + }; } #endif diff --git a/CC_SDK/Include/basic/CCByteArray.h b/CC_SDK/Include/basic/CCByteArray.h index 438a2ea6..3d87cb0b 100644 --- a/CC_SDK/Include/basic/CCByteArray.h +++ b/CC_SDK/Include/basic/CCByteArray.h @@ -1,30 +1,33 @@ - -#ifndef CCBYTE_CCBYTEARRAY_H -#define CCBYTE_CCBYTEARRAY_H +#ifndef CC_BYTEARRAY_H +#define CC_BYTEARRAY_H #include "CCByte.h" #include "CCEncode.h" #include "CCVector.h" +#include "TL/AutoDestruct.h" -typedef long long ByteHander; +typedef size_t ByteHander; // #define HanderSize sizeof(ByteHander) namespace CTL { /** * ByteArray类用于处理字节数组,提供多种方式的字节操作和转换。 */ - class ByteArray - { - private: + class ByteArray{ std::vector bytes; public: - // 默认构造函数 ByteArray() = default; /** * 构造函数,从std::string初始化字节数组。 * @param str 用于初始化字节数组的字符串。 */ ByteArray(const std::string& str); + /** + * 构造函数,将结构体指针初始化字节数组。 + * @param str 结构体指针。 + * @param size 结构体指针大小。 + */ + ByteArray(const void* str, size_t size); /** * 构造函数,从C风格字符串初始化字节数组。 * @param str 用于初始化字节数组的C风格字符串。 @@ -55,6 +58,11 @@ namespace CTL { * @param initList 用于初始化字节数组的初始化列表。 */ ByteArray(std::initializer_list initList); + /** + * 构造函数,创建指定大小的字节数组。 + * @param size 要创建的字节数组的大小。 + */ + ByteArray(ByteHander size); /** * 添加一个字节到字节数组末尾。 * @param byte 要添加的字节。 @@ -65,7 +73,7 @@ namespace CTL { * @param index 字节的索引。 * @return 指定索引处的字节。 */ - Byte get(int index) const; + [[nodiscard]] Byte get(int index) const; /** * 设置指定索引处的字节。 * @param index 要设置字节的索引。 @@ -97,21 +105,12 @@ namespace CTL { * @param buffer 指定的缓冲区。 * @param size 缓冲区的大小。 */ - void assign(char * buffer, unsigned int size); - // /** - // * 用指定的缓冲区和大小赋值字节数组。 - // * @param buffer 指定的缓冲区。 - // * @param size 缓冲区的大小。 - // */ - // void assign(char * buffer, int size); -#ifdef __linux__ + void assign(const void* buffer, ByteHander size); /** - * 用指定的缓冲区和大小赋值字节数组。 - * @param buffer 指定的缓冲区 - * @param size 缓冲区的大小。 - */ - // void assign(char* buffer, std::ptrdiff_t size); -#endif + * 判断字节数组是否为空。 + * @return 字节数组是否为空。 + */ + [[nodiscard]] bool IsEmpty() const; /** * 在字节数组末尾追加一个字符串。 * @param str 要追加的字符串。 @@ -174,7 +173,12 @@ namespace CTL { * 获取字节数组的底层vector。 * @return 字节数组的底层vector。 */ - std::vector data(); + std::vector toVector(); + /** + * 获取字节数组的底层vector。 + * @return 字节数组的底层vector。 + */ + std::vector toVector() const; /** * 获取字节数组的缓冲区。 * @return 字节数组的缓冲区。 @@ -185,6 +189,11 @@ namespace CTL { * @return 字节数组的缓冲区。 */ [[nodiscard]] const char* buffer() const; + /** + * 获取字节数组的缓冲区。 + * @return 新创建的字节数组的缓冲区(需要手动管理内存) + */ + char* newBuffer() const; /** * 调整字节数组的大小。 * @param len 新的大小。 @@ -227,6 +236,122 @@ namespace CTL { * @param other 要移除的另一个字节数组。 */ void operator -= (const ByteArray& other); + /** + * 索引运算符重载,用于获取字节数组中的指定索引处的字节。 + * @param index 要获取的字节索引。 + * @return 指定索引处的字节。 + */ + Byte& operator [] (int index); + /** + * 索引运算符重载,用于获取字节数组中的指定索引处的字节。 + * @param index 要获取的字节索引。 + * @return 指定索引处的字节。 + */ + Byte operator [] (int index) const; + /** + * 将字节数组转换为指定类型的指针。 + * @param other 要转换的字节数组 + * @return 返回指向字节数组的指定类型的指针(需要手动管理内存) + */ + template + static T* Conversion(const ByteArray& other) { + const T* t_const = reinterpret_cast(other.newBuffer()); + T* t = const_cast(t_const); + return t; + } + /** + * 将字节数组转换为指定类型的指针。 + * @return 指向字节数组的指定类型的指针(RAII管理内存) + */ + template + AutoDestruct Conversion() { + const T* t_const = reinterpret_cast(this->newBuffer()); + T* t = const_cast(t_const); + return CTL::AutoDestruct(t); + } + /** + * 将字节数组转换为指定类型的指针。 + * @param str 要转换的字节数组 + * @param size 字节数组的长度 + * @return 返回指向字节数组的指定类型的指针(RAII管理内存) + */ + template + void Conversion(T* str, const ByteHander size) { + const auto c_str = reinterpret_cast(str); + bytes.assign(c_str, c_str + size); + } + /** + * 获取字节数组的子数组。 + * @param start 子数组的起始索引。 + * @param end 子数组的结束索引。 + * @return 返回子数组。 + */ + [[nodiscard]] ByteArray subBuffer(ByteHander start, ByteHander end) const; + /** + * 将字节数组转换为Base64字符串。 + * @return Base64字符串。 + */ + std::string toBase64(); + /** + * 将Base64字符串转换为字节数组。 + * @param base64Str Base64字符串。 + * @return 转换后的字节数组。 + */ + static ByteArray fromBase64(const std::string& base64Str); + /** + * 将指定值填充到数组的某个范围 + * @param value 要填充的值 + * @param start 起始索引 + * @param end 结束索引(不包含) + */ + void fill(Byte value, size_t start = 0, size_t end = -1); + /** + * 复制数组的一部分到另一个ByteArray + * @param dest 目标ByteArray + * @param srcStart 源起始索引 + * @param destStart 目标起始索引 + * @param count 复制的元素数量 + */ + void copyTo(ByteArray& dest, size_t srcStart = 0, size_t destStart = 0, size_t count = -1) const; + /** + * 克隆当前ByteArray + * @return 新的ByteArray副本 + */ + ByteArray clone() const; + /** + * 查找特定字节第一次出现的位置 + * @param value 要查找的字节 + * @param start 起始搜索位置 + * @return 找到的位置,未找到返回-1 + */ + int indexOf(Byte value, size_t start = 0) const; + /** + * 查找特定字节最后一次出现的位置 + * @param value 要查找的字节 + * @param start 起始搜索位置 + * @return 找到的位置,未找到返回-1 + */ + int lastIndexOf(Byte value, size_t start = -1) const; + /** + * 查找字节序列第一次出现的位置 + * @param pattern 要查找的字节序列 + * @param start 起始搜索位置 + * @return 找到的位置,未找到返回-1 + */ + int indexOf(const ByteArray& pattern, size_t start = 0) const; + /** + * 查找字节序列最后一次出现的位置 + * @param pattern 要查找的字节序列 + * @param start 起始搜索位置 + * @return 找到的位置,未找到返回-1 + */ + int lastIndexOf(const ByteArray& pattern, size_t start = -1) const; + /** + * 比较两个ByteArray是否相等 + * @param other 要比较的另一个ByteArray + * @return 如果相等返回true,否则返回false + */ + bool equals(const ByteArray& other) const; }; /** diff --git a/CC_SDK/Include/basic/CCEncode.h b/CC_SDK/Include/basic/CCEncode.h index 5decfb17..53079227 100644 --- a/CC_SDK/Include/basic/CCEncode.h +++ b/CC_SDK/Include/basic/CCEncode.h @@ -136,6 +136,9 @@ namespace CTL{ // 格式化字符串,从源编码转换为目标编码 static std::string Format(const std::string& str,const std::string &from,const std::string &to); + // 格式化字符串,从源编码转换为目标编码 + static std::string formatString(const std::string& str,StandardCharsets from,StandardCharsets to); + // 格式化字符串,从源编码转换为目标编码,并以字符向量形式返回结果 static std::vector Format(const std::string& str,StandardCharsets from,StandardCharsets to); diff --git a/CC_SDK/Include/basic/CCObject.h b/CC_SDK/Include/basic/CCObject.h index 85e27633..e9784c98 100644 --- a/CC_SDK/Include/basic/CCObject.h +++ b/CC_SDK/Include/basic/CCObject.h @@ -2,32 +2,33 @@ #define CC_OBJECT_H #pragma once -#include "CC.h" -#include // 用于 std::hash -#include // 用于 std::string -#include // 用于 std::addressof +#include +#include +#include +#include +#include "map" +#include "mutex" namespace CTL { class Object { + inline static std::mutex Mutex_Object; + std::string MemoryID; + public: + + private: + public: virtual ~Object() = default; // 虚析构函数确保正确析构 // 比较两个对象是否逻辑相等(默认实现为地址比较) - virtual bool equals(const Object* other) const { - return this == other; // 默认比较内存地址 - } + virtual bool equals(const Object* other); // 生成基于对象地址的哈希值 - [[nodiscard]] virtual size_t hashCode() const noexcept { - return std::hash{}(this); - } + [[nodiscard]] virtual size_t hashCode() const noexcept; // 返回对象的字符串表示(默认格式:类名@地址) - [[nodiscard]] virtual std::string toString() const { - char buffer[64]; - snprintf(buffer, sizeof(buffer), "Object@%p", static_cast(this)); - return buffer; - } - friend std::ostream& operator<<(std::ostream& os, const Object& map) { - os << map.toString(); - return os; + [[nodiscard]] virtual std::string toString() const; + friend std::ostream& operator<<(std::ostream& os, const Object& map); + template + static std::shared_ptr create(Args&&... args) { + return std::make_shared(std::forward(args)...); } }; } diff --git a/CC_SDK/Include/basic/CCString.h b/CC_SDK/Include/basic/CCString.h index 0e2f4671..f070f4cd 100644 --- a/CC_SDK/Include/basic/CCString.h +++ b/CC_SDK/Include/basic/CCString.h @@ -9,25 +9,71 @@ #include #include #include + #ifdef __linux__ #include #endif -class CCWString; +#if __OHOS__ +#pragma warning(push) +#pragma warning(disable: -Wformat-security) +// 或者对于 GCC/Clang +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-security" +#endif using CCStream = std::ostringstream; using CCSStream = std::stringstream; using WString = std::wstring; namespace CTL { + class CCWString; + /** * @brief 字符串类,继承自std::string,提供额外的功能 */ - class String : public std::string - { + class String : public std::string{ + template + static void format_one_arg(std::string& result, T&& value) { + size_t pos = result.find("{}"); + if (pos != std::string::npos) { + std::string replacement; + if constexpr (std::is_same_v, const char*> || + std::is_same_v, char*>) { + replacement = value ? value : "null"; + } + else if constexpr (std::is_arithmetic_v>) { + replacement = std::to_string(value); + } + else { + replacement = std::to_string(value); // 假设对象有 to_string 方法 + } + result.replace(pos, 2, replacement); + } + } + static std::string format_braces_template(std::string fmt_str) { + return fmt_str; + } + template + static std::string format_braces_template(std::string fmt_str, T&& first, Rest&&... rest) { + format_one_arg(fmt_str, std::forward(first)); + if constexpr (sizeof...(rest) > 0) { + return format_braces_template(fmt_str, std::forward(rest)...); + } + return fmt_str; + } + template + static std::string format_braces_template(std::string fmt_str, T&& first) { + format_one_arg(fmt_str, std::forward(first)); + return fmt_str; + } public: // 默认构造函数 String() = default; - explicit String(const char *fmt, ...); + template + String(const char* fmt, Args... args) { + const auto str = format(fmt,args...); + this->assign(str); + } String(const std::initializer_list list){ for (auto& i : list) { this->append(i); @@ -57,10 +103,25 @@ namespace CTL { /** * @brief 格式化字符串的静态方法 * @param fmt 格式化字符串的格式 - * @param ... 可变参数,与格式化字符串匹配 + * @param args 可变参数,与格式化字符串匹配 * @return 返回格式化后的String对象 */ - static String format(const char* fmt, ...); + template + static std::string format(const char* fmt, Args... args) { + std::string fmt_str = fmt; + if (fmt_str.find("{}") != std::string::npos) { + return format_braces_template(fmt_str, args...); + } + const int length = std::snprintf(nullptr, 0, fmt, args...); + if (length <= 0) { + return fmt_str; // 格式化失败,返回原始格式字符串 + } + + // 分配足够的空间来存储格式化后的字符串 + std::string result(length, '\0'); + std::snprintf(&result[0], length + 1, fmt, args...); + return result; + } // 转换String对象为WString对象 [[nodiscard]] WString to_CCWString() const { #ifdef _WIN32 @@ -168,4 +229,10 @@ struct std::hash { } }; +#if __OHOS__ +#pragma warning(pop) +// 或者对于 GCC/Clang +#pragma GCC diagnostic pop +#endif + #endif diff --git a/CC_SDK/Include/basic/ConcurrentLinkedList.h b/CC_SDK/Include/basic/ConcurrentLinkedList.h index ce7d5d63..576a1b78 100644 --- a/CC_SDK/Include/basic/ConcurrentLinkedList.h +++ b/CC_SDK/Include/basic/ConcurrentLinkedList.h @@ -207,6 +207,6 @@ namespace CTL { return os; } }; -} // namespace CTL +} -#endif // CONCURRENTLINKEDLIST_H +#endif diff --git a/CC_SDK/Include/basic/StreamHandler.h b/CC_SDK/Include/basic/StreamHandler.h index 24497c6f..c5faa053 100644 --- a/CC_SDK/Include/basic/StreamHandler.h +++ b/CC_SDK/Include/basic/StreamHandler.h @@ -6,7 +6,7 @@ #include #ifdef __OHOS__ -#define CC_OHOS_ +#define CC_OHOS_ 1 #include "hilog/log.h" #undef LOG_DOMAIN #undef LOG_TAG diff --git a/CC_SDK/Install.sh b/CC_SDK/Install.sh index 1d2f0fff..9542cad4 100644 --- a/CC_SDK/Install.sh +++ b/CC_SDK/Install.sh @@ -19,3 +19,4 @@ sudo apt-get install libmotif-dev sudo apt install libappindicator3-dev sudo apt install libayatana-appindicator3-dev sudo apt install libzip-dev +sudo apt-get install libasound2-dev diff --git a/CC_SDK/src/CCServlet/CCRequest.cpp b/CC_SDK/src/CCServlet/CCRequest.cpp index 1410fdab..4dcea381 100644 --- a/CC_SDK/src/CCServlet/CCRequest.cpp +++ b/CC_SDK/src/CCServlet/CCRequest.cpp @@ -584,7 +584,7 @@ CTL::String CTL::Request::GetFileInfo(const CTL::String& key) { return URL_Decode(RequestData.FileHeaders[key]); } -CTL::JSONObject CTL::Request::GetJson() { +CTL::JSONObject CTL::Request::GetJson() const { const CTL::String str = RequestData.Body; return CTL::JSONObject::parse(str); } @@ -624,117 +624,97 @@ bool Request::GetMediaFiles(const ReceiveFileCallback& callback) { if (!callback) { return false; } - while (IsRun.load() >= MAX_UPLOAD_FILE_CONCURRENT) { - CTL::Thread::SleepMS(20); - } - ++IsRun; Client.SetSocketNonBlocking(); - CTL::String str = "\r\n" + RequestData.FileHeaders["Boundary"] + "--\r\n"; - auto strlength = str.length(); - auto S = RequestData.Headers["Content-Length"]; - if(S.empty()){ - S = RequestData.Headers["content-length"]; - } - long long Maxlength = std::stoll(S); - if (IsFileUploadSize) { - if (Maxlength > 10 * 1024 * 1024) { // >10MB - File_Buffer_Max = 16384; // 16KB - } - else { - File_Buffer_Max = 4096; // 4KB + CTL::String str = "\r\n" + RequestData.FileHeaders["Boundary"] + "--\r\n"; + auto S = RequestData.Headers["Content-Length"]; + if(S.empty()){ + S = RequestData.Headers["content-length"]; + } + long long Maxlength = std::stoll(S); + size_t Length = 0; + CCVector data; + char buffer[File_Buffer_Max] = {0}; + int F = 0; + if (!this->RequestData.Buffer.empty()) { + data = this->RequestData.Buffer; + } + int Timeout = 0; + if(ssl) { + while (true) { + const auto l = SSL_read(ssl, buffer, File_Buffer_Max); + if(l > 0 && F == 0){ + Timeout = 0; + Length += l; + // 更高效地添加数据到vector + data.insert(data.end(), buffer, buffer + l); + Maxlength = Maxlength - l; + + if(Maxlength < File_Buffer_Max * 2){ + CTL::String DB(data.data(), data.size()); + auto len = DB.find(str); + if(len != std::string::npos){ + // 使用更高效的构造方式 + data.resize(len); + F = 1; + } + } + + bool CF = callback(data, data.size()); + if (!CF) { + return false; + } + data.clear(); + } + else { + if (Timeout >= 1000) { + break; + } + Timeout++; + CTL::Thread::SleepMS(1); + } } } - CCVector data; - int F = 0; - if(ssl) { - while (true) { - std::vector buffer; - buffer.resize(File_Buffer_Max); - auto l = SSL_read(ssl, buffer.data(), File_Buffer_Max); - int err = SSL_get_error(ssl, l); - if(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { - continue; // 可重试 - } - if(l > 0 && F == 0){ - if(l != File_Buffer_Max){ - for (int i = 0; i < l; ++i) { - data.push_back(buffer[i]); - } - } - else { - for (auto i : buffer) { - data.push_back(i); - } - } - Maxlength = Maxlength - data.size(); - if(Maxlength < File_Buffer_Max * 2){ - CTL::String DB = CTL::String(data.begin(),data.end()); - auto len = DB.find(str); - if(len != std::string::npos){ - data = CCVector(data.begin(),data.begin() + len); - F = 1; - } - } - bool CF = callback(data,data.size()); - if (!CF) { - return false; - } - data.clear(); - } - else { - if (Maxlength <= 1024) { - std::cerr << "GetMediaFiles Connection interruption" << std::endl; - return false; - } - break; - } - } - } else { - data = RequestData.Buffer; while (true){ if(Client.isDataAvailable()){ - std::vector buffer; - buffer.resize(File_Buffer_Max); - auto l = Client.RecvData(buffer.data(), File_Buffer_Max); + auto l = Client.RecvData(buffer, File_Buffer_Max); if(l > 0 && F == 0){ - if(l != File_Buffer_Max){ - for (int i = 0; i < l; ++i) { - data.push_back(buffer[i]); - } - } - else { - for (auto i : buffer) { - data.push_back(i); - } - } - Maxlength = Maxlength - data.size(); + Timeout = 0; + // 更高效地添加数据到vector + data.insert(data.end(), buffer, buffer + l); + Maxlength = Maxlength - l; + if(Maxlength < File_Buffer_Max * 2){ - CTL::String DB = CTL::String(data.begin(),data.end()); + CTL::String DB(data.data(), data.size()); auto len = DB.find(str); if(len != std::string::npos){ - data = CCVector(data.begin(),data.begin() + len); + // 使用更高效的构造方式 + data.resize(len); F = 1; } } - bool CF = callback(data,data.size()); + + bool CF = callback(data, data.size()); if (!CF) { return false; } data.clear(); } else { - std::cerr << "GetMediaFiles Connection interruption" << std::endl; - return false; + break; } } else { - break; + // 超时或无数据可读 + if (Timeout >= 1000) { + break; + } + Timeout++; + CTL::Thread::SleepMS(1); } } } - --IsRun; - return true; + return F == 1; } void CTL::Request::Init(CTL::Socket& socket,CORS* cors,SSL* ssl) { @@ -870,7 +850,7 @@ void Request::SetMaxConcurrentFileUploads(int Num) { void Request::SetFileUploadSize(int Size) { IsFileUploadSize = false; - File_Buffer_Max = Size; + // File_Buffer_Max = Size; } void Request::FileWriting(const CTL::String &path, const CCVector &buffer, size_t size) { diff --git a/CC_SDK/src/CCServlet/CCResponse.cpp b/CC_SDK/src/CCServlet/CCResponse.cpp index b3cac68c..03de9f01 100644 --- a/CC_SDK/src/CCServlet/CCResponse.cpp +++ b/CC_SDK/src/CCServlet/CCResponse.cpp @@ -74,28 +74,64 @@ void CTL::Response::SendHeader(const int Status, const CTL::String& HeaderFlag) SendData(header.data(),header.length()); } -bool CTL::Response::WriteSSLResponse(SSL* ssl, const char* buffer, const size_t size) { +int CTL::Response::WriteSSLResponse(SSL* ssl, const char* buffer, const size_t size) { if (ssl == nullptr) { - return false; + return -1; // 错误ssl } -#if __linux__ +#if __linux__ + // 在Linux系统中,防止SSL_write触发SIGPIPE信号 + // 该设置已在InitSSL中通过sigaction处理,此处作为额外保障 + signal(SIGPIPE, SIG_IGN); #endif - if (const int result = SSL_write(ssl, buffer, size); result <= 0) { - switch (int err = SSL_get_error(ssl, result)) { - case SSL_ERROR_ZERO_RETURN: - // 对方已关闭连接 - return false; - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - // 非阻塞操作,稍后重试 - return false; - default: - // 其他错误 - return false; + + const int result = SSL_write(ssl, buffer, static_cast(size)); + if (result <= 0) { + const int err = SSL_get_error(ssl, result); + switch (err) { + case SSL_ERROR_ZERO_RETURN: { + // 对方已关闭连接,这是正常情况 + return 0; + } + case SSL_ERROR_WANT_READ: { + // 非阻塞操作,需要等待可读事件 + return -5; + } + case SSL_ERROR_WANT_WRITE: { + // 非阻塞操作,需要等待可写事件 + return -5; + } + case SSL_ERROR_SYSCALL: { + // 系统调用错误,可能包括SIGPIPE + if (ERR_peek_error() == 0) { + // 如果没有SSL错误,检查系统错误 + if (errno == EPIPE || errno == ECONNRESET) { + // 连接已断开或管道破裂 + return -4; + } + } + // 其他系统错误 + return -3; + } + case SSL_ERROR_SSL: { + // SSL协议错误 + ERR_print_errors_fp(stderr); + return -2; + } + default: { + // 其他SSL错误 + return 99; + } } } - return true; + + // 检查写入字节数是否匹配期望值 + if (static_cast(result) != size) { + // 写入不完整,可能需要重试或处理错误 + return 98; + } + + return 1; } void CTL::Response::ResponseRouting() { @@ -190,7 +226,19 @@ bool CTL::Response::Write(const CTL::String& Data) { bool CTL::Response::SendData(const char* buffer, const size_t size) { bool F = false; if (ssl) { - F = WriteSSLResponse(ssl, buffer, size); + m_status = true; + const int ret = WriteSSLResponse(this->ssl, buffer, size); + if (ret == 1) { + m_status = false; + F = true; + } + else { + if (ret == 0 || ret == -4 || ret == -2 || ret == -3 || ret == 99) { + this->Socket.Close(); + } + m_status = false; + F = false; + } } else { while (!CTL::Socket::IsSocketWritable(Socket.Socketbit)) { diff --git a/CC_SDK/src/CCServlet/CCSQLite3.cpp b/CC_SDK/src/CCServlet/CCSQLite3.cpp index c9bd93ff..92648b65 100644 --- a/CC_SDK/src/CCServlet/CCSQLite3.cpp +++ b/CC_SDK/src/CCServlet/CCSQLite3.cpp @@ -135,6 +135,8 @@ CCResultSet SQLite3::SqlQuery(CTL::String sql) { } bool SQLite3::Close(){ + M_Thread.Stop(); + this->Blockage = false; if (!RemoteLink) { return sqlite3_close(SQL) != 0; } diff --git a/CC_SDK/src/CCServlet/CCWebServlet.cpp b/CC_SDK/src/CCServlet/CCWebServlet.cpp index bb774594..32053b42 100644 --- a/CC_SDK/src/CCServlet/CCWebServlet.cpp +++ b/CC_SDK/src/CCServlet/CCWebServlet.cpp @@ -47,9 +47,9 @@ bool WebServlet::Init(const String &address, const int Port, const bool ChokeUp) return F; } -bool CTL::WebServlet::SetWebSocket(const WebSocket& ws) { +bool CTL::WebServlet::SetWebSocket(const WebSocketBind& bind) { WebSocketFlag = true; - return m_WebSocket.Init(ws,ssl_ctx); + return m_WebSocket.Init(bind); } bool CTL::WebServlet::InitSSL() { @@ -121,7 +121,8 @@ bool CTL::WebServlet::LoadSSLVerify(const CTL::String &CA_Path) const { return true; } -int CTL::WebServlet::Running(bool InitStaticFlag) { +int CTL::WebServlet::Running(bool Ws,bool InitStaticFlag) { + ServerFlag = true; if (InitStaticFlag) { InitStatic(); } @@ -138,6 +139,11 @@ int CTL::WebServlet::Running(bool InitStaticFlag) { return -1; } M_S_POOl.InitStart(M_Pool_Size, M_Pool_Max, M_Pool_KeepAliveTime); + if (Ws && WebSocketFlag) { + m_WebSocket.SetSSL(this->ssl_ctx); + m_WebSocket.SettingPing(true); + m_WebSocket.InitService(); + } while (ServerFlag) { const int _fds = ep.Epoll_Wait(events,MAX_EVENTS,10); if (_fds == -1) { @@ -152,6 +158,7 @@ int CTL::WebServlet::Running(bool InitStaticFlag) { } } } + ep.Close(); return 0; } @@ -182,8 +189,8 @@ void CTL::WebServlet::SetWebCORS(const CORS& cors) { CORS_Header = new CORS(cors); } -CTL::WebSocket& CTL::WebServlet::GetWebSocket() { - return m_WebSocket; +CTL::WebSocket* CTL::WebServlet::GetWebSocket() { + return &m_WebSocket; } void WebServlet::SetTimeout(const unsigned long MS) { @@ -233,6 +240,7 @@ bool CTL::WebServlet::Permission(CTL::Socket& client) const { void CTL::WebServlet::AcceptingClient() { CTL::Socket client = server.Accept(); if (client.Socketbit == SockError) { + MessagePrint("Accept failed: " + CTL::String(strerror(errno))); return; } // client.SetSocketNonBlocking(); @@ -253,11 +261,11 @@ void CTL::WebServlet::ProcessingClientRequests(CTL::Socket& client,CC_EP_EV &ev) } CTL::String Data = GetRequest(client,ssl); if(Data.empty()) { - client.Close(); - ep.Epoll_CTL(client.Socketbit, &ev,CTL_DEL); if (ssl) { SSL_shutdown(ssl); } + client.Close(); + ep.Epoll_CTL(client.Socketbit, &ev,CTL_DEL); return; } Request request; @@ -286,6 +294,8 @@ void CTL::WebServlet::ProcessingClientRequests(CTL::Socket& client,CC_EP_EV &ev) ep.Epoll_CTL(client.Socketbit, &ev,CTL_DEL); if (ssl) { SSL_shutdown(ssl); + SSL_free(ssl); + ssl = nullptr; } } @@ -365,7 +375,7 @@ CTL::String CTL::WebServlet::GetRequest(CTL::Socket& client,SSL* ssl) { } } else{ - this->MessagePrint("HandleRequest -> Abnormal disconnect"); + // this->MessagePrint("HandleRequest -> Abnormal disconnect"); return ""; } } @@ -395,7 +405,7 @@ void CTL::WebServlet::HandleRequest(CTL::Socket& client, Request& request,SSL* s else { String Path = ProcessPath(request.RequestData.Path); Path = CCFile::NormalizePath(Path); - if(hasMapSuffix(Path)){ + if(hasMapSuffix(Path) && !source_map_){ Path = removeMapSuffix(Path); } const CCVar Data = StaticResources[Path]; @@ -479,7 +489,7 @@ void CTL::WebServlet::DirInitStatic(const CTL::String &Path) { } } catch (CCException& exception) { - MessagePrint(" DirInitStatic -> " + file.GetPath() + " -> " + CTL::String(exception.what())); + // MessagePrint(" DirInitStatic -> " + file.GetPath() + " -> " + CTL::String(exception.what())); } } } @@ -508,22 +518,19 @@ CTL::String CTL::WebServlet::GetApp_Form_Data(CTL::Socket& socket, Request& HTTP } CTL::String data; const auto len = st.to_int(); + CCVar* Buffer = new char[len + 1]; if (!ssl) { while (true) { if(socket.isDataAvailable()) { - CCVar* Buffer = new char[len + 1]; - memset(Buffer, 0, len); CCVar length = socket.RecvData(Buffer, len); Buffer[len] = '\0'; if(length > 0) { data.assign(Buffer, length); - delete[] Buffer; if(data.find("\r\n\r\n") != CTL::String::npos) { break; } } else { - delete[] Buffer; break; } } @@ -534,17 +541,15 @@ CTL::String CTL::WebServlet::GetApp_Form_Data(CTL::Socket& socket, Request& HTTP } else { while (true) { - CCVar* Buffer = new char[len + 1]; - memset(Buffer, 0, len); const auto length = SSL_read(ssl, Buffer, len); Buffer[len] = '\0'; if(length > 0) { data.assign(Buffer, length); } - delete[] Buffer; break; } } + delete[] Buffer; return data; } @@ -609,21 +614,21 @@ SSL * CTL::WebServlet::NewSSL(const CTL::Socket& client) const { } SSL_set_accept_state(ssl); SSL_set_fd(ssl, client.Socketbit); - // 完成 SSL 握手 - if (const int ret = SSL_accept(ssl); ret <= 0) { - SSL_free(ssl); - return nullptr; + int ret; + int retryTimes = 0; + while ((ret = SSL_accept(ssl)) <= 0 && retryTimes++ < 50) { + const int err = SSL_get_error(ssl, ret); + if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { + // 等待 100ms 后重试 + CTL::Thread::Sleep(100); + continue; + } + else { + SSL_free(ssl); + return nullptr; + } } - // int code; - // int retryTimes = 0; - // while ((code = SSL_accept(ssl)) <= 0 && retryTimes++ < 100) { - // if (SSL_get_error(ssl, code) != SSL_ERROR_WANT_READ) { - // // printf("ssl accept error. %d\n", SSL_get_error(ssl, code)); - // break; - // } - // CCThread::Sleep(1000 * 100); - // } - return ssl; + return (ret > 0) ? ssl : nullptr; } void WebServlet::ErrorHandling(CTL::Socket &client, Request& request, SSL *ssl) { @@ -647,6 +652,8 @@ String WebServlet::FormatRequest(const String &str) { return result; } - +void WebServlet::SetSourceMap(bool flag){ + this->source_map_ = flag; +} diff --git a/CC_SDK/src/DataModule/NetSqlite.cpp b/CC_SDK/src/DataModule/NetSqlite.cpp index a9b3211e..4f73149f 100644 --- a/CC_SDK/src/DataModule/NetSqlite.cpp +++ b/CC_SDK/src/DataModule/NetSqlite.cpp @@ -40,11 +40,16 @@ void CTL::NetSqlite::Close() { void CTL::NetSqlite::Running() { this->Flag = true; - this->m_WebSocket.OnBind("/SQLITE",CC_WSFunClass(OnOpen),CC_WSFunClass(OnClose), - CC_WSFunClass(OnMessage),CC_WSFunClass(OnError)); + WebSocketBind bind; + bind.URL = "/SQLITE"; + bind.OnOpenFun = CC_WSFunClass(OnOpen); + bind.OnCloseFun = CC_WSFunClass(OnClose); + bind.OnMessageFun = CC_WSFunClass(OnMessage); + bind.OnErrorFun = CC_WSFunClass(OnError); + m_Socket.SetWebSocket(bind); while (this->Flag) { Thread::Sleep(1000 * 500); - m_Socket.Running(this->m_WebSocket); + m_Socket.Running(true); } } diff --git a/CC_SDK/src/Module/Comm/WebSocket/CCWebSocket.cpp b/CC_SDK/src/Module/Comm/WebSocket/CCWebSocket.cpp index 155837eb..0ce03629 100644 --- a/CC_SDK/src/Module/Comm/WebSocket/CCWebSocket.cpp +++ b/CC_SDK/src/Module/Comm/WebSocket/CCWebSocket.cpp @@ -51,28 +51,67 @@ int CTL::WebSocketInfo::GetID() const { return ID; } -bool CTL::WebSocketInfo::WriteSSLResponse(SSL* ssl, const char* buffer, const size_t size) { +int CTL::WebSocketInfo::WriteSSLResponse(SSL* ssl, const char* buffer, const size_t size) { if (ssl == nullptr) { - return false; + return -1; // 错误ssl } -#if __linux__ +#if __linux__ + // 在Linux系统中,防止SSL_write触发SIGPIPE信号 + // 该设置已在InitSSL中通过sigaction处理,此处作为额外保障 + // struct sigaction sa; + // sa.sa_handler = SIG_IGN; + // sigaction(SIGPIPE, &sa, nullptr); + signal(SIGPIPE, SIG_IGN); #endif - if (const int result = SSL_write(ssl, buffer, size); result <= 0) { - switch (int err = SSL_get_error(ssl, result)) { - case SSL_ERROR_ZERO_RETURN: - // 对方已关闭连接 - return false; - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - // 非阻塞操作,稍后重试 - return false; - default: - // 其他错误 - return false; + + const int result = SSL_write(ssl, buffer, static_cast(size)); + if (result <= 0) { + const int err = SSL_get_error(ssl, result); + switch (err) { + case SSL_ERROR_ZERO_RETURN: { + // 对方已关闭连接,这是正常情况 + return 0; + } + case SSL_ERROR_WANT_READ: { + // 非阻塞操作,需要等待可读事件 + return -5; + } + case SSL_ERROR_WANT_WRITE: { + // 非阻塞操作,需要等待可写事件 + return -5; + } + case SSL_ERROR_SYSCALL: { + // 系统调用错误,可能包括SIGPIPE + if (ERR_peek_error() == 0) { + // 如果没有SSL错误,检查系统错误 + if (errno == EPIPE || errno == ECONNRESET) { + // 连接已断开或管道破裂 + return -4; + } + } + // 其他系统错误 + return -3; + } + case SSL_ERROR_SSL: { + // SSL协议错误 + ERR_print_errors_fp(stderr); + return -2; + } + default: { + // 其他SSL错误 + return 99; + } } } - return true; + + // 检查写入字节数是否匹配期望值 + if (static_cast(result) != size) { + // 写入不完整,可能需要重试或处理错误 + return 98; + } + + return 1; } bool WebSocketClient::Send_Handshake(const String &ip_, const int port_,const String& Path, const String &ssh) const { @@ -215,17 +254,16 @@ bool CTL::WebSocket::Init(const CTL::String& ip, const int port, const bool Chok return F; } -bool CTL::WebSocket::Init(const WebSocket& ws,SSL_CTX* ssl_ctx) { - this->URLOpenFun = ws.URLOpenFun; - this->URLCloseFun = ws.URLCloseFun; - this->URLMessageFun = ws.URLMessageFun; - this->URL_ERROR_Fun = ws.URL_ERROR_Fun; - this->URLS = ws.URLS; - this->ssl_ctx = ssl_ctx; - this->Clients = ws.Clients; +bool CTL::WebSocket::Init(const WebSocketBind& bind) { + this->OnBind(bind.URL, bind.OnOpenFun, bind.OnCloseFun, bind.OnMessageFun, + bind.OnErrorFun, bind.OnPingFun, bind.OnPongFun); return true; } +void WebSocket::SetSSL(SSL_CTX *ssl_ctx_t) { + this->ssl_ctx = ssl_ctx_t; +} + bool WebSocketClient::Connect(const CTL::String &ip, const int port,const String& URL) { Client = true; ServerFlag = true; @@ -388,9 +426,7 @@ int CTL::WebSocket::Running() { return -1; } M_S_POOl.InitStart(M_Pool_Size, M_Pool_Max, M_Pool_KeepAliveTime); - if (Tick_m) { - m_timer.Start([&](){Tick();}, m_timer_count, TimeType::Second); - } + InitService(); while (ServerFlag) { const int _fds = m_epoll.Epoll_Wait(events,MAX_EVENTS,10); if (_fds == -1) { @@ -428,8 +464,22 @@ void WebSocketClient::OnBind(const RequestFunc &OnOpenFun, const RequestFunc &On } bool CTL::WebSocketInfo::Write(const char* data, const size_t size) { + std::lock_guard lock(m_mutex_id); if (this->ssl) { - return WriteSSLResponse(this->ssl,data,size); + m_status = true; + const int ret = WriteSSLResponse(this->ssl, data, size); + if (ret == 1) { + m_status = false; + return true; + } + else { + if (ret == 0 || ret == -4 || ret == -2 || ret == -3 || ret == 99) { + auto sock = this->GetSock(); + sock.Close(); + } + m_status = false; + return false; + } } else { return this->m_sock.Send(data, size, MSL_N); @@ -530,10 +580,6 @@ int WebSocketInfo::GetStatus() const { return m_count; } -int WebSocketInfo::GetStatus() { - return m_count; -} - void WebSocketInfo::SetURLPath(const String& path) { URL_Path = path; } @@ -542,6 +588,10 @@ String WebSocketInfo::GetURLPath() { return URL_Path; } +bool WebSocketInfo::GetSendStatus() const { + return m_status; +} + void CTL::WebSocket::AcceptingClient() { CTL::Socket client = m_sock.Accept(); if (client.GetClientHost().Port == 0) { @@ -561,17 +611,20 @@ void CTL::WebSocket::AcceptingClient() { } void CTL::WebSocket::ProcessingClientRequests(CTL::Socket& client, CC_EP_EV& ev,const CTL::String& Data,SSL* ssl) { + // int value = 1; + // setsockopt(client.Socketbit, SOL_SOCKET, MSL_N, &value, sizeof(value)); ByteBuffer buffer; - buffer.append(Data.data(),Data.size()); + buffer.append(Data.data(),static_cast(Data.size())); WebSocketPacket m_packet; - WebSocketInfo info; - info.ssl = ssl; + auto info = new WebSocketInfo(); + info->ssl = ssl; const CCVar l = m_packet.recv_handshake(buffer); + CTL::String URL = ""; try { if (l == 0) { - CTL::String URL = m_packet.uri(); + URL = m_packet.uri(); CTL::String mod = m_packet.mothod(); - info.SetSock(client); + info->SetSock(client); if (CCVar BURL = URLS[URL]; !BURL) { client.Close(); m_epoll.Epoll_CTL(client.Socketbit, &ev,CTL_DEL); @@ -579,23 +632,23 @@ void CTL::WebSocket::ProcessingClientRequests(CTL::Socket& client, CC_EP_EV& ev, } CTL::String AnswerBack = URLS[URL] ? "OK" : "NO URL"; if (const CCVar Answer = m_packet.pack_handshake_rsp(AnswerBack); Answer == 0) { - info.Write(AnswerBack.data(),AnswerBack.size()); - info.SetConnectFlag(true); + info->Write(AnswerBack.data(),AnswerBack.size()); } else { client.Close(); m_epoll.Epoll_CTL(client.Socketbit, &ev,CTL_DEL); return; } - info.SetID(AllocationID()); - info.StatusUpdate(); + int ID = AllocationID(); + info->SetID(ID); + info->StatusUpdate(); + info->SetURLPath(URL); AddClient(info); - info.SetURLPath(URL); if (CCVar OpenFun = URLOpenFun[URL]) { if (OpenFun) { try { - info.SetPacket(m_packet); - OpenFun(info); + info->SetPacket(m_packet); + OpenFun(*info); } catch (CCException& exception) { MessagePrint(exception.what()); @@ -610,25 +663,15 @@ void CTL::WebSocket::ProcessingClientRequests(CTL::Socket& client, CC_EP_EV& ev, buffer.clear(); m_packet.payload_.clear(); while (true) { - if (client.isDataAvailable()) { + if (client.isDataAvailable() && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) { char buf[1024] = {0}; if (const CCVar length = ReadBuffer(ssl,client,buf,sizeof buf); length > 0) { - buffer.append(buf,length); + buffer.append(buf,static_cast(length)); if (uint64_t frameSize = m_packet.recv_dataframe(buffer); frameSize > 0) { // 成功接收到一个完整的帧 if (uint8_t opcode = m_packet.get_opcode(); opcode == WebSocketPacket::WSOpcode_Close) { - if (CCVar CloseFun = URLCloseFun[URL]) { - if (CloseFun) { - try { - info.SetPacket(m_packet); - CloseFun(info); - } - catch (CCException& exception) { - MessagePrint(exception.what()); - } - } - } - if (info.GetConnectFlag()) { +#ifdef _WIN32 + if (info->GetConnectFlag()) { // 构建关闭帧 char closeFrame[2 + 125]; // 最大关闭帧大小为125字节 closeFrame[0] = 0b10001000; // FIN=1, Opcode=0x8 @@ -636,18 +679,32 @@ void CTL::WebSocket::ProcessingClientRequests(CTL::Socket& client, CC_EP_EV& ev, closeFrame[2] = 0x03; // 状态码高字节,1000表示正常关闭 closeFrame[3] = 0xE8; // 状态码低字节 // 发送关闭帧 - info.Write(closeFrame, 4); + info->Write(closeFrame, 4); + } +#endif + + if (CCVar CloseFun = URLCloseFun[URL]) { + if (CloseFun) { + try { + info->SetPacket(m_packet); + info->SetConnectFlag(false); + CloseFun(*info); + } + catch (CCException& exception) { + MessagePrint(exception.what()); + } + } } break; } else if (opcode == WebSocketPacket::WSOpcode_Binary || opcode == WebSocketPacket::WSOpcode_Text) { if (CCVar MessageFun = URLMessageFun[URL]) { try { - info.SetPacket(m_packet); + info->SetPacket(m_packet); // 获取payload数据 ByteBuffer payload = m_packet.get_payload(); - info.SetBuffer(payload); - MessageFun(info); + info->SetBuffer(payload); + MessageFun(*info); } catch (CCException& exception) { MessagePrint(exception.what()); @@ -657,8 +714,8 @@ void CTL::WebSocket::ProcessingClientRequests(CTL::Socket& client, CC_EP_EV& ev, else if (opcode == WebSocketPacket::WSOpcode_Ping) { if (CCVar PingFun = URL_Ping_Fun[URL]) { try { - info.SetPacket(m_packet); - PingFun(info); + info->SetPacket(m_packet); + PingFun(*info); } catch (CCException& exception) { MessagePrint(exception.what()); @@ -666,13 +723,14 @@ void CTL::WebSocket::ProcessingClientRequests(CTL::Socket& client, CC_EP_EV& ev, } } else if (opcode == WebSocketPacket::WSOpcode_Pong) { - auto i = Clients.get(info.GetID()); - i.StatusUpdate(); - UpClient(i); + auto i = GetClient(ID); + if (i) { + i->StatusUpdate(); + } if (CCVar PongFun = URL_Pong_Fun[URL]) { try { - info.SetPacket(m_packet); - PongFun(info); + info->SetPacket(m_packet); + PongFun(*info); } catch (CCException& exception) { MessagePrint(exception.what()); @@ -687,8 +745,9 @@ void CTL::WebSocket::ProcessingClientRequests(CTL::Socket& client, CC_EP_EV& ev, if (CCVar ERFun = URL_ERROR_Fun[URL]) { try { if (ERFun) { - info.SetPacket(m_packet); - ERFun(info); + info->SetPacket(m_packet); + info->SetConnectFlag(false); + ERFun(*info); } } catch (CCException& e) { @@ -704,32 +763,58 @@ void CTL::WebSocket::ProcessingClientRequests(CTL::Socket& client, CC_EP_EV& ev, } } else { - MessagePrint("recv_handshake error"); - } + MessagePrint("recv_handshake error"); + } } catch (CCException& exception) { - MessagePrint("recv_handshake -> " + CTL::String(exception.what())); + if (CCVar ERFun = URL_ERROR_Fun[URL]) { + try { + if (ERFun) { + info->SetPacket(m_packet); + info->SetConnectFlag(false); + ERFun(*info); + } + } + catch (CCException& e) { + MessagePrint("ERFun -> " + CTL::String(e.what())); + } + } + else { + MessagePrint("recv_handshake -> " + CTL::String(exception.what())); + } } client.Close(); m_epoll.Epoll_CTL(client.Socketbit, &ev,CTL_DEL); - DeleteClient(info); + if (ssl) { + while (info->GetSendStatus()) { + CTL::Thread::SleepMS(10); + } + SSL_shutdown(ssl); + SSL_free(ssl); + ssl = nullptr; + } + if (info) { + DeleteClient(info->GetID()); + } } -CCMap CTL::WebSocket::GetClientAll() { - return Clients; -} - -CCList CTL::WebSocket::GetClientListAll() { - CCUniqueLock lock(m_mutex); - CCList list; +CCVector CTL::WebSocket::GetClientListAll() { + std::shared_lock lock(m_mutex_t); + CCList list; for (auto& [key,value] : Clients) { - list.push_back(value); + list.push_back(key); } return list; } -CTL::WebSocketInfo CTL::WebSocket::GetClient(const int ID) { - return Clients[ID]; +CTL::WebSocketInfo* CTL::WebSocket::GetClient(const int ID) { + std::shared_lock lock(m_mutex_t); + const auto item = Clients.get(ID); + if (item && *item) { + const auto info = *item; + return info; + } + return nullptr; } bool CTL::WebSocket::InitSSL() { @@ -867,19 +952,19 @@ void CTL::WebSocket::MessagePrint(const CTL::String& str) { } int CTL::WebSocket::AllocationID() { - CCUniqueLock lock(m_mutex); + std::shared_lock lock(m_mutex_t); for (int i = 0; i < 100000; i++) { - if (Clients[i].GetID() == -1) { + if (!Clients.IsContains(i)) { return i; } } return -1; } -void CTL::WebSocket::AddClient(const WebSocketInfo& ws) { - m_mutex.lock(); - Clients[ws.GetID()] = ws; - m_mutex.unlock(); +void CTL::WebSocket::AddClient(WebSocketInfo* ws) { + std::unique_lock lock(m_mutex_t); + ws->SetConnectFlag(true); + Clients.put(ws->GetID(),ws); } SSL* CTL::WebSocket::NewSSL(const CTL::Socket& client) const { @@ -907,11 +992,15 @@ SSL* CTL::WebSocket::NewSSL(const CTL::Socket& client) const { return ssl; } -void CTL::WebSocket::DeleteClient(const WebSocketInfo& ws) { - m_mutex.lock(); - Clients[ws.GetID()].SetID(-1); - Clients.erase(ws.GetID()); - m_mutex.unlock(); +void CTL::WebSocket::DeleteClient(const int ID) { + std::unique_lock lock(m_mutex_t); + const auto item = Clients.get(ID); + if (item && *item) { + auto info = *item; + info->SetConnectFlag(false); + Clients.Remove(ID); + info = nullptr; + } } ByteHander CTL::WebSocket::ReadBuffer(SSL* ssl,CTL::Socket& client,char* buf, ByteHander size) { @@ -925,6 +1014,12 @@ ByteHander CTL::WebSocket::ReadBuffer(SSL* ssl,CTL::Socket& client,char* buf, By return read; } +void WebSocket::InitService() { + if (Tick_m) { + m_timer.Start([&](){Tick();}, m_timer_count, TimeType::Second); + } +} + void WebSocket::Stop() { m_timer.Stop(); m_sock.Close(); @@ -1043,27 +1138,21 @@ bool WebSocketInfo::SendPong(const ByteArray& binaryData) { } void WebSocket::Tick() { - if (CCVar list = Clients.values(); !list.empty()) { - for (auto& i : list) { - if (const auto count = i.GetStatus(); count == 0) { - DeleteClient(i); - i.CloseConnection(); + const auto List = Clients.values(); + for (const auto& i : List) { + if (i) { + if (const auto count = i->GetStatus(); count == 0) { + i->CloseConnection(); + DeleteClient(i->GetID()); + } + else { + i->SendPing(""); + i->StateReset(); } - } - list = Clients.values(); - for (auto& i : list) { - i.SendPing(""); - i.StateReset(); } } } -void WebSocket::UpClient(const WebSocketInfo& ws) { - m_mutex.lock(); - Clients[ws.GetID()] = ws; - m_mutex.unlock(); -} - diff --git a/CC_SDK/src/Module/Comm/WebSocket/ws_packet.cpp b/CC_SDK/src/Module/Comm/WebSocket/ws_packet.cpp index af6bcb25..e3eb8faa 100644 --- a/CC_SDK/src/Module/Comm/WebSocket/ws_packet.cpp +++ b/CC_SDK/src/Module/Comm/WebSocket/ws_packet.cpp @@ -57,10 +57,11 @@ int32_t WebSocketPacket::recv_handshake(ByteBuffer &input) input.resetoft(); return 0; } - - if (get_param("Upgrade") != "websocket" || get_param("Connection") != "Upgrade" || - get_param("Sec-WebSocket-Version") != "13" || get_param("Sec-WebSocket-Key") == "") - { + const bool A = get_param("Upgrade") != "websocket"; + const bool B = get_param("Connection").find("Upgrade") == std::string::npos; + const bool C = get_param("Sec-WebSocket-Version") != "13"; + const bool D = get_param("Sec-WebSocket-Key").empty(); + if (A || B || C || D){ input.resetoft(); return WS_ERROR_INVALID_HANDSHAKE_PARAMS; } diff --git a/CC_SDK/src/Module/File/CCFIleInStream.cpp b/CC_SDK/src/Module/File/CCFIleInStream.cpp index 73c1190a..134f2ebb 100644 --- a/CC_SDK/src/Module/File/CCFIleInStream.cpp +++ b/CC_SDK/src/Module/File/CCFIleInStream.cpp @@ -1,6 +1,24 @@ #include "CCFIleInStream.h" + using namespace CTL; -CTL::String CCFileInStream::ReadFileDataAll(const CTL::String &filename) { + +FileInputStream::FileInputStream() : CCInStream() { + +} + +FileInputStream::FileInputStream(const CTL::String &filename, std::ios_base::openmode mode) : CCInStream(filename, mode) { + +} + +FileInputStream::FileInputStream(const std::FILE *file) { + if (file) { + auto fb = std::make_unique(); + fb->open(reinterpret_cast(file), std::ios_base::in); + std::istream::rdbuf(fb.release()); + } +} + +CTL::String FileInputStream::ReadFileDataAll(const CTL::String &filename) { CCInStream inputFile(filename); if (!inputFile.is_open()) { std::cerr << "无法打开文件: " << filename << std::endl; @@ -12,7 +30,7 @@ CTL::String CCFileInStream::ReadFileDataAll(const CTL::String &filename) { return fileContent; } -CCVector CCFileInStream::ReadBinaryFile(const CTL::String &filename) { +CCVector FileInputStream::ReadBinaryFile(const CTL::String &filename) { std::ifstream file(filename, std::ios::binary | std::ios::ate); if (!file.is_open()) { throw std::runtime_error("无法打开文件"); @@ -31,19 +49,40 @@ CCVector CCFileInStream::ReadBinaryFile(const CTL::String &filename) { return buffer; } -bool CCFileInStream::ReadData(CCFileInStream &file, CTL::String &line) { +CTL::ByteArray FileInputStream::ReadFileData(const CTL::String &filename) { + std::ifstream file(filename, std::ios::binary | std::ios::ate); + if (!file.is_open()) { + throw std::runtime_error("无法打开文件"); + } + // 获取文件大小 + std::streamsize size = file.tellg(); + file.seekg(0, std::ios::beg); + // 分配缓冲区 + std::vector buffer(size); + CTL::ByteArray buffer_t; + // 读取文件内容 + if (!file.read(reinterpret_cast(buffer.data()), size)) { + throw std::runtime_error("读取文件失败"); + } + // 关闭文件 + file.close(); + buffer_t.assign(buffer.data(),size); + return buffer_t; +} + +bool FileInputStream::ReadData(FileInputStream &file, CTL::String &line) { const bool ret = std::getline(file, line) ? true : false; return ret; } -bool CCFileInStream::ReadData(ByteArray &data, const size_t size) { +bool FileInputStream::ReadData(ByteArray &data, const size_t size) { if (!this->is_open()) { throw std::runtime_error("无法打开文件"); } bool A = false; // const std::unique_ptr buffer(new char[size]); auto* buffer = new char[size]; - this->read(buffer, size); + std::ifstream::read(buffer, size); if (const std::streamsize bytesRead = this->gcount(); bytesRead > 0) { data.clear(); data.assign(buffer, static_cast(bytesRead)); @@ -52,3 +91,88 @@ bool CCFileInStream::ReadData(ByteArray &data, const size_t size) { } return A; } + +int FileInputStream::read() { + if (!this->is_open()) { + throw std::runtime_error("Stream is closed"); + } + + char byte; + this->get(byte); + if (this->good()) { + return static_cast(static_cast(byte)); + } + return -1; // EOF +} + +int FileInputStream::read(char *buffer, const size_t size) { + if (!this->is_open()) { + throw std::runtime_error("Stream is closed"); + } + if (!buffer || size == 0) { + throw std::runtime_error("buffer is null"); + } + // 保存当前位置(用于计算实际读取的字节数) + std::streampos startPos = this->tellg(); + std::ifstream::read(buffer, static_cast(size)); + const std::streamsize bytesRead = this->gcount(); + if (bytesRead == 0 && this->eof()) { + return -1; // EOF + } + return static_cast(bytesRead); +} + +int FileInputStream::read(CTL::ByteArray &buffer) { + return read(buffer, 0, buffer.size()); +} + +int FileInputStream::read(CTL::ByteArray &buffer, const size_t offset, const size_t length) { + if (!this->is_open()) { + throw std::runtime_error("Stream is closed"); + } + + if (offset + length > buffer.size()) { + throw std::out_of_range("Buffer overflow"); + } + + // 保存当前位置(用于计算实际读取的字节数) + std::streampos startPos = this->tellg(); + + std::ifstream::read(buffer.buffer() + offset, static_cast(length)); + const std::streamsize bytesRead = this->gcount(); + if (bytesRead == 0 && this->eof()) { + return -1; // EOF + } + return static_cast(bytesRead); +} + +long FileInputStream::skip(const long n) { + if (!this->is_open()) { + throw std::runtime_error("Stream is closed"); + } + + const std::streampos currentPos = this->tellg(); + this->seekg(n, std::ios_base::cur); + + // 检查是否跳到了文件末尾之后 + if (this->fail()) { + this->clear(); + this->seekg(0, std::ios_base::end); + const std::streampos endPos = this->tellg(); + return static_cast(endPos - currentPos); + } + + const std::streampos newPos = this->tellg(); + return static_cast(newPos - currentPos); +} + +int FileInputStream::available() { + if (!this->is_open()) { + throw std::runtime_error("Stream is closed"); + } + const std::streampos currentPos = this->tellg(); + this->seekg(0, std::ios_base::end); + const std::streampos endPos = this->tellg(); + this->seekg(currentPos); + return static_cast(endPos - currentPos); +} diff --git a/CC_SDK/src/Module/File/CCFile.cpp b/CC_SDK/src/Module/File/CCFile.cpp index 82603eeb..dd1fd64e 100644 --- a/CC_SDK/src/Module/File/CCFile.cpp +++ b/CC_SDK/src/Module/File/CCFile.cpp @@ -174,7 +174,9 @@ CCVector CCFile::GetDirectoryContents(const CTL::String &directoryPa fileInfo.Size = CC_FS::file_size(entry); } // 获取创建时间和最后修改时间 - fileInfo.LastWriteTime = to_string(entry.last_write_time()); + const auto t = entry.last_write_time(); + fileInfo.LastWriteTime = to_string(t); + fileInfo.Path = entry.path().generic_string(); fileInfos.push_back(fileInfo); } } diff --git a/CC_SDK/src/Module/File/CCFileOutStream.cpp b/CC_SDK/src/Module/File/CCFileOutStream.cpp index ca452dfe..ff6cfcc1 100644 --- a/CC_SDK/src/Module/File/CCFileOutStream.cpp +++ b/CC_SDK/src/Module/File/CCFileOutStream.cpp @@ -1,6 +1,17 @@ #include "CCFileOutStream.h" + +#include "CCFile.h" + using namespace CTL; -void CCFileOutStream::WriteFile(const CTL::String &filename, const CTL::String &content,openmode mode) { + +void FileOutStream::WriteFile(const CTL::String &filename, const CTL::String &content,openmode mode) { + // 获取对应文件的互斥量 + std::unique_lock mapLock(mapMutex); + auto& fileMutex = mutexMap[filename]; + mapLock.unlock(); + + std::lock_guard fileLock(fileMutex); + // 使用ofstream对象打开或创建文件 std::ofstream file(filename,mode); // 检查文件是否成功打开 @@ -14,25 +25,32 @@ void CCFileOutStream::WriteFile(const CTL::String &filename, const CTL::String & file.close(); } -void CCFileOutStream::Append(const CTL::String &filename, const std::vector& data,openmode mode) { +void FileOutStream::WriteFile(const CTL::String &filename, void* content, const size_t size) { + // 获取对应文件的互斥量 + std::unique_lock mapLock(mapMutex); + auto& fileMutex = mutexMap[filename]; + mapLock.unlock(); + + std::lock_guard fileLock(fileMutex); + + std::ofstream file(filename,std::ios::out | std::ios::binary); + if (!file.is_open()) { + std::cerr << "无法打开文件: " << filename << std::endl; + return; + } + file.write(static_cast(content), size); + file.close(); +} + +void FileOutStream::Append(const CTL::String &filename, const std::vector& data,openmode mode) { + // 获取对应文件的互斥量 + std::unique_lock mapLock(mapMutex); + auto& fileMutex = mutexMap[filename]; + mapLock.unlock(); + + std::lock_guard fileLock(fileMutex); + // 使用ofstream对象打开或创建文件,并设置为追加模式 - M_mutexs.lock(); - std::ofstream file(filename, mode); - // 检查文件是否成功打开 - if (!file.is_open()) { - M_mutexs.unlock(); - std::cerr << "无法打开文件: " << filename << std::endl; - return; - } - // 写入数据到文件 - file.write(data.data(), data.size()); - // 关闭文件 - file.close(); - M_mutexs.unlock(); -} - -void CCFileOutStream::Append(const CTL::String &filename, CTL::String data, std::ios_base::openmode mode) { -// 使用ofstream对象打开或创建文件,并设置为追加模式 std::ofstream file(filename, mode); // 检查文件是否成功打开 if (!file.is_open()) { @@ -45,6 +63,202 @@ void CCFileOutStream::Append(const CTL::String &filename, CTL::String data, std: file.close(); } -CCFileOutStream::CCFileOutStream(CTL::String Path, std::ios_base::openmode mode) { - open(Path,mode); +void FileOutStream::Append(const CTL::String &filename, CTL::String data, std::ios_base::openmode mode) { + // 获取对应文件的互斥量 + std::unique_lock mapLock(mapMutex); + auto& fileMutex = mutexMap[filename]; + mapLock.unlock(); + + std::lock_guard fileLock(fileMutex); + + // 使用ofstream对象打开或创建文件,并设置为追加模式 + std::ofstream file(filename, mode); + // 检查文件是否成功打开 + if (!file.is_open()) { + std::cerr << "无法打开文件: " << filename << std::endl; + return; + } + // 写入数据到文件 + file.write(data.data(), data.size()); + // 关闭文件 + file.close(); } + +void FileOutStream::Append(const CTL::String &filename, CTL::ByteArray &data, openmode mode) { + // 获取对应文件的互斥量 + std::unique_lock mapLock(mapMutex); + auto& fileMutex = mutexMap[filename]; + mapLock.unlock(); + + std::lock_guard fileLock(fileMutex); + + std::ofstream file(filename, mode); + // 检查文件是否成功打开 + if (!file.is_open()) { + std::cerr << "无法打开文件: " << filename << std::endl; + return; + } + // 写入数据到文件 + file.write(data.buffer(), data.size()); + // 关闭文件 + file.close(); +} + +void FileOutStream::Append(const CTL::String &filename, void *content, const size_t size) { + // 获取对应文件的互斥量 + std::unique_lock mapLock(mapMutex); + auto& fileMutex = mutexMap[filename]; + mapLock.unlock(); + + std::lock_guard fileLock(fileMutex); + + std::ofstream file(filename, std::ios::app | std::ios::binary); + // 检查文件是否成功打开 + if (!file.is_open()) { + std::cerr << "无法打开文件: " << filename << std::endl; + return; + } + // 写入数据到文件 + file.write(static_cast(content), size); + // 关闭文件 + file.close(); +} + +void FileOutStream::WriteAt(const CTL::String &filename, const size_t position, const char *data, const size_t size) { + // 获取对应文件的互斥量 + std::unique_lock mapLock(mapMutex); + auto& fileMutex = mutexMap[filename]; + mapLock.unlock(); + + std::lock_guard fileLock(fileMutex); + + std::fstream file(filename, std::ios::in | std::ios::out | std::ios::binary); + + // 检查文件是否成功打开 + if (!file.is_open()) { + std::cerr << "无法打开文件进行随机访问写入: " << filename << std::endl; + return; + } + + // 定位到指定位置 + file.seekp(position, std::ios::beg); + + // 检查定位是否成功 + if (file.fail()) { + std::cerr << "无法定位到文件位置: " << position << " in " << filename << std::endl; + file.close(); + return; + } + + // 在指定位置写入数据 + file.write(data, size); + + // 检查写入是否成功 + if (file.fail()) { + std::cerr << "写入文件失败: " << filename << std::endl; + file.close(); + return; + } + + // 关闭文件 + file.close(); +} + +FileOutStream::FileOutStream(CTL::String& Path, std::ios_base::openmode mode): m_filename(Path) { + if (Path.find(".") == 0) { + Path = CCFile::NormalizePath(Path); + } + // 如果文件不存在且模式包含追加或输出,则尝试创建 + if (!std::ifstream(Path).good() && (mode & (std::ios::app | std::ios::out))) { + std::ofstream tmp(Path, std::ios::out); + tmp.close(); + } + open(Path, mode); // 调用基类打开 + setBuffer(4096); +} + +FileOutStream::FileOutStream(CTL::String &filename, bool append): m_filename(filename) { + if (filename.find(".") == 0) { + filename = CCFile::NormalizePath(filename); + } + std::ios_base::openmode mode = std::ios::binary; + if (append) { + mode |= std::ios::app; + mode |= std::ios::out; + } + else { + mode |= std::ios::out; + } + open(filename, mode); + setBuffer(4096); +} + +FileOutStream::~FileOutStream() { + if (is_open()) { + this->close(); + } +} + +void FileOutStream::write(const unsigned char byte) { + if (!is_open()) { + throw std::runtime_error("Stream is not open"); + } + + // 获取当前文件的互斥量 + std::unique_lock mapLock(mapMutex); + auto& fileMutex = mutexMap[m_filename]; + mapLock.unlock(); + + std::lock_guard fileLock(fileMutex); + put(byte); +} + +void FileOutStream::write(const std::vector &data) { + if (!is_open()) { + throw std::runtime_error("Stream is not open"); + } + + // 获取当前文件的互斥量 + std::unique_lock mapLock(mapMutex); + auto& fileMutex = mutexMap[m_filename]; + mapLock.unlock(); + + std::lock_guard fileLock(fileMutex); + std::ostream::write(reinterpret_cast(data.data()), data.size()); +} + +void FileOutStream::write(const char *data, size_t size) { + if (!is_open()) { + throw std::runtime_error("Stream is not open"); + } + + // 获取当前文件的互斥量 + std::unique_lock mapLock(mapMutex); + auto& fileMutex = mutexMap[m_filename]; + mapLock.unlock(); + + std::lock_guard fileLock(fileMutex); + std::ostream::write(data, size); +} + +void FileOutStream::write(const std::vector &data, size_t offset, size_t length) { + if (!is_open()) { + throw std::runtime_error("Stream is not open"); + } + + // 获取当前文件的互斥量 + std::unique_lock mapLock(mapMutex); + auto& fileMutex = mutexMap[m_filename]; + mapLock.unlock(); + + std::lock_guard fileLock(fileMutex); + std::ostream::write(reinterpret_cast(data.data() + offset), length); +} + +void FileOutStream::setBuffer(const size_t size) { + if (size > 0) { + m_buffer.resize(size); + rdbuf()->pubsetbuf(m_buffer.data(), size); + } +} + diff --git a/CC_SDK/src/Module/File/CCLogger.cpp b/CC_SDK/src/Module/File/CCLogger.cpp index 741cc077..38901ff4 100644 --- a/CC_SDK/src/Module/File/CCLogger.cpp +++ b/CC_SDK/src/Module/File/CCLogger.cpp @@ -1,8 +1,10 @@ #include "CCLogger.h" - #include - #include "CCFile.h" +#include "CCFIleInStream.h" +#include "CCSystem.h" + +int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; CTL::Logger::Logger() { log_flag = true; @@ -34,29 +36,24 @@ void CTL::Logger::SetLevel(const Logger_Level level) { m_level = level; } -void CTL::Logger::Debug(const char* fmt,...) { - const String message = String::format(fmt); - Log2(Logger_Level::Debug, message); +void CTL::Logger::Debug(const String& fmt) { + Log2(Logger_Level::Debug, fmt); } -void CTL::Logger::Info(const char* fmt,...) { - const String message = String::format(fmt); - Log2(Logger_Level::Info, message); +void CTL::Logger::Info(const String& fmt) { + Log2(Logger_Level::Info, fmt); } -void CTL::Logger::Warning(const char* fmt,...) { - const String message = String::format(fmt); - Log2(Logger_Level::Warning, message); +void CTL::Logger::Warning(const String& fmt) { + Log2(Logger_Level::Warning, fmt); } -void CTL::Logger::Error(const char* fmt,...) { - const String message = String::format(fmt); - Log2(Logger_Level::Error, message); +void CTL::Logger::Error(const String& fmt) { + Log2(Logger_Level::Error, fmt); } -void CTL::Logger::Fatal(const char* fmt,...) { - const String message = String::format(fmt); - Log2(Logger_Level::Fatal, message); +void CTL::Logger::Fatal(const String& fmt) { + Log2(Logger_Level::Fatal, fmt); } void CTL::Logger::LogOutput(const Logger_Level level, const String& message, const String& file, const int line) { @@ -98,10 +95,8 @@ void CTL::Logger::Start() { break; } } - m_log_thread.Start([&]() - { - // LogThread(); - }, 12,TimeType::Hour); + auto func = [this] { LogThread(); }; + m_log_thread.Start(func, 12,TimeType::Hour); } void CTL::Logger::Stop() { @@ -109,6 +104,138 @@ void CTL::Logger::Stop() { CloseWrite(); } +bool CTL::Logger::isLeapYear(const int year) { + return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); +} + +int CTL::Logger::dateToDays(int year, int month, int day) { + int days = 0; + // 加上整年的天数 + for (int y = 1; y < year; ++y) { + days += isLeapYear(y) ? 366 : 365; + } + // 加上当年前面月份的天数 + for (int m = 1; m < month; ++m) { + days += daysInMonth[m - 1]; + if (m == 2 && isLeapYear(year)) { + days += 1; // 闰年2月多一天 + } + } + // 加上当月的天数 + days += day; + return days; +} + +void CTL::Logger::parseDateString(const std::string &dateStr, int &year, int &month, int &day) { + sscanf(dateStr.c_str(), "%d-%d-%d", &year, &month, &day); +} + +int CTL::Logger::calculateDaysDifference(const std::string &date1, const std::string &date2) { + int year1, month1, day1; + int year2, month2, day2; + + parseDateString(date1, year1, month1, day1); + parseDateString(date2, year2, month2, day2); + + int days1 = dateToDays(year1, month1, day1); + int days2 = dateToDays(year2, month2, day2); + + return days2 - days1; +} + +CCVector CTL::Logger::GetLogs() { + return m_log_map.values(); +} + +CCVector CTL::Logger::GetLogFiles(const String &Date) { + CCVector result; + const auto Item = m_log_map.get(Date); + if (Item) { + String Path = ""; +#ifdef _WIN32 + Path = CCFile::NormalizePath(Item->File_Path); +#else + Path = CCFile::NormalizePath("/" + Item->File_Path); +#endif + const auto FileList = CCFile::GetDirectoryContents(Path); + for (const auto& File : FileList) { + try { + LogFile_t file; + file.Name = File.Name; + file.Size = File.Size; + file.Date = CCTimeData::formatTime(File.LastWriteTime); + result.add_lock(file); + } + catch (...){} + } + } + return result; +} + +CTL::String CTL::Logger::GetCurrentFolder() const { + const String RP = CCFile::NormalizePath(Root_Folder_Path); + const String RPA = CCFile::NormalizePath(RP + "/" + "log_" + CurrentDate); + return RPA; +} + +CTL::String CTL::Logger::GetCurrentDate() const { + return CurrentDate; +} + +CTL::String CTL::Logger::GetLogFile(const String &Date, const String &fileName) { + const auto List = GetLogFiles(Date); + for (const auto &I : List) { + if (I.Name == fileName) { + try { + const String RP = CCFile::NormalizePath(Root_Folder_Path); + const String RPA = CCFile::NormalizePath(RP + "/" + "log_" + Date); + return RPA + "/" + I.Name; + } + catch (...){} + break; + } + } + return ""; +} + +CTL::String CTL::Logger::GetLog(const String &Date, const String &fileName) { + const auto List = GetLogFiles(Date); + for (const auto &I : List) { + if (I.Name == fileName) { + try { + const String RP = CCFile::NormalizePath(Root_Folder_Path); + const String RPA = CCFile::NormalizePath(RP + "/" + "log_" + Date); + const String Path = RPA + "/" + I.Name; + String str = CCFileInStream::ReadFileDataAll(Path); + return str; + } + catch (...){} + } + } + return ""; +} + +bool CTL::Logger::DeleteLog(const String &Date, const String &fileName) { + bool F = false; + const auto List = GetLogFiles(Date); + for (const auto &I : List) { + if (I.Name == fileName) { + try { + const String RP = CCFile::NormalizePath(Root_Folder_Path); + const String RPA = CCFile::NormalizePath(RP + "/" + "log_" + Date); + const String Path = RPA + "/" + I.Name; + CCFile file(Path); + if (file.isExists()) { + F = file.Delete(false); + } + } + catch (...){} + break; + } + } + return F; +} + void CTL::Logger::Log2(const Logger_Level level, const String& message) { if (m_level > level) { return; @@ -116,20 +243,38 @@ void CTL::Logger::Log2(const Logger_Level level, const String& message) { const CCTimeData Time; const String T = Time.to_String(); const String str = String::format("[%s] %s -> %s",T.c_str() ,Level_Count[level],message.c_str()); + const auto OS = System::GetOS(); if (level == Logger_Level::Debug) { - CC::Println(str,BLUE); + if (OS == OS::OpenHarmony) { + System::Println(str); + } + else { + CC::Println(str,BLUE); + } } else if (level == Logger_Level::Info) { - CC::Println(str,GREEN); + if (OS == OS::OpenHarmony) { + System::Println(str); + } + else { + CC::Println(str,GREEN); + } } else if (level == Logger_Level::Warning) { - CC::Println(str,YELLOW); + if (OS == OS::OpenHarmony) { + System::Println(str); + } + else { + CC::Println(str,YELLOW); + } } - else if (level == Logger_Level::Error) { - CC::Println(str,RED); - } - else if (level == Logger_Level::Fatal) { - CC::Println(str,RED); + else if (level == Logger_Level::Error || Logger_Level::Fatal) { + if (OS == OS::OpenHarmony) { + System::Println(str); + } + else { + CC::Println(str,RED); + } } LogWriting(str); } @@ -181,9 +326,19 @@ void CTL::Logger::InitializeFolder() { for (const auto& entry : list) { if (entry.is_directory()) { CCFile file(entry); - if (const String Name = GetLogFilePath(file.GetName()); !Name.empty()) { - if (CompareDateDifference(baseDate, Name,is_save_cond_)) { - bool F = f.Delete(true); + if (const String Time2 = GetLogFilePath(file.GetName()); !Time2.empty()) { + if (CompareDateDifference(baseDate, Time2,is_save_cond_)) { + bool F = file.Delete(true); + if (F) { + m_log_map.Remove(Time2); + } + } + else { + LogParentFile logger_t; + logger_t.Date = Time2; + logger_t.Name = file.GetName(); + logger_t.File_Path = file.GetPath(); + m_log_map.put(logger_t.Date, logger_t); } } } @@ -191,7 +346,7 @@ void CTL::Logger::InitializeFolder() { } } -void CTL::Logger::DeleteOldFolders(const String& rootPath, int days) { +void CTL::Logger::DeleteOldFolders(const String& rootPath, const int days) { const auto list = CCFile::DirectoryList(rootPath); const auto now = std::chrono::system_clock::now(); const auto duration = std::chrono::hours(24 * days); @@ -225,6 +380,7 @@ CTL::String CTL::Logger::GetLogFilePath(const String& fileName) { } std::chrono::system_clock::time_point CTL::Logger::StringToDate(const String& dateString) { +#ifdef _WIN32 std::tm tm = {}; std::istringstream ss(dateString.c_str()); ss >> std::get_time(&tm, "%Y-%m-%d"); @@ -232,26 +388,40 @@ std::chrono::system_clock::time_point CTL::Logger::StringToDate(const String& da throw std::runtime_error("Invalid date format"); } return std::chrono::system_clock::from_time_t(std::mktime(&tm)); +#else + std::tm tm = {}; + const auto result = strptime(dateString.c_str(), "%Y-%m-%d", &tm); + if (result == nullptr) { + throw std::runtime_error("Invalid date format"); + } + return std::chrono::system_clock::from_time_t(std::mktime(&tm)); +#endif } bool CTL::Logger::CompareDateDifference(const String& dateStr1, const String& dateStr2, int days) { - auto date1 = StringToDate(dateStr1); - auto date2 = StringToDate(dateStr2); - auto duration = std::chrono::duration_cast(date2 - date1); - return std::abs(duration.count()) / 24 == days; + // auto date1 = StringToDate(dateStr1); + // auto date2 = StringToDate(dateStr2); + // auto duration = std::chrono::duration_cast(date2 - date1); + const int daysDiff = daysBetweenDates(dateStr1, dateStr2); + return daysDiff >= days || daysDiff <= -days; } CTL::String CTL::Logger::GetsTheCurrentLogFile() { const CCTimeData Time; - const String Tim = Time.to_String("yyyy-MM-dd"); + CurrentDate = Time.to_String("yyyy-MM-dd"); const String RP = CCFile::NormalizePath(Root_Folder_Path); - m_log_file_dir = RP + "/" + "log_" + Tim; + m_log_file_dir = RP + "/" + "log_" + CurrentDate; const String RPA = CCFile::NormalizePath(m_log_file_dir); if (const CCFile f(RPA); !f.isExists()) { log_m_count = 0; CCFile::Create(RPA, true); + LogParentFile logger_t; + logger_t.Date = GetLogFilePath(f.GetName()); + logger_t.Name = f.GetName(); + logger_t.File_Path = f.GetPath(); + m_log_map.put(logger_t.Date, logger_t); } - const String Path = RPA + "/" + Tim + "_CC_" + CCInt(log_m_count).to_String() + ".log"; + const String Path = RPA + "/" + CurrentDate + "_CC_" + CCInt(log_m_count).to_String() + ".log"; m_log_file_name = CCFile::NormalizePath(Path); return m_log_file_name; } @@ -260,3 +430,11 @@ void CTL::Logger::CloseWrite() { m_log_file_name = GetsTheCurrentLogFile(); WriteData(m_log_file_name); } + +int CTL::Logger::daysBetweenDates(const std::string &date1, const std::string &date2) { + auto tp1 = StringToDate(date1); + auto tp2 = StringToDate(date2); + + auto duration = std::chrono::duration_cast(tp2 - tp1); + return duration.count() / 24; // 转换为天数 +} diff --git a/CC_SDK/src/Module/IO/CCProcess.cpp b/CC_SDK/src/Module/IO/CCProcess.cpp index c36d1209..bb119dcd 100644 --- a/CC_SDK/src/Module/IO/CCProcess.cpp +++ b/CC_SDK/src/Module/IO/CCProcess.cpp @@ -1,65 +1,196 @@ #include "IO/CCProcess.h" - #include -CTL::Process::Process(Process &p) { - pipe = p.pipe; +#include "CCSystem.h" + +#ifdef _WIN32 +#include "windows.h" +#elif __linux__ +#include +#include +#include +#endif + +CTL::Process::Process(const Process &p) { ReadBuffer = p.ReadBuffer; - CommandQueues = p.CommandQueues; } -void CTL::Process::AddCommand(const CTL::String& Command) { - CommandQueues.emplace(Command); +void CTL::Process::Command(const CTL::String& CommandExe) { + ExeName = CommandExe; } -void CTL::Process::Start() { - CTL::String str = ""; - while (!CommandQueues.empty()) { - auto Command = CommandQueues.front(); - str.append(Command); - CommandQueues.pop(); +void CTL::Process::SetWorking(const String &WorkPath) { + this->Working = WorkPath; +} + +bool CTL::Process::Start(const bool isolation) { +#ifdef _WIN32 + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.lpSecurityDescriptor = nullptr; + sa.bInheritHandle = TRUE; + if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) { + std::cerr << "CreatePipe failed" << std::endl; + return false; } - pipe = popen(str.c_str(), "r"); + STARTUPINFO si; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdOutput = hWritePipe; + si.hStdError = hWritePipe; + ZeroMemory(&pi, sizeof(pi)); + const auto cmdLine = const_cast(this->ExeName.c_str()); + const auto Group = isolation ? CREATE_NEW_PROCESS_GROUP : 0; + const char* workingDir = Working.empty() ? nullptr : Working.c_str(); + if (!CreateProcessA(nullptr, cmdLine, nullptr, + nullptr, TRUE, Group, nullptr, + workingDir, reinterpret_cast(&si), &pi)) { + std::cerr << "CreateProcess failed" << std::endl; + CloseHandle(hReadPipe); + CloseHandle(hWritePipe); + return false; + } + CloseHandle(hWritePipe); Flag = true; + return true; +#elif __linux__ + if (pipe(pipefd) == -1) { + std::cerr << "Create pipe failed" << std::endl; + return false; + } + pid = fork(); + if (pid == -1) { + std::cerr << "Fork failed" << std::endl; + close(pipefd[0]); + close(pipefd[1]); + return false; + } + if (pid == 0) { + if (isolation) { + if (setsid() == -1) { + exit(1); + } + pid_t pid2 = fork(); + if (pid2 == -1) { + exit(1); + } + if (pid2 != 0) { + exit(0); + } + if (!Working.empty()) { + chdir(Working.c_str()); + } + close(pipefd[0]); + close(pipefd[1]); + const int fd = open("/dev/null", O_RDWR); + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + close(fd); + execl("/bin/sh", "sh", "-c", ExeName.c_str(), nullptr); + exit(1); + } else { + dup2(pipefd[1], STDOUT_FILENO); + dup2(pipefd[1], STDERR_FILENO); + close(pipefd[0]); + close(pipefd[1]); + if (!Working.empty()) { + chdir(Working.c_str()); + } + execl("/bin/sh", "sh", "-c", ExeName.c_str(), nullptr); + exit(1); + } + } + else { + if (isolation) { + waitpid(pid, nullptr, 0); + close(pipefd[0]); + close(pipefd[1]); + } + else { + close(pipefd[1]); + } + Flag = true; + return true; + } +#endif } void CTL::Process::Stop() { - if (pipe) { - int status = pclose(pipe); // pclose会阻塞直到子进程结束 - Flag = (status == -1); // status=-1表示关闭失败 - pipe = nullptr; +#ifdef _WIN32 + WaitForSingleObject(pi.hProcess, INFINITE); + CloseHandle(hReadPipe); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + Flag = false; +#elif __linux__ + if (Flag) { + int status; + waitpid(pid, &status, 0); + close(pipefd[0]); + Flag = false; } +#endif } -CTL::String CTL::Process::ReadLineBuffer() { - if (!pipe) return Process_Read_Error; - - char buffer[CC_PROCESS_MAX_BUFFER_SIZE] = {0}; - if (fgets(buffer, sizeof(buffer), pipe) == NULL) { - if (feof(pipe)) { - Flag = false; - pclose(pipe); - pipe = nullptr; - } - return Process_Read_Error; +CTL::ByteArray CTL::Process::ReadLineBuffer() const { +#ifdef _WIN32 + DWORD bytesRead; + ByteArray ReadBuffer_t; + char buffer[CC_PROCESS_MAX_BUFFER_SIZE]{}; + if (ReadFile(hReadPipe, buffer, sizeof buffer - 1, &bytesRead, nullptr) && bytesRead > 0) { + buffer[bytesRead] = '\0'; } - return buffer; -} - -bool CTL::Process::IsRunning() { -// return Flag; - if (!pipe) return false; - - // 尝试非阻塞读取 - char buf[CC_PROCESS_MAX_BUFFER_SIZE] = {0}; - if (fgets(buf, sizeof(buf), pipe) == NULL) { - if (feof(pipe)) { // 检测到EOF说明进程已关闭 - Flag = false; - } + ReadBuffer_t.assign(buffer, bytesRead); + return ReadBuffer_t; +#elif __linux__ + char buffer[CC_PROCESS_MAX_BUFFER_SIZE]; + const ssize_t bytesRead = read(pipefd[0], buffer, sizeof(buffer) - 1); + ByteArray ReadBuffer_t; + if (bytesRead > 0) { + buffer[bytesRead] = '\0'; + ReadBuffer_t.assign(buffer, bytesRead); } - return Flag; + return ReadBuffer_t; +#endif } -void CTL::Process::Execute(const CTL::String &Command) { - +bool CTL::Process::IsRunning() const { +#ifdef _WIN32 + if (!Flag) { + return false; + } + DWORD exitCode; + if (GetExitCodeProcess(pi.hProcess, &exitCode)) { + return (exitCode == STILL_ACTIVE); + } + return false; +#elif __linux__ + if (!Flag) { + return false; + } + return (waitpid(pid, nullptr, WNOHANG) == 0); +#endif +} + +void CTL::Process::Execute(const String &Command) { + Process process; + process.Command(Command); + process.Start(); + const auto line = process.ReadLineBuffer(); + if (!line.IsEmpty()) { + System::Println("{}",line.toString().c_str()); + } + process.Stop(); +} + +void CTL::Process::StopProcess(String &Name) { +#ifdef _WIN32 + Name += ".exe"; + const String cmd = String::format("taskkill /im {} /t /f",Name.c_str()); + Execute(cmd); +#elif __linux__ + const String cmd = String::format("killall -9 {}",Name.c_str()); + Execute(cmd); +#endif } diff --git a/CC_SDK/src/Module/IO/CCThread.cpp b/CC_SDK/src/Module/IO/CCThread.cpp index 5820fc50..b9001085 100644 --- a/CC_SDK/src/Module/IO/CCThread.cpp +++ b/CC_SDK/src/Module/IO/CCThread.cpp @@ -1,29 +1,30 @@ #include "IO/CCThread.h" + using namespace CTL; -void Thread_V::Start() { +void Thread_Integration::Start() { this->Flag = true; - Thread_m = std::thread(&Thread_V::running, this); + Thread_m = std::thread(&Thread_Integration::running, this); } -void Thread_V::Stop() { +void Thread_Integration::Stop() { this->Flag = false; while (this->Flag_m) { CTL::Thread::SleepMS(10); } } -void Thread_V::Wait() { +void Thread_Integration::Wait() { this->Flag = true; - Thread_m = std::thread(&Thread_V::running, this); + Thread_m = std::thread(&Thread_Integration::running, this); Thread_m.join(); } -bool Thread_V::Sign() const { +bool Thread_Integration::Sign() const { return Flag; } -void Thread_V::running() { +void Thread_Integration::running() { this->Flag = true; this->Flag_m = true; this->Run(); @@ -31,26 +32,46 @@ void Thread_V::running() { this->Flag_m = false; } -Thread::Thread(const Thread &&other) { +Thread::Thread() { + std::unique_lock lock(thread_mutex_t); + this->threadID = AssignID(); + CC_thread_Map_t.put(threadID, this); +} + +Thread::Thread(const Thread &&other) noexcept { this->Flag = other.Flag; this->task = other.task; + Thread_m = other.Thread_m; + this->threadID = other.threadID; } Thread::Thread(const Thread &other) { this->Flag = other.Flag; this->task = other.task; + Thread_m = other.Thread_m; + this->threadID = other.threadID; } -Thread::~Thread() -{ - if (Thread_m.joinable()) - { - Thread_m.join(); +Thread::~Thread(){ + CCUniqueLock lock(thread_mutex_t); + if (!Thread_m) { + return; } + if (Thread_m->joinable() && SafeExit){ + Thread_m->join(); + } + try{ + this->task = nullptr; + delete Thread_m; + Thread_m = nullptr; + if (SafeExit){ + CC_thread_Map_t.Remove(this->threadID); + } + } + catch (...){} } -void Thread::Stop() -{ +void Thread::Stop(){ Flag = false; } @@ -79,12 +100,28 @@ long Thread::SleepMS(const unsigned int MS) { return duration.count(); } -std::thread & Thread::GetThread(){ +std::thread* Thread::GetThread() const { return Thread_m; } std::thread::id Thread::GetThreadId() const { - return Thread_m.get_id(); + if (Thread_m) { + return Thread_m->get_id(); + } + return {}; +} + +void Thread::SetSafeExit(const bool Flag){ + SafeExit = Flag; +} + +int Thread::AssignID() { + for (int i = 0; i < 100 * 1024 * 1024; i++) { + if (!CC_thread_Map_t.IsContains(i)) { + return i; + } + } + return -1; } diff --git a/CC_SDK/src/Module/IO/CCThreadPool.cpp b/CC_SDK/src/Module/IO/CCThreadPool.cpp index 58431712..c0e08d40 100644 --- a/CC_SDK/src/Module/IO/CCThreadPool.cpp +++ b/CC_SDK/src/Module/IO/CCThreadPool.cpp @@ -29,28 +29,28 @@ void CTL::ThreadPool::Stop() { // CC::Println("ThreadPool Close"); } -int CTL::ThreadPool::GetActiveThread() { - return T_PoolSize; +int CTL::ThreadPool::GetActiveThread() const { + return T_PoolSize.load(); } -int CTL::ThreadPool::GetMaxPoolSize() { +int CTL::ThreadPool::GetMaxPoolSize() const { return m_maximumPoolSize; } -int CTL::ThreadPool::GetCorePoolSize() { +int CTL::ThreadPool::GetCorePoolSize() const { return m_corePoolSize; } -int CTL::ThreadPool::GetTimeout() { +int CTL::ThreadPool::GetTimeout() const { return m_keepAliveTime; } -int CTL::ThreadPool::GetActiveExtraThread() { - return E_PoolSize; +int CTL::ThreadPool::GetActiveExtraThread() const { + return E_PoolSize.load(); } void CTL::ThreadPool::Worker(int index) { - m_C_threadPool++; + ++m_C_threadPool; while (!m_isStop.load()) { // 使用 load 方法读取 atomic 变量 Function task = nullptr; { @@ -66,14 +66,18 @@ void CTL::ThreadPool::Worker(int index) { } if (task) { try { + ++T_PoolSize; task(); - } catch (CCException& e) { - CC_PRINT_ERROR("ThreadPool::Worker() Error: " + CTL::String(e.what())); + --T_PoolSize; + } + catch (CCException& e) { + String errorMsg = "ThreadPool::Worker Error in function: "; + errorMsg += e.what(); + CC_PRINT_ERROR(errorMsg); } } } - m_C_threadPool--; - // CC::Println("ThreadPool End -> " + CC::to_String(index)); + --m_C_threadPool; } void CTL::ThreadPool::CC_PRINT_ERROR(const CTL::String& str) { @@ -83,8 +87,8 @@ void CTL::ThreadPool::CC_PRINT_ERROR(const CTL::String& str) { void CTL::ThreadPool::ExtraThread(Function Task) { Thread([&]() { - E_PoolSize++; - T_PoolSize++; + ++E_PoolSize; + ++T_PoolSize; try { while (!m_isStop) { if (Task) { @@ -111,7 +115,7 @@ void CTL::ThreadPool::ExtraThread(Function Task) { catch (CCException& e) { CC_PRINT_ERROR("ThreadPool::Worker() Error: " + CTL::String(e.what())); } - T_PoolSize--; - E_PoolSize--; + --T_PoolSize; + --E_PoolSize; }).Start(); } diff --git a/CC_SDK/src/Module/IO/CCTimeData.cpp b/CC_SDK/src/Module/IO/CCTimeData.cpp index 587a109e..24959cc6 100644 --- a/CC_SDK/src/Module/IO/CCTimeData.cpp +++ b/CC_SDK/src/Module/IO/CCTimeData.cpp @@ -2,6 +2,8 @@ #include "CCString.h" using namespace CTL; +int daysInMonth_t[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + CCTimeData::CCTimeData(std::time_t* t) { m_time = t; } @@ -45,7 +47,7 @@ CCTimeInfo CCTimeData::GetTime(const time_t t) { return CCTimeInfo{year, month, day, hour, minute, second, weekday}; } -int CCTimeData::GetWeek(int week) { +int CCTimeData::GetWeek(const int week) { switch (week) { case 0: return 7; case 1: return 1; @@ -102,6 +104,42 @@ std::string CCTimeData::Format(const std::string &format) const { return std::string(buffer); } +CCTimeInfo CCTimeData::parseTimeString(const std::string &timeStr) { + CCTimeInfo timeInfo = {}; + std::istringstream ss(timeStr); + char delimiter; + + + ss >> timeInfo.year >> delimiter >> timeInfo.month >> delimiter >> timeInfo.day + >> timeInfo.hour >> delimiter >> timeInfo.minute >> delimiter >> timeInfo.second; + + // 注意:week 字段需要额外计算,这里暂时设为 0 + timeInfo.week = 0; + + return timeInfo; +} + +time_t CCTimeData::parseTimeString_t(const std::string &timeStr) { + std::tm tm = {}; + std::istringstream ss(timeStr); + ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S"); + tm.tm_isdst = -1; // 让系统决定是否为夏令时 + return std::mktime(&tm); +} + +std::string CCTimeData::formatTime(const time_t time) { + std::tm* tm = std::localtime(&time); + std::ostringstream ss; + ss << std::put_time(tm, "%Y-%m-%d %H:%M:%S"); + return ss.str(); +} + +std::string CCTimeData::addSecondsToTime(const std::string &timeStr, int seconds) { + time_t time = parseTimeString_t(timeStr); + time += seconds; // 加上指定秒数 + return formatTime(time); +} + bool CCTimeData::operator==(const CCTimeInfo &other) const { return GetTimeInfo.year == other.year && GetTimeInfo.month == other.month && GetTimeInfo.day == other.day && GetTimeInfo.hour == other.hour && @@ -143,3 +181,43 @@ int CCTimeData::operator-(const CCTimeInfo &other) const { (GetTimeInfo.day - other.day) * 24 + (GetTimeInfo.hour - other.hour) * 60 + (GetTimeInfo.minute - other.minute) * 60 + (GetTimeInfo.second - other.second); } + +bool CCTimeData::isLeapYear(const int year) { + return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); +} + +int CCTimeData::dateToDays(const int year, const int month, const int day) { + int days = 0; + // 加上整年的天数 + for (int y = 1; y < year; ++y) { + days += isLeapYear(y) ? 366 : 365; + } + // 加上当年前面月份的天数 + for (int m = 1; m < month; ++m) { + days += daysInMonth_t[m - 1]; + if (m == 2 && isLeapYear(year)) { + days += 1; // 闰年2月多一天 + } + } + // 加上当月的天数 + days += day; + return days; +} + +int CCTimeData::calculateDaysDifference(const std::string &date1, const std::string &date2) { + const auto T1 = parseTimeString(date1); + const auto T2 = parseTimeString(date2); + const int days1 = dateToDays(T1.year, T1.month, T1.day); + const int days2 = dateToDays(T2.year, T2.month, T2.day); + return days2 - days1; +} + +bool CCTimeData::IsNewDay() { + const CCTimeData currentTime; + const std::string currentDate = currentTime.to_String("yyyy-MM-dd"); + if (LastCheckedDate != currentDate) { + LastCheckedDate = currentDate; + return true; + } + return false; +} diff --git a/CC_SDK/src/Module/Window/CCApplication.cpp b/CC_SDK/src/Module/Window/CCApplication.cpp index ae09d8c7..011c5b3f 100644 --- a/CC_SDK/src/Module/Window/CCApplication.cpp +++ b/CC_SDK/src/Module/Window/CCApplication.cpp @@ -1,25 +1,37 @@ #include "CCApplication.h" +#include "CCFileOutStream.h" +#ifdef _WIN32 +#include "windows.h" +#elif __linux__ +#include +#include +#include +#endif int CTL::Application::Running(const Application* app) { while (CC::IsRun()){ - CTL::Thread::SleepMS(16); + Thread::SleepMS(16); { CCUniqueLock locks(M_Mutex); - while (true) { - try { - if (M_SignalQueues.empty()) { - break; - } - auto signal = M_SignalQueues.front(); - M_SignalQueues.pop(); - signal(); - } - catch (CCException& e) { - CC::Println("Application::Running -> " + CTL::String(e.what()),RED); + try { + if (M_SignalQueues.empty()) { + continue; } + auto signal = M_SignalQueues.front(); + M_SignalQueues.pop(); + signal(); + } + catch (CCException& e) { + CC::Println("Application::Running -> " + CTL::String(e.what()),RED); } } } + if (func_Close){ + func_Close(); + } + if(SingleInstance_t){ + ReleaseLock(); + } return 0; } @@ -56,3 +68,50 @@ void CTL::Application::Signal(Function &&func) { M_SignalQueues.push(std::move(func)); } +void CTL::Application::SetCloseFun(Function&& func){ + func_Close = func; +} + +bool CTL::Application::IsSingleInstance() { + SingleInstance_t = true; +#ifdef _WIN32 + mutex_handle = CreateMutex(NULL, TRUE, mutex_name.to_CCWString().c_str()); + if (GetLastError() == ERROR_ALREADY_EXISTS) { + if (mutex_handle) { + CloseHandle(mutex_handle); + } + return false; + } + return true; +#else + lock_fd = open(lock_file_path, O_CREAT | O_RDWR, 0666); + if (lock_fd < 0) { + return false; + } + if (flock(lock_fd, LOCK_EX | LOCK_NB) != 0) { + close(lock_fd); + return false; + } + char pid_str[16]; + sprintf(pid_str, "%d\n", getpid()); + write(lock_fd, pid_str, strlen(pid_str)); + + return true; +#endif +} + +void CTL::Application::ReleaseLock() { +#ifdef _WIN32 + if (mutex_handle) { + ReleaseMutex(mutex_handle); + CloseHandle(mutex_handle); + } +#else + if (lock_fd >= 0) { + flock(lock_fd, LOCK_UN); + close(lock_fd); + unlink(lock_file_path); // 删除锁文件 + } +#endif +} + diff --git a/CC_SDK/src/Module/Window/CCSystem.cpp b/CC_SDK/src/Module/Window/CCSystem.cpp index 5e413d6d..b4d11fb3 100644 --- a/CC_SDK/src/Module/Window/CCSystem.cpp +++ b/CC_SDK/src/Module/Window/CCSystem.cpp @@ -1,15 +1,32 @@ #include "CCSystem.h" #include "CCString.h" +#include "CCFile.h" #include #ifdef _WIN32 +#include "Windows.h" +#include +#include +#include +#include #include -#include "windows.h" -#include "shlwapi.h" #include #include #elif __linux__ +#include +#include +#include +#include #include +#include +#include +#include +#include +#ifdef __OHOS__ +#include "hidebug/hidebug.h" +#else +#include +#endif #endif #ifdef _WIN32 @@ -105,32 +122,49 @@ bool CTL::System::SetAppAutoStart(bool F) { } #elif __linux__ if (F) { - CTL::String name = GetAppName(); - const std::string desktopPath = "/home/" + GetUserName() + "/.config/autostart/" + name + ".desktop"; - if (std::ofstream desktopFile(desktopPath); desktopFile.is_open()) { - desktopFile << "[Desktop Entry]\n"; - desktopFile << "Version=1.0\n"; - desktopFile << "Type=Application\n"; - desktopFile << "Categories=Development\n"; - desktopFile << "Exec=" << ApplicationDirPath() + "/" + name << "\n"; - desktopFile << "Path=" << ApplicationDirPath() << "\n"; - desktopFile << "NoDisplay=false\n"; - desktopFile << "StartupWMClass="+ name +"\n"; - desktopFile << "Name=" << name << "\n"; - desktopFile << "Terminal=true\n"; - desktopFile << "StartupNotify=false\n"; - desktopFile << "X-GNOME-Autostart-enabled=true\n"; - desktopFile << "X-GNOME-Autostart-Delay=10\n"; - desktopFile << "X-MATE-Autostart-Delay=10\n"; - desktopFile << "X-KDE-autostart-after=panel\n"; - desktopFile.close(); - SetFileReadPermission(desktopPath); + String name = GetAppName(); + // 使用用户级systemd服务 + const std::string servicePath = "/etc/systemd/system/" + name + ".service"; + std::ofstream serviceFile(servicePath); + if (serviceFile.is_open()) { + serviceFile << "[Unit]\n"; + serviceFile << "Description=" << name << " Application\n"; + serviceFile << "After=graphical-session.target\n"; + serviceFile << "\n"; + serviceFile << "[Service]\n"; + serviceFile << "Type=simple\n"; + serviceFile << "ExecStart=" << ApplicationDirPath() + "/" + name << "\n"; + serviceFile << "Environment=" << "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:" + "/usr/bin:/sbin:/bin:/snap/bin:/" << ApplicationDirPath() << "\n"; + serviceFile << "WorkingDirectory=" << ApplicationDirPath() << "\n"; + serviceFile << "Restart=always\n"; + serviceFile << "RestartSec=5\n"; + serviceFile << "\n"; + serviceFile << "[Install]\n"; + serviceFile << "WantedBy=default.target\n"; + serviceFile.close(); + + // 设置文件权限 + SetFileReadPermission(servicePath); + + // 启用服务 + std::string enableCmd = "systemctl enable " + name + ".service"; + system(enableCmd.c_str()); + A = true; } } else { - const std::string desktopPath = "/home/" + GetUserName() + "/.config/autostart/" + GetAppName() + ".desktop"; - std::remove(desktopPath.c_str()); + const String name = GetAppName(); + const std::string servicePath = "/etc/systemd/system/" + name + ".service"; + + // 禁用服务 + std::string disableCmd = "systemctl disable " + name + ".service"; + system(disableCmd.c_str()); + + // 删除服务文件 + std::remove(servicePath.c_str()); + A = true; } #endif @@ -144,9 +178,17 @@ bool CTL::System::IsAppAutoStart() { CCFile file(AB); F = file.isExists(); #elif __linux__ - const std::string desktopPath = "/home/" + GetUserName() + "/.config/autostart/"+ GetAppName() +".desktop"; - CCFile file(desktopPath); - F = file.isExists(); + const String name = GetAppName(); + const std::string servicePath = "/etc/systemd/system/" + name + ".service"; + + // 首先检查服务文件是否存在 + CCFile file(servicePath); + if (file.isExists()) { + // 检查服务是否已启用 + const std::string checkCmd = "systemctl is-enabled " + name + ".service > /dev/null 2>&1"; + const int result = system(checkCmd.c_str()); + F = (result == 0); // 返回值为0表示服务已启用 + } #endif return F; } @@ -173,26 +215,6 @@ CTL::String CTL::System::ApplicationDirPath() { return CCFile::NormalizePath("./"); } -void CTL::System::Println(const char* fmt,...){ - va_list args; - va_start(args, fmt); - // 计算格式化后字符串的长度 - va_list argsCopy; - va_copy(argsCopy, args); - const int length = std::vsnprintf(nullptr, 0, fmt, argsCopy); - va_end(argsCopy); - // 分配足够的空间来存储格式化后的字符串 - const auto buffer = new char[length + 1]; - std::vsnprintf(buffer, length + 1, fmt, args); - #ifdef CC_OHOS_ - OH_LOG_Print(LOG_APP, LOG_INFO, 0x0728, "CC_SDK", "%{public}s",buffer); -// OH_LOG_INFO(LOG_APP, "%{public}s",str.c_str()); - #else - CC::Println(buffer); - #endif - delete[] buffer; -} - void CTL::System::Println(const CTL::String &str) { #ifdef CC_OHOS_ OH_LOG_Print(LOG_APP, LOG_INFO, 0x0728, "CC_SDK", "%{public}s",str.c_str()); @@ -202,13 +224,15 @@ void CTL::System::Println(const CTL::String &str) { } void CTL::System::ReleaseProcessHeap() { -#if __linux__ - // malloc_trim(0); -#elif CC_OHOS_ +#if CC_OHOS_ +#elif __linux__ + malloc_trim(0); #elif _WIN32 - HANDLE heap = GetProcessHeap(); - HeapCompact(heap, 0); // 替换 malloc_trim(0) + const HANDLE heap = GetProcessHeap(); + HeapCompact(heap, 0); + HeapDestroy(heap); + SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1); #endif } @@ -291,6 +315,13 @@ CTL::MemoryInfo CTL::System::GetMemoryInfo() { status.ullTotalPhys, status.ullAvailPhys }; +#elif __OHOS__ + HiDebug_SystemMemInfo memInfo; + OH_HiDebug_GetSystemMemInfo(&memInfo); + return { + memInfo.totalMem, + memInfo.availableMem + }; #elif __linux__ struct sysinfo info; sysinfo(&info); @@ -339,47 +370,53 @@ CTL::String CTL::System::GetMac() { return macAddress; #elif __linux__ - struct ifreq ifr{}; + struct ifconf ifc; + struct ifreq *ifr; + char buffer[4096]; int sock = socket(AF_INET, SOCK_DGRAM, 0); CTL::String macAddress; if (sock >= 0) { - strcpy(ifr.ifr_name, "eth0"); // 先尝试eth0 + // 设置ifconf结构 + ifc.ifc_len = sizeof(buffer); + ifc.ifc_buf = buffer; - if (ioctl(sock, SIOCGIFHWADDR, &ifr) >= 0) { - char macStr[18] = {0}; - sprintf(macStr, "%02X-%02X-%02X-%02X-%02X-%02X", - static_cast(ifr.ifr_hwaddr.sa_data[0]), - (unsigned char)ifr.ifr_hwaddr.sa_data[1], - (unsigned char)ifr.ifr_hwaddr.sa_data[2], - (unsigned char)ifr.ifr_hwaddr.sa_data[3], - (unsigned char)ifr.ifr_hwaddr.sa_data[4], - (unsigned char)ifr.ifr_hwaddr.sa_data[5]); - macAddress = macStr; - } + // 获取所有网络接口 + if (ioctl(sock, SIOCGIFCONF, &ifc) >= 0) { + // 遍历所有网络接口 + int numInterfaces = ifc.ifc_len / sizeof(struct ifreq); + ifr = ifc.ifc_req; - // 如果eth0失败,尝试其他常见接口名 - if (macAddress.empty()) { - const char* interfaces[] = {"enp0s3", "wlan0", "eno1"}; - for (const char* ifname : interfaces) { - strcpy(ifr.ifr_name, ifname); - if (ioctl(sock, SIOCGIFHWADDR, &ifr) >= 0) { - char macStr[18] = {0}; - sprintf(macStr, "%02X-%02X-%02X-%02X-%02X-%02X", - (unsigned char)ifr.ifr_hwaddr.sa_data[0], - (unsigned char)ifr.ifr_hwaddr.sa_data[1], - (unsigned char)ifr.ifr_hwaddr.sa_data[2], - (unsigned char)ifr.ifr_hwaddr.sa_data[3], - (unsigned char)ifr.ifr_hwaddr.sa_data[4], - (unsigned char)ifr.ifr_hwaddr.sa_data[5]); - macAddress = macStr; - break; + for (int i = 0; i < numInterfaces; i++) { + // 跳过回环接口 + if (strcmp(ifr[i].ifr_name, "lo") == 0) { + continue; + } + + // 获取该接口的MAC地址 + strcpy(ifr[i].ifr_name, ifr[i].ifr_name); + if (ioctl(sock, SIOCGIFHWADDR, &ifr[i]) >= 0) { + // 检查是否是以太网接口 + if (ifr[i].ifr_hwaddr.sa_family == ARPHRD_ETHER) { + unsigned char* mac = (unsigned char*)ifr[i].ifr_hwaddr.sa_data; + // 检查MAC地址是否全为0 + if (mac[0] != 0 || mac[1] != 0 || mac[2] != 0 || + mac[3] != 0 || mac[4] != 0 || mac[5] != 0) { + + char macStr[18] = {0}; + sprintf(macStr, "%02X-%02X-%02X-%02X-%02X-%02X", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + macAddress = macStr; + break; + } + } } } } close(sock); } + // 如果仍然没有获取到MAC地址,则返回空字符串 return macAddress; #endif } diff --git a/CC_SDK/src/basic/CCByteArray.cpp b/CC_SDK/src/basic/CCByteArray.cpp index d893a181..f7b59c49 100644 --- a/CC_SDK/src/basic/CCByteArray.cpp +++ b/CC_SDK/src/basic/CCByteArray.cpp @@ -1,10 +1,38 @@ #include "basic/CCByteArray.h" using namespace CTL; -ByteArray::ByteArray -(const std::string &str) { + +static const char base64_chars[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +"abcdefghijklmnopqrstuvwxyz" +"0123456789+/"; + +static const unsigned char base64_decode_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, + 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +ByteArray::ByteArray(const std::string &str) { bytes.assign(str.begin(), str.end()); } +ByteArray::ByteArray(const void *str, const size_t size) { + this->Conversion<>(str,size); +} + ByteArray::ByteArray(const char *str) { bytes.assign(str, str + strlen(str)); } @@ -29,6 +57,10 @@ ByteArray::ByteArray(const std::initializer_list initList) { bytes.assign(initList); } +ByteArray::ByteArray(const ByteHander size) { + bytes.resize(size); +} + void ByteArray::add(const Byte byte) { bytes.push_back(byte); } @@ -66,18 +98,14 @@ void ByteArray::assign(char *buffer, const ByteHander size) { bytes.assign(buffer, buffer + size); } -void ByteArray::assign(char *buffer, const unsigned int size) { - bytes.assign(buffer, buffer + size); +void ByteArray::assign(const void *buffer, const ByteHander size) { + const char* cstr = static_cast(buffer); + bytes.assign(cstr, cstr + size); } -// void ByteArray::assign(char *buffer, const int size) { -// bytes.assign(buffer, buffer + size); -// } -// #ifdef __linux__ -// void ByteArray::assign(char* get, const std::ptrdiff_t size) { -// bytes.assign(get, get + size); -// } -// #endif +bool ByteArray::IsEmpty() const { + return bytes.empty(); +} void ByteArray::append(const std::string& str) { bytes.insert(bytes.end(), str.begin(), str.end()); @@ -127,7 +155,11 @@ ByteArray ByteArray::toFormat(const std::string &EncodeStr) const { return ByteArray(Encode::Format(this->toString(), EncodeStr)); } -std::vector ByteArray::data() { +std::vector ByteArray::toVector() { + return bytes; +} + +std::vector ByteArray::toVector() const{ return bytes; } @@ -139,6 +171,13 @@ const char* ByteArray::buffer() const { return reinterpret_cast(bytes.data()); } +char * ByteArray::newBuffer() const { + const auto str = new char[bytes.size() + 1]; + std::memcpy(str, bytes.data(), bytes.size()); + str[bytes.size()] = '\0'; + return str; +} + void ByteArray::resize(const size_t len) { bytes.resize(len); } @@ -171,3 +210,242 @@ void ByteArray::operator-=(const ByteArray &other) { bytes.erase(other.bytes.begin(), other.bytes.end()); } +Byte& ByteArray::operator[](const int index) { + if (index < 0 || index >= bytes.size()) { + throw std::out_of_range("Index out of range"); + } + return *(bytes.data() + index); +} + +Byte ByteArray::operator[](const int index) const { + if (index < 0 || index >= bytes.size()) { + throw std::out_of_range("Index out of range"); + } + return *(bytes.data() + index); +} + +ByteArray ByteArray::subBuffer(const ByteHander start, const ByteHander end) const { + if (start > end || end > bytes.size()) { + throw std::out_of_range("subBuffer Index out of range"); + } + return {bytes.data() + start, end - start}; +} + +std::string ByteArray::toBase64() { + std::string ret; + int i = 0; + uint8_t char_array_3[3]; + uint8_t char_array_4[4]; + auto it = bytes.begin(); + while (it != bytes.end()) { + char_array_3[i++] = *(it++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (i = 0; (i < 4); i++) { + ret += base64_chars[char_array_4[i]]; + } + i = 0; + } + } + if (i) { + int j = 0; + for (j = i; j < 3; j++) { + char_array_3[j] = '\0'; + } + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (j = 0; (j < i + 1); j++) { + ret += base64_chars[char_array_4[j]]; + } + + while ((i++ < 3)) { + ret += '='; + } + } + return ret; +} + +ByteArray ByteArray::fromBase64(const std::string &base64Str) { + ByteArray result; + unsigned char char_array_4[4]; + unsigned char char_array_3[3]; + size_t i = 0; + size_t j = 0; + + auto it = base64Str.begin(); + while (it != base64Str.end() && *it != '=') { + // 跳过非Base64字符 + if (*it == ' ' || *it == '\r' || *it == '\n') { + ++it; + continue; + } + + char_array_4[i++] = static_cast(*it); + ++it; + + if (i == 4) { + for (j = 0; j < 4; j++) { + char_array_4[j] = base64_decode_table[char_array_4[j]]; + } + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; j < 3; j++) { + result.add(Byte(char_array_3[j])); + } + i = 0; + } + } + + // 处理剩余字符 + if (i > 0) { + for (j = i; j < 4; j++) { + char_array_4[j] = 0; + } + + for (j = 0; j < i; j++) { + char_array_4[j] = base64_decode_table[char_array_4[j]]; + } + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; j < i - 1; j++) { + result.add(Byte(char_array_3[j])); + } + } + + return result; +} + +void ByteArray::fill(const Byte value, const size_t start, size_t end) { + if (bytes.empty()) return; + + if (end == static_cast(-1)) { + end = bytes.size(); + } + + if (start >= bytes.size() || end > bytes.size() || start > end) { + throw std::out_of_range("Index out of range"); + } + + std::fill(bytes.begin() + start, bytes.begin() + end, value); +} + +void ByteArray::copyTo(ByteArray &dest, const size_t srcStart, const size_t destStart, size_t count) const { + if (bytes.empty()) return; + + if (srcStart >= bytes.size()) { + throw std::out_of_range("Source start index out of range"); + } + + if (count == static_cast(-1)) { + count = bytes.size() - srcStart; + } + + if (srcStart + count > bytes.size()) { + throw std::out_of_range("Copy count exceeds source size"); + } + + // 确保目标数组有足够的空间 + if (destStart + count > dest.bytes.size()) { + dest.bytes.resize(destStart + count); + } + std::copy_n(bytes.begin() + srcStart, count, dest.bytes.begin() + destStart); +} + +ByteArray ByteArray::clone() const { + return ByteArray(*this); +} + +int ByteArray::indexOf(const Byte value, const size_t start) const { + if (bytes.empty() || start >= bytes.size()) { + return -1; + } + + const auto it = std::find(bytes.begin() + start, bytes.end(), value); + if (it != bytes.end()) { + return static_cast(std::distance(bytes.begin(), it)); + } + return -1; +} + +int ByteArray::lastIndexOf(const Byte value, size_t start) const { + if (bytes.empty()) { + return -1; + } + + if (start == static_cast(-1) || start >= bytes.size()) { + start = bytes.size() - 1; + } + + for (int i = static_cast(start); i >= 0; --i) { + if (bytes[i] == value) { + return i; + } + } + return -1; +} + +int ByteArray::indexOf(const ByteArray &pattern, const size_t start) const { + if (pattern.bytes.empty() || bytes.empty() || start >= bytes.size()) { + return -1; + } + + auto it = std::search(bytes.begin() + start, bytes.end(), + pattern.bytes.begin(), pattern.bytes.end()); + if (it != bytes.end()) { + return static_cast(std::distance(bytes.begin(), it)); + } + return -1; +} + +int ByteArray::lastIndexOf(const ByteArray &pattern, size_t start) const { + if (pattern.bytes.empty() || bytes.empty()) { + return -1; + } + + if (pattern.bytes.size() > bytes.size()) { + return -1; + } + + if (start == static_cast(-1) || start >= bytes.size()) { + start = bytes.size() - 1; + } + + // 限制start确保不会越界 + if (start < pattern.bytes.size() - 1) { + return -1; + } + + size_t end = start - pattern.bytes.size() + 1; + for (int i = static_cast(start); i >= static_cast(end); --i) { + bool match = true; + for (size_t j = 0; j < pattern.bytes.size(); ++j) { + if (bytes[i - static_cast(pattern.bytes.size()) + 1 + j] != pattern.bytes[j]) { + match = false; + break; + } + } + if (match) { + return i - static_cast(pattern.bytes.size()) + 1; + } + } + return -1; +} + +bool ByteArray::equals(const ByteArray &other) const { + return *this == other; +} + diff --git a/CC_SDK/src/basic/CCEncode.cpp b/CC_SDK/src/basic/CCEncode.cpp index 7108b894..25851b63 100644 --- a/CC_SDK/src/basic/CCEncode.cpp +++ b/CC_SDK/src/basic/CCEncode.cpp @@ -54,6 +54,12 @@ std::string CTL::Encode::Format(const std::string &str, const std::string &from, return std::string(A.begin(), A.end()); } +std::string CTL::Encode::formatString(const std::string &str, const StandardCharsets from, const StandardCharsets to) { + std::vector data(str.begin(), str.end()); + auto A = reiconv::encode(Charset::format(from), Charset::format(to), data); + return std::string(A.begin(), A.end()); +} + std::vector CTL::Encode::Format(const std::string &str, const StandardCharsets from, const StandardCharsets to) { const std::vector data(str.begin(), str.end()); return reiconv::encode(Charset::format(from), Charset::format(to), data); diff --git a/CC_SDK/src/basic/CCObject.cpp b/CC_SDK/src/basic/CCObject.cpp index 31709f31..3c9db35b 100644 --- a/CC_SDK/src/basic/CCObject.cpp +++ b/CC_SDK/src/basic/CCObject.cpp @@ -1 +1,24 @@ #include "./basic/CCObject.h" +#include "iostream" +#include +#include + + +bool CTL::Object::equals(const Object *other) { + return this == other; // 默认比较内存地址 +} + +size_t CTL::Object::hashCode() const noexcept { + return std::hash{}(this); +} + +std::string CTL::Object::toString() const { + char buffer[64]; + snprintf(buffer, sizeof(buffer), "Object@%p", static_cast(this)); + return buffer; +} + +std::ostream & CTL::operator<<(std::ostream &os, const Object &map) { + os << map.toString(); + return os; +} diff --git a/CC_SDK/src/basic/CCString.cpp b/CC_SDK/src/basic/CCString.cpp index c7dd5310..d56b98c1 100644 --- a/CC_SDK/src/basic/CCString.cpp +++ b/CC_SDK/src/basic/CCString.cpp @@ -7,22 +7,6 @@ String::String(const CCSStream &stream) { this->assign(stream.str()); } -String::String(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - // 计算格式化后字符串的长度 - va_list argsCopy; - va_copy(argsCopy, args); - const int length = std::vsnprintf(nullptr, 0, fmt, argsCopy); - va_end(argsCopy); - // 分配足够的空间来存储格式化后的字符串 - const auto buffer = new char[length + 1]; - std::vsnprintf(buffer, length + 1, fmt, args); - va_end(args); - this->assign(buffer); - delete[] buffer; -} - Byte * CTL::String::toBytes() const { return (Byte*)this->data(); } @@ -72,23 +56,6 @@ double CTL::String::to_double() { return atof(data()); } -String String::format(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - // 计算格式化后字符串的长度 - va_list argsCopy; - va_copy(argsCopy, args); - const int length = std::vsnprintf(nullptr, 0, fmt, argsCopy); - va_end(argsCopy); - // 分配足够的空间来存储格式化后的字符串 - const auto buffer = new char[length + 1]; - std::vsnprintf(buffer, length + 1, fmt, args); - va_end(args); - // 创建 CCString 对象并释放缓冲区 - String result(buffer); - delete[] buffer; - return result; -} diff --git a/CMakeLists.txt b/CMakeLists.txt index 2342f2b3..1f7f6069 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,60 +5,24 @@ project(IPBS_NSSM) add_subdirectory(CC_SDK) set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(CMAKE_AUTOUIC ON) -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) - set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm|ARM|Armv[0-9]+") set(CMAKE_PREFIX_PATH "/home/xunb/Environment/ARM-Qt5.11.3") message(STATUS "Building for ARM") -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|i686") # 显式添加 x86 支持 +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|i686|AMD64") # 显式添加 x86 支持 set(CMAKE_PREFIX_PATH "/home/xunb/Environment/5.15.2/gcc_64") message(STATUS "Building for x86: ${CMAKE_PREFIX_PATH}") else() message(FATAL_ERROR "Unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}") endif() - -# QtCreator supports the following variables for Android, which are identical to qmake Android variables. -# Check http://doc.qt.io/qt-5/deployment-android.html for more information. -# They need to be set before the find_package(Qt5 ...) call. - -#if(ANDROID) -# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") -# if (ANDROID_ABI STREQUAL "armeabi-v7a") -# set(ANDROID_EXTRA_LIBS -# ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libcrypto.so -# ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libssl.so) -# endif() -#endif() -set(Qt5_DIR "${CMAKE_PREFIX_PATH}/lib/cmake/Qt5") # 关键修复 -find_package(Qt5 COMPONENTS Widgets REQUIRED) -message(STATUS "Qt5Widgets_LIBRARIES = ${Qt5Widgets_LIBRARIES}") -if(ANDROID) - add_library(IPBS_NSSM SHARED - main.cpp - ) -else() - add_executable(IPBS_NSSM - # WIN32 - main.cpp - ) -endif() +add_executable(IPBS_NSSM + main.cpp +) target_include_directories(IPBS_NSSM PUBLIC ${CC_API_INC}) -target_link_libraries(IPBS_NSSM PRIVATE Qt5::Widgets CC_API) +target_link_libraries(IPBS_NSSM PRIVATE CC_API) -#if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm|ARM|Armv[0-9]+") -# target_link_libraries(IPBS_NSSM PRIVATE Qt5::Widgets CC_API) -#else () -# target_link_libraries(IPBS_NSSM PRIVATE -# ${CMAKE_PREFIX_PATH}/lib/libQt5Widgets.so.5.15.2 -# ${CMAKE_PREFIX_PATH}/lib/libQt5Core.so.5.15.2 -# CC_API -# ) -#endif () diff --git a/main.cpp b/main.cpp index caed552b..99a3cf23 100644 --- a/main.cpp +++ b/main.cpp @@ -1,14 +1,10 @@ #include -#include -#include -#include #include #include "CCThread.h" -#include "QProcess" -#include "QSharedMemory" #include - #include "CCSystem.h" +#include "CCApplication.h" +#include "CCProcess.h" #ifdef _WIN32 #include @@ -81,7 +77,7 @@ bool IsProcessRunning(const std::string& processName) { #endif } -static bool Flag = true; +inline bool Flag = true; bool CloseConnect() { Flag = false; @@ -94,28 +90,26 @@ int main(int argc, char *argv[]) { if(argc < 3){ return -2; } - std::cout << argv[0] << std::endl; - std::cout << argv[1] << std::endl; - std::cout << argv[2] << std::endl; - std::cout << argv[3] << std::endl; - static auto *shareMem = new QSharedMemory(argv[1]); //创建“SingleApp”的共享内存块 - if (!shareMem->create(1)){ //创建大小1b的内存 - CTL::System::Println("创建共享内存失败"); - delete shareMem; + if(!CTL::Application::IsSingleInstance()){ return -1; } - QCoreApplication a(argc, argv); + CTL::Application app(argc, argv); +// std::cout << argv[0] << std::endl; +// std::cout << argv[1] << std::endl; // 守护服务进程名称 +// std::cout << argv[2] << std::endl; // 进程名称 +// std::cout << argv[3] << std::endl; // 启动路径 + CTL::System::Println("Start Daemon {}",argv[2]); CC::SetCloseFun(CloseConnect); while (Flag){ bool F = IsProcessRunning(argv[2]); // CTL::System::Println("IsProcessRunning %d",F ? 1 : 0); if(!F){ - QProcess::startDetached(argv[3]); + CTL::Process process; + process.Command(argv[2]); + process.Start(); + process.Stop(); } - CTL::Thread::Sleep(1000 * 1000 * 5); - + CTL::Thread::SleepMS(5 * 1000); } - // shareMem->detach(); - // return QCoreApplication::exec(); - return 0; + return CTL::Application::Running(&app); }