├── .gitignore ├── .vscode ├── c_cpp_properties.json ├── launch.json ├── settings.json └── tasks.json ├── 1704592362012.yml ├── 3rdparty └── rga │ ├── .DS_Store │ ├── .gitignore │ └── RK3588 │ ├── .DS_Store │ ├── include │ ├── GrallocOps.h │ ├── RgaApi.h │ ├── RgaMutex.h │ ├── RgaSingleton.h │ ├── RgaUtils.h │ ├── RockchipRga.h │ ├── drmrga.h │ ├── im2d.h │ ├── im2d.hpp │ ├── im2d_buffer.h │ ├── im2d_common.h │ ├── im2d_expand.h │ ├── im2d_mpi.h │ ├── im2d_single.h │ ├── im2d_task.h │ ├── im2d_type.h │ ├── im2d_version.h │ └── rga.h │ └── lib │ ├── .gitignore │ └── Linux │ └── aarch64 │ ├── librga.a │ ├── librga.a_1.9.0 │ ├── librga.so │ └── librga.so_1.9.0 ├── CMakeLists.txt ├── README ├── copy_mpp_libs.sh ├── include ├── bo.h ├── dev.h ├── drm_display.h ├── modeset.h ├── mpp_api.h └── screen_test.h ├── librknn_api ├── aarch64 │ └── librknnrt.so ├── armhf │ └── librknnrt.so └── include │ ├── rknn_api.h │ └── rknn_matmul_api.h ├── mpp_inc ├── mpp_buffer.h ├── mpp_compat.h ├── mpp_err.h ├── mpp_frame.h ├── mpp_log.h ├── mpp_log_def.h ├── mpp_meta.h ├── mpp_packet.h ├── mpp_rc_api.h ├── mpp_rc_defs.h ├── mpp_task.h ├── rk_hdr_meta_com.h ├── rk_mpi.h ├── rk_mpi_cmd.h ├── rk_type.h ├── rk_vdec_cfg.h ├── rk_vdec_cmd.h ├── rk_venc_cfg.h ├── rk_venc_cmd.h ├── rk_venc_rc.h ├── rk_venc_ref.h ├── vpu.h └── vpu_api.h ├── mpp_libs ├── libmk_api.so └── libutils.a ├── rtsp.list ├── src ├── bo.c ├── coco_80_labels_list.txt ├── dev.c ├── draw │ ├── cv_draw.cpp │ └── cv_draw.h ├── engine │ ├── engine.h │ ├── rknn_engine.cpp │ └── rknn_engine.h ├── media │ ├── ffmpeg_source.cpp │ ├── media_buffer.cpp │ ├── media_buffer.h │ ├── mpi_dec.cpp │ ├── mpi_dec.h │ ├── mpi_enc.cpp │ ├── nn_media.cpp │ ├── nn_media.h │ ├── zlmedia_worker.cpp │ └── zlmedia_worker.h ├── modeset.c ├── mpp_api.cpp ├── process │ ├── postprocess.cpp │ ├── postprocess.h │ ├── preprocess.cpp │ └── preprocess.h ├── rkmedia │ ├── drm_func.h │ ├── rga_func.h │ └── utils │ │ ├── drawing.cpp │ │ ├── drawing.h │ │ ├── mpp_decoder.cpp │ │ ├── mpp_decoder.h │ │ ├── mpp_encoder.cpp │ │ └── mpp_encoder.h ├── rtsp_pool.cpp ├── rtsp_single.cpp ├── screen_test.cpp ├── task │ ├── yolov8_custom.cpp │ ├── yolov8_custom.h │ ├── yolov8_thread_pool.cpp │ └── yolov8_thread_pool.h ├── types │ ├── datatype.h │ ├── error.h │ ├── media_dtype.h │ └── yolo_datatype.h ├── utils │ ├── engine_helper.h │ └── logging.h ├── x11_screen_driver.cpp └── yolov8_stream_pool.cxx └── weights └── yolov8s.float.rknn /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | vscode 3 | submodules -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Linux", 5 | "includePath": [ 6 | "${workspaceFolder}/**", 7 | "3rdparty/rga/RK3588/include", 8 | "/usr/include/opencv4", 9 | "submodules/ZLMediaKit/api/include", 10 | ], 11 | "defines": [], 12 | "compilerPath": "/usr/bin/gcc", 13 | "cStandard": "c17", 14 | "cppStandard": "gnu++17", 15 | "intelliSenseMode": "linux-gcc-arm64" 16 | } 17 | ], 18 | "version": 4 19 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "CMake调试", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/build/rknn_engine_test", // 编译后的程序,需要结合CMakeLists.txt中的add_executable()函数 12 | "args": [ 13 | "./weights/mobilenet_v1.rknn", 14 | "./images/dog_224x224.jpg" 15 | ], 16 | "stopAtEntry": false, 17 | "cwd": "${workspaceFolder}", 18 | "environment": [], 19 | "externalConsole": false, 20 | "MIMode": "gdb", 21 | "miDebuggerPath": "/usr/bin/gdb", 22 | "setupCommands": [ 23 | { 24 | "description": "Enable pretty-printing for gdb", 25 | "text": "-enable-pretty-printing", 26 | "ignoreFailures": true 27 | } 28 | ], 29 | "preLaunchTask": "CMake编译" 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "vector": "cpp", 4 | "array": "cpp", 5 | "atomic": "cpp", 6 | "bit": "cpp", 7 | "*.tcc": "cpp", 8 | "cctype": "cpp", 9 | "chrono": "cpp", 10 | "clocale": "cpp", 11 | "cmath": "cpp", 12 | "compare": "cpp", 13 | "complex": "cpp", 14 | "concepts": "cpp", 15 | "condition_variable": "cpp", 16 | "cstdarg": "cpp", 17 | "cstddef": "cpp", 18 | "cstdint": "cpp", 19 | "cstdio": "cpp", 20 | "cstdlib": "cpp", 21 | "cstring": "cpp", 22 | "ctime": "cpp", 23 | "cwchar": "cpp", 24 | "cwctype": "cpp", 25 | "deque": "cpp", 26 | "list": "cpp", 27 | "map": "cpp", 28 | "set": "cpp", 29 | "string": "cpp", 30 | "unordered_map": "cpp", 31 | "exception": "cpp", 32 | "algorithm": "cpp", 33 | "functional": "cpp", 34 | "iterator": "cpp", 35 | "memory": "cpp", 36 | "memory_resource": "cpp", 37 | "numeric": "cpp", 38 | "random": "cpp", 39 | "ratio": "cpp", 40 | "string_view": "cpp", 41 | "system_error": "cpp", 42 | "tuple": "cpp", 43 | "type_traits": "cpp", 44 | "utility": "cpp", 45 | "fstream": "cpp", 46 | "initializer_list": "cpp", 47 | "iomanip": "cpp", 48 | "iosfwd": "cpp", 49 | "iostream": "cpp", 50 | "istream": "cpp", 51 | "limits": "cpp", 52 | "mutex": "cpp", 53 | "new": "cpp", 54 | "numbers": "cpp", 55 | "ostream": "cpp", 56 | "semaphore": "cpp", 57 | "sstream": "cpp", 58 | "stdexcept": "cpp", 59 | "stop_token": "cpp", 60 | "streambuf": "cpp", 61 | "thread": "cpp", 62 | "cinttypes": "cpp", 63 | "typeindex": "cpp", 64 | "typeinfo": "cpp", 65 | "bitset": "cpp", 66 | "regex": "cpp", 67 | "csignal": "cpp", 68 | "unordered_set": "cpp" 69 | }, 70 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | // cmake配置 6 | "type": "cppbuild", 7 | "label": "CMake配置", 8 | "command": "cmake", // cmake命令 9 | "args": [ 10 | "-S .", // 源码目录 11 | "-B build", // 编译目录 12 | "-DCMAKE_BUILD_TYPE=Debug" // 编译类型 13 | ], 14 | "options": { 15 | "cwd": "${workspaceFolder}" // 工作目录 16 | }, 17 | "problemMatcher": [ 18 | "$gcc" 19 | ], 20 | "group": "build", 21 | }, 22 | { 23 | // cmake编译 24 | "type": "cppbuild", 25 | "label": "CMake编译", 26 | "command": "cmake", // cmake命令 27 | "args": [ 28 | "--build", // 编译 29 | "build", // 编译目录 30 | ], 31 | "options": { 32 | "cwd": "${workspaceFolder}" // 工作目录 33 | }, 34 | "problemMatcher": [ 35 | "$gcc" 36 | ], 37 | "group": "build", 38 | "dependsOn": [ 39 | "CMake配置" // 依赖CMake配置,先执行CMake配置 40 | ] 41 | }, 42 | { 43 | // 删除build目录 44 | "type": "shell", 45 | "label": "删除build目录", 46 | "command": "rm -rf build", 47 | "options": { 48 | "cwd": "${workspaceFolder}" // 工作目录 49 | }, 50 | "problemMatcher": [ 51 | "$gcc" 52 | ], 53 | "group": "build", 54 | 55 | 56 | } 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /3rdparty/rga/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MontaukLaw/3588_multi_rtsp_decode/91405545382f0ab3e18f4669e7c819e0281180bd/3rdparty/rga/.DS_Store -------------------------------------------------------------------------------- /3rdparty/rga/.gitignore: -------------------------------------------------------------------------------- 1 | RK356X 2 | RV110X -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MontaukLaw/3588_multi_rtsp_decode/91405545382f0ab3e18f4669e7c819e0281180bd/3rdparty/rga/RK3588/.DS_Store -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/GrallocOps.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Zhiqin Wei 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _rk_graphic_buffer_h_ 20 | #define _rk_graphic_buffer_h_ 21 | 22 | #ifdef ANDROID 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | #include "drmrga.h" 49 | #include "rga.h" 50 | 51 | // ------------------------------------------------------------------------------- 52 | int RkRgaGetHandleFd(buffer_handle_t handle, int *fd); 53 | int RkRgaGetHandleAttributes(buffer_handle_t handle, 54 | std::vector *attrs); 55 | int RkRgaGetHandleMapAddress(buffer_handle_t handle, 56 | void **buf); 57 | #endif //Android 58 | 59 | #endif //_rk_graphic_buffer_h_ 60 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/RgaApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Zhiqin Wei 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _rockchip_rga_c_h_ 19 | #define _rockchip_rga_c_h_ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | #include 32 | 33 | #include "drmrga.h" 34 | #include "rga.h" 35 | 36 | #ifdef __cplusplus 37 | extern "C"{ 38 | #endif 39 | 40 | /* 41 | * Compatible with the old version of C interface.The new 42 | * version of the C interface no longer requires users to 43 | * initialize rga, so RgaInit and RgaDeInit are just for 44 | * compatibility with the old C interface, so please do 45 | * not use ctx, because it is usually a NULL. 46 | */ 47 | #define RgaInit(ctx) ({ \ 48 | int ret = 0; \ 49 | ret = c_RkRgaInit(); \ 50 | c_RkRgaGetContext(ctx); \ 51 | ret;\ 52 | }) 53 | #define RgaDeInit(ctx) { \ 54 | (void)ctx; /* unused */ \ 55 | c_RkRgaDeInit(); \ 56 | } 57 | #define RgaBlit(...) c_RkRgaBlit(__VA_ARGS__) 58 | #define RgaCollorFill(...) c_RkRgaColorFill(__VA_ARGS__) 59 | #define RgaFlush() c_RkRgaFlush() 60 | 61 | int c_RkRgaInit(); 62 | void c_RkRgaDeInit(); 63 | void c_RkRgaGetContext(void **ctx); 64 | int c_RkRgaBlit(rga_info_t *src, rga_info_t *dst, rga_info_t *src1); 65 | int c_RkRgaColorFill(rga_info_t *dst); 66 | int c_RkRgaFlush(); 67 | 68 | #ifndef ANDROID /* linux */ 69 | int c_RkRgaGetAllocBuffer(bo_t *bo_info, int width, int height, int bpp); 70 | int c_RkRgaGetAllocBufferCache(bo_t *bo_info, int width, int height, int bpp); 71 | int c_RkRgaGetMmap(bo_t *bo_info); 72 | int c_RkRgaUnmap(bo_t *bo_info); 73 | int c_RkRgaFree(bo_t *bo_info); 74 | int c_RkRgaGetBufferFd(bo_t *bo_info, int *fd); 75 | #endif /* #ifndef ANDROID */ 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif /* #ifndef _rockchip_rga_c_h_ */ 82 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/RgaMutex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * PutinLee 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | 20 | #ifndef _LIBS_RGA_MUTEX_H 21 | #define _LIBS_RGA_MUTEX_H 22 | 23 | #ifndef ANDROID 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | 31 | // Enable thread safety attributes only with clang. 32 | // The attributes can be safely erased when compiling with other compilers. 33 | #if defined(__clang__) && (!defined(SWIG)) 34 | #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) 35 | #else 36 | #define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op 37 | #endif 38 | 39 | #define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) 40 | 41 | #define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) 42 | 43 | #define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) 44 | 45 | #define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) 46 | 47 | #define ACQUIRED_BEFORE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) 48 | 49 | #define ACQUIRED_AFTER(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) 50 | 51 | #define REQUIRES(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__)) 52 | 53 | #define REQUIRES_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__)) 54 | 55 | #define ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__)) 56 | 57 | #define ACQUIRE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__)) 58 | 59 | #define RELEASE(...) THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__)) 60 | 61 | #define RELEASE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) 62 | 63 | #define TRY_ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) 64 | 65 | #define TRY_ACQUIRE_SHARED(...) \ 66 | THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__)) 67 | 68 | #define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) 69 | 70 | #define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) 71 | 72 | #define ASSERT_SHARED_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) 73 | 74 | #define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) 75 | 76 | #define NO_THREAD_SAFETY_ANALYSIS THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) 77 | 78 | class Condition; 79 | 80 | /* 81 | * NOTE: This class is for code that builds on Win32. Its usage is 82 | * deprecated for code which doesn't build for Win32. New code which 83 | * doesn't build for Win32 should use std::mutex and std::lock_guard instead. 84 | * 85 | * Simple mutex class. The implementation is system-dependent. 86 | * 87 | * The mutex must be unlocked by the thread that locked it. They are not 88 | * recursive, i.e. the same thread can't lock it multiple times. 89 | */ 90 | class CAPABILITY("mutex") Mutex { 91 | public: 92 | enum { 93 | PRIVATE = 0, 94 | SHARED = 1 95 | }; 96 | 97 | Mutex(); 98 | explicit Mutex(const char* name); 99 | explicit Mutex(int type, const char* name = nullptr); 100 | ~Mutex(); 101 | 102 | // lock or unlock the mutex 103 | int32_t lock() ACQUIRE(); 104 | void unlock() RELEASE(); 105 | 106 | // lock if possible; returns 0 on success, error otherwise 107 | int32_t tryLock() TRY_ACQUIRE(0); 108 | 109 | int32_t timedLock(int64_t timeoutNs) TRY_ACQUIRE(0); 110 | 111 | // Manages the mutex automatically. It'll be locked when Autolock is 112 | // constructed and released when Autolock goes out of scope. 113 | class SCOPED_CAPABILITY Autolock { 114 | public: 115 | inline explicit Autolock(Mutex& mutex) ACQUIRE(mutex) : mLock(mutex) { 116 | mLock.lock(); 117 | } 118 | inline explicit Autolock(Mutex* mutex) ACQUIRE(mutex) : mLock(*mutex) { 119 | mLock.lock(); 120 | } 121 | inline ~Autolock() RELEASE() { 122 | mLock.unlock(); 123 | } 124 | 125 | private: 126 | Mutex& mLock; 127 | // Cannot be copied or moved - declarations only 128 | Autolock(const Autolock&); 129 | Autolock& operator=(const Autolock&); 130 | }; 131 | 132 | private: 133 | friend class Condition; 134 | 135 | // A mutex cannot be copied 136 | Mutex(const Mutex&); 137 | Mutex& operator=(const Mutex&); 138 | 139 | pthread_mutex_t mMutex; 140 | }; 141 | 142 | // --------------------------------------------------------------------------- 143 | inline Mutex::Mutex() { 144 | pthread_mutex_init(&mMutex, nullptr); 145 | } 146 | inline Mutex::Mutex(__attribute__((unused)) const char* name) { 147 | pthread_mutex_init(&mMutex, nullptr); 148 | } 149 | inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) { 150 | if (type == SHARED) { 151 | pthread_mutexattr_t attr; 152 | pthread_mutexattr_init(&attr); 153 | pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 154 | pthread_mutex_init(&mMutex, &attr); 155 | pthread_mutexattr_destroy(&attr); 156 | } else { 157 | pthread_mutex_init(&mMutex, nullptr); 158 | } 159 | } 160 | inline Mutex::~Mutex() { 161 | pthread_mutex_destroy(&mMutex); 162 | } 163 | inline int32_t Mutex::lock() { 164 | return -pthread_mutex_lock(&mMutex); 165 | } 166 | inline void Mutex::unlock() { 167 | pthread_mutex_unlock(&mMutex); 168 | } 169 | inline int32_t Mutex::tryLock() { 170 | return -pthread_mutex_trylock(&mMutex); 171 | } 172 | inline int32_t Mutex::timedLock(int64_t timeoutNs) { 173 | timespec now; 174 | clock_gettime(CLOCK_REALTIME, &now); 175 | timeoutNs += now.tv_sec*1000000000 + now.tv_nsec; 176 | const struct timespec ts = { 177 | /* .tv_sec = */ static_cast(timeoutNs / 1000000000), 178 | /* .tv_nsec = */ static_cast(timeoutNs % 1000000000), 179 | }; 180 | return -pthread_mutex_timedlock(&mMutex, &ts); 181 | } 182 | 183 | // --------------------------------------------------------------------------- 184 | 185 | /* 186 | * Automatic mutex. Declare one of these at the top of a function. 187 | * When the function returns, it will go out of scope, and release the 188 | * mutex. 189 | */ 190 | 191 | typedef Mutex::Autolock AutoMutex; 192 | #endif // __ANDROID_VNDK__ 193 | #endif // _LIBS_RGA_MUTEX_H 194 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/RgaSingleton.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Zhiqin Wei 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _LIBS_RGA_SINGLETON_H 20 | #define _LIBS_RGA_SINGLETON_H 21 | 22 | #ifndef ANDROID 23 | #include "RgaMutex.h" 24 | 25 | #if defined(__clang__) 26 | #pragma clang diagnostic push 27 | #pragma clang diagnostic ignored "-Wundefined-var-template" 28 | #endif 29 | 30 | template 31 | class Singleton { 32 | public: 33 | static TYPE& getInstance() { 34 | Mutex::Autolock _l(sLock); 35 | TYPE* instance = sInstance; 36 | if (instance == nullptr) { 37 | instance = new TYPE(); 38 | sInstance = instance; 39 | } 40 | return *instance; 41 | } 42 | 43 | static bool hasInstance() { 44 | Mutex::Autolock _l(sLock); 45 | return sInstance != nullptr; 46 | } 47 | 48 | protected: 49 | ~Singleton() { } 50 | Singleton() { } 51 | 52 | private: 53 | Singleton(const Singleton&); 54 | Singleton& operator = (const Singleton&); 55 | static Mutex sLock; 56 | static TYPE* sInstance; 57 | }; 58 | 59 | #if defined(__clang__) 60 | #pragma clang diagnostic pop 61 | #endif 62 | 63 | #define RGA_SINGLETON_STATIC_INSTANCE(TYPE) \ 64 | template<> ::Mutex \ 65 | (::Singleton< TYPE >::sLock)(::Mutex::PRIVATE); \ 66 | template<> TYPE* ::Singleton< TYPE >::sInstance(nullptr); /* NOLINT */ \ 67 | template class ::Singleton< TYPE >; 68 | 69 | #endif //ANDROID 70 | #endif //_LIBS_RGA_SINGLETON_H 71 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/RgaUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Zhiqin Wei 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _rga_utils_h_ 20 | #define _rga_utils_h_ 21 | 22 | // ------------------------------------------------------------------------------- 23 | float get_bpp_from_format(int format); 24 | int get_perPixel_stride_from_format(int format); 25 | int get_buf_from_file(void *buf, int f, int sw, int sh, int index); 26 | int output_buf_data_to_file(void *buf, int f, int sw, int sh, int index); 27 | const char *translate_format_str(int format); 28 | int get_buf_from_file_FBC(void *buf, int f, int sw, int sh, int index); 29 | int output_buf_data_to_file_FBC(void *buf, int f, int sw, int sh, int index); 30 | #endif 31 | 32 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/RockchipRga.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Zhiqin Wei 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _rockchip_rga_h_ 20 | #define _rockchip_rga_h_ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "drmrga.h" 34 | #include "GrallocOps.h" 35 | #include "RgaUtils.h" 36 | #include "rga.h" 37 | 38 | ////////////////////////////////////////////////////////////////////////////////// 39 | #ifndef ANDROID 40 | #include "RgaSingleton.h" 41 | #endif 42 | 43 | #ifdef ANDROID 44 | #include 45 | #include 46 | #include 47 | 48 | namespace android { 49 | #endif 50 | 51 | class RockchipRga :public Singleton { 52 | public: 53 | 54 | static inline RockchipRga& get() { 55 | return getInstance(); 56 | } 57 | 58 | int RkRgaInit(); 59 | void RkRgaDeInit(); 60 | void RkRgaGetContext(void **ctx); 61 | #ifndef ANDROID /* LINUX */ 62 | int RkRgaAllocBuffer(int drm_fd /* input */, bo_t *bo_info, 63 | int width, int height, int bpp, int flags); 64 | int RkRgaFreeBuffer(int drm_fd /* input */, bo_t *bo_info); 65 | int RkRgaGetAllocBuffer(bo_t *bo_info, int width, int height, int bpp); 66 | int RkRgaGetAllocBufferExt(bo_t *bo_info, int width, int height, int bpp, int flags); 67 | int RkRgaGetAllocBufferCache(bo_t *bo_info, int width, int height, int bpp); 68 | int RkRgaGetMmap(bo_t *bo_info); 69 | int RkRgaUnmap(bo_t *bo_info); 70 | int RkRgaFree(bo_t *bo_info); 71 | int RkRgaGetBufferFd(bo_t *bo_info, int *fd); 72 | #else 73 | int RkRgaGetBufferFd(buffer_handle_t handle, int *fd); 74 | int RkRgaGetHandleMapCpuAddress(buffer_handle_t handle, void **buf); 75 | #endif 76 | int RkRgaBlit(rga_info *src, rga_info *dst, rga_info *src1); 77 | int RkRgaCollorFill(rga_info *dst); 78 | int RkRgaCollorPalette(rga_info *src, rga_info *dst, rga_info *lut); 79 | int RkRgaFlush(); 80 | 81 | 82 | void RkRgaSetLogOnceFlag(int log) { 83 | mLogOnce = log; 84 | } 85 | void RkRgaSetAlwaysLogFlag(bool log) { 86 | mLogAlways = log; 87 | } 88 | void RkRgaLogOutRgaReq(struct rga_req rgaReg); 89 | int RkRgaLogOutUserPara(rga_info *rgaInfo); 90 | inline bool RkRgaIsReady() { 91 | return mSupportRga; 92 | } 93 | 94 | RockchipRga(); 95 | ~RockchipRga(); 96 | private: 97 | bool mSupportRga; 98 | int mLogOnce; 99 | int mLogAlways; 100 | void * mContext; 101 | 102 | friend class Singleton; 103 | }; 104 | 105 | #ifdef ANDROID 106 | }; // namespace android 107 | #endif 108 | 109 | #endif 110 | 111 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/im2d.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * PutinLee 5 | * Cerf Yu 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | #ifndef _im2d_h_ 21 | #define _im2d_h_ 22 | 23 | #include "im2d_version.h" 24 | #include "im2d_type.h" 25 | 26 | #include "im2d_common.h" 27 | #include "im2d_buffer.h" 28 | #include "im2d_single.h" 29 | #include "im2d_task.h" 30 | #include "im2d_mpi.h" 31 | 32 | #endif /* #ifndef _im2d_h_ */ 33 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/im2d.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * PutinLee 5 | * Cerf Yu 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | #ifndef _im2d_hpp_ 20 | #define _im2d_hpp_ 21 | 22 | #include "im2d.h" 23 | #include "im2d_expand.h" 24 | 25 | #endif /* #ifndef _im2d_hpp_ */ 26 | 27 | 28 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/im2d_buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Cerf Yu 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _im2d_buffer_h_ 19 | #define _im2d_buffer_h_ 20 | 21 | #include "im2d_type.h" 22 | 23 | /** 24 | * Import external buffers into RGA driver. 25 | * 26 | * @param fd/va/pa 27 | * Select dma_fd/virtual_address/physical_address by buffer type 28 | * @param size 29 | * Describes the size of the image buffer 30 | * 31 | * @return rga_buffer_handle_t 32 | */ 33 | #ifdef __cplusplus 34 | IM_API rga_buffer_handle_t importbuffer_fd(int fd, int size); 35 | IM_API rga_buffer_handle_t importbuffer_virtualaddr(void *va, int size); 36 | IM_API rga_buffer_handle_t importbuffer_physicaladdr(uint64_t pa, int size); 37 | #endif 38 | 39 | /** 40 | * Import external buffers into RGA driver. 41 | * 42 | * @param fd/va/pa 43 | * Select dma_fd/virtual_address/physical_address by buffer type 44 | * @param width 45 | * Describes the pixel width stride of the image buffer 46 | * @param height 47 | * Describes the pixel height stride of the image buffer 48 | * @param format 49 | * Describes the pixel format of the image buffer 50 | * 51 | * @return rga_buffer_handle_t 52 | */ 53 | #ifdef __cplusplus 54 | IM_API rga_buffer_handle_t importbuffer_fd(int fd, int width, int height, int format); 55 | IM_API rga_buffer_handle_t importbuffer_virtualaddr(void *va, int width, int height, int format); 56 | IM_API rga_buffer_handle_t importbuffer_physicaladdr(uint64_t pa, int width, int height, int format); 57 | #endif 58 | 59 | /** 60 | * Import external buffers into RGA driver. 61 | * 62 | * @param fd/va/pa 63 | * Select dma_fd/virtual_address/physical_address by buffer type 64 | * @param param 65 | * Configure buffer parameters 66 | * 67 | * @return rga_buffer_handle_t 68 | */ 69 | IM_EXPORT_API rga_buffer_handle_t importbuffer_fd(int fd, im_handle_param_t *param); 70 | IM_EXPORT_API rga_buffer_handle_t importbuffer_virtualaddr(void *va, im_handle_param_t *param); 71 | IM_EXPORT_API rga_buffer_handle_t importbuffer_physicaladdr(uint64_t pa, im_handle_param_t *param); 72 | 73 | /** 74 | * Import external buffers into RGA driver. 75 | * 76 | * @param handle 77 | * rga buffer handle 78 | * 79 | * @return success or else negative error code. 80 | */ 81 | IM_EXPORT_API IM_STATUS releasebuffer_handle(rga_buffer_handle_t handle); 82 | 83 | /** 84 | * Wrap image Parameters. 85 | * 86 | * @param handle/virtualaddr/physicaladdr/fd 87 | * RGA buffer handle/virtualaddr/physicaladdr/fd. 88 | * @param width 89 | * Width of image manipulation area. 90 | * @param height 91 | * Height of image manipulation area. 92 | * @param wstride 93 | * Width pixel stride, default (width = wstride). 94 | * @param hstride 95 | * Height pixel stride, default (height = hstride). 96 | * @param format 97 | * Image format. 98 | * 99 | * @return rga_buffer_t 100 | */ 101 | #define wrapbuffer_handle(handle, width, height, format, ...) \ 102 | ({ \ 103 | rga_buffer_t im2d_api_buffer; \ 104 | int __args[] = {__VA_ARGS__}; \ 105 | int __argc = sizeof(__args)/sizeof(int); \ 106 | if (__argc == 0) { \ 107 | im2d_api_buffer = wrapbuffer_handle_t(handle, width, height, width, height, format); \ 108 | } else if (__argc == 2){ \ 109 | im2d_api_buffer = wrapbuffer_handle_t(handle, width, height, __args[0], __args[1], format); \ 110 | } else { \ 111 | memset(&im2d_api_buffer, 0x0, sizeof(im2d_api_buffer)); \ 112 | printf("invalid parameter\n"); \ 113 | } \ 114 | im2d_api_buffer; \ 115 | }) 116 | 117 | #define wrapbuffer_virtualaddr(vir_addr, width, height, format, ...) \ 118 | ({ \ 119 | rga_buffer_t im2d_api_buffer; \ 120 | int __args[] = {__VA_ARGS__}; \ 121 | int __argc = sizeof(__args)/sizeof(int); \ 122 | if (__argc == 0) { \ 123 | im2d_api_buffer = wrapbuffer_virtualaddr_t(vir_addr, width, height, width, height, format); \ 124 | } else if (__argc == 2){ \ 125 | im2d_api_buffer = wrapbuffer_virtualaddr_t(vir_addr, width, height, __args[0], __args[1], format); \ 126 | } else { \ 127 | memset(&im2d_api_buffer, 0x0, sizeof(im2d_api_buffer)); \ 128 | printf("invalid parameter\n"); \ 129 | } \ 130 | im2d_api_buffer; \ 131 | }) 132 | 133 | #define wrapbuffer_physicaladdr(phy_addr, width, height, format, ...) \ 134 | ({ \ 135 | rga_buffer_t im2d_api_buffer; \ 136 | int __args[] = {__VA_ARGS__}; \ 137 | int __argc = sizeof(__args)/sizeof(int); \ 138 | if (__argc == 0) { \ 139 | im2d_api_buffer = wrapbuffer_physicaladdr_t(phy_addr, width, height, width, height, format); \ 140 | } else if (__argc == 2){ \ 141 | im2d_api_buffer = wrapbuffer_physicaladdr_t(phy_addr, width, height, __args[0], __args[1], format); \ 142 | } else { \ 143 | memset(&im2d_api_buffer, 0x0, sizeof(im2d_api_buffer)); \ 144 | printf("invalid parameter\n"); \ 145 | } \ 146 | im2d_api_buffer; \ 147 | }) 148 | 149 | #define wrapbuffer_fd(fd, width, height, format, ...) \ 150 | ({ \ 151 | rga_buffer_t im2d_api_buffer; \ 152 | int __args[] = {__VA_ARGS__}; \ 153 | int __argc = sizeof(__args)/sizeof(int); \ 154 | if (__argc == 0) { \ 155 | im2d_api_buffer = wrapbuffer_fd_t(fd, width, height, width, height, format); \ 156 | } else if (__argc == 2){ \ 157 | im2d_api_buffer = wrapbuffer_fd_t(fd, width, height, __args[0], __args[1], format); \ 158 | } else { \ 159 | memset(&im2d_api_buffer, 0x0, sizeof(im2d_api_buffer)); \ 160 | printf("invalid parameter\n"); \ 161 | } \ 162 | im2d_api_buffer; \ 163 | }) 164 | /* Symbols for define *_t functions */ 165 | IM_C_API rga_buffer_t wrapbuffer_handle_t(rga_buffer_handle_t handle, int width, int height, int wstride, int hstride, int format); 166 | IM_C_API rga_buffer_t wrapbuffer_virtualaddr_t(void* vir_addr, int width, int height, int wstride, int hstride, int format); 167 | IM_C_API rga_buffer_t wrapbuffer_physicaladdr_t(void* phy_addr, int width, int height, int wstride, int hstride, int format); 168 | IM_C_API rga_buffer_t wrapbuffer_fd_t(int fd, int width, int height, int wstride, int hstride, int format); 169 | 170 | #ifdef __cplusplus 171 | #undef wrapbuffer_handle 172 | IM_API rga_buffer_t wrapbuffer_handle(rga_buffer_handle_t handle, 173 | int width, int height, int format); 174 | IM_API rga_buffer_t wrapbuffer_handle(rga_buffer_handle_t handle, 175 | int width, int height, int format, 176 | int wstride, int hstride); 177 | #endif 178 | 179 | #endif /* #ifndef _im2d_buffer_h_ */ 180 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/im2d_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Cerf Yu 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _im2d_common_h_ 19 | #define _im2d_common_h_ 20 | 21 | #include "im2d_type.h" 22 | 23 | /** 24 | * Query RGA basic information, supported resolution, supported format, etc. 25 | * 26 | * @param name 27 | * RGA_VENDOR 28 | * RGA_VERSION 29 | * RGA_MAX_INPUT 30 | * RGA_MAX_OUTPUT 31 | * RGA_INPUT_FORMAT 32 | * RGA_OUTPUT_FORMAT 33 | * RGA_EXPECTED 34 | * RGA_ALL 35 | * 36 | * @returns a string describing properties of RGA. 37 | */ 38 | IM_EXPORT_API const char* querystring(int name); 39 | 40 | /** 41 | * String to output the error message 42 | * 43 | * @param status 44 | * process result value. 45 | * 46 | * @returns error message. 47 | */ 48 | #define imStrError(...) \ 49 | ({ \ 50 | const char* im2d_api_err; \ 51 | int __args[] = {__VA_ARGS__}; \ 52 | int __argc = sizeof(__args)/sizeof(int); \ 53 | if (__argc == 0) { \ 54 | im2d_api_err = imStrError_t(IM_STATUS_INVALID_PARAM); \ 55 | } else if (__argc == 1){ \ 56 | im2d_api_err = imStrError_t((IM_STATUS)__args[0]); \ 57 | } else { \ 58 | im2d_api_err = ("Fatal error, imStrError() too many parameters\n"); \ 59 | printf("Fatal error, imStrError() too many parameters\n"); \ 60 | } \ 61 | im2d_api_err; \ 62 | }) 63 | IM_C_API const char* imStrError_t(IM_STATUS status); 64 | 65 | /** 66 | * check im2d api header file 67 | * 68 | * @param header_version 69 | * Default is RGA_CURRENT_API_HEADER_VERSION, no need to change if there are no special cases. 70 | * 71 | * @returns no error or else negative error code. 72 | */ 73 | #ifdef __cplusplus 74 | IM_API IM_STATUS imcheckHeader(im_api_version_t header_version = RGA_CURRENT_API_HEADER_VERSION); 75 | #endif 76 | 77 | /** 78 | * check RGA basic information, supported resolution, supported format, etc. 79 | * 80 | * @param src 81 | * @param dst 82 | * @param pat 83 | * @param src_rect 84 | * @param dst_rect 85 | * @param pat_rect 86 | * @param mode_usage 87 | * 88 | * @returns no error or else negative error code. 89 | */ 90 | #define imcheck(src, dst, src_rect, dst_rect, ...) \ 91 | ({ \ 92 | IM_STATUS __ret = IM_STATUS_NOERROR; \ 93 | rga_buffer_t __pat; \ 94 | im_rect __pat_rect; \ 95 | memset(&__pat, 0, sizeof(rga_buffer_t)); \ 96 | memset(&__pat_rect, 0, sizeof(im_rect)); \ 97 | int __args[] = {__VA_ARGS__}; \ 98 | int __argc = sizeof(__args)/sizeof(int); \ 99 | if (__argc == 0) { \ 100 | __ret = imcheck_t(src, dst, __pat, src_rect, dst_rect, __pat_rect, 0); \ 101 | } else if (__argc == 1){ \ 102 | __ret = imcheck_t(src, dst, __pat, src_rect, dst_rect, __pat_rect, __args[0]); \ 103 | } else { \ 104 | __ret = IM_STATUS_FAILED; \ 105 | printf("check failed\n"); \ 106 | } \ 107 | __ret; \ 108 | }) 109 | #define imcheck_composite(src, dst, pat, src_rect, dst_rect, pat_rect, ...) \ 110 | ({ \ 111 | IM_STATUS __ret = IM_STATUS_NOERROR; \ 112 | int __args[] = {__VA_ARGS__}; \ 113 | int __argc = sizeof(__args)/sizeof(int); \ 114 | if (__argc == 0) { \ 115 | __ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, 0); \ 116 | } else if (__argc == 1){ \ 117 | __ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, __args[0]); \ 118 | } else { \ 119 | __ret = IM_STATUS_FAILED; \ 120 | printf("check failed\n"); \ 121 | } \ 122 | __ret; \ 123 | }) 124 | IM_C_API IM_STATUS imcheck_t(const rga_buffer_t src, const rga_buffer_t dst, const rga_buffer_t pat, 125 | const im_rect src_rect, const im_rect dst_rect, const im_rect pat_rect, const int mode_usage); 126 | /* Compatible with the legacy symbol */ 127 | IM_C_API void rga_check_perpare(rga_buffer_t *src, rga_buffer_t *dst, rga_buffer_t *pat, 128 | im_rect *src_rect, im_rect *dst_rect, im_rect *pat_rect, int mode_usage); 129 | 130 | /** 131 | * block until all execution is complete 132 | * 133 | * @param release_fence_fd 134 | * RGA job release fence fd 135 | * 136 | * @returns success or else negative error code. 137 | */ 138 | IM_EXPORT_API IM_STATUS imsync(int release_fence_fd); 139 | 140 | /** 141 | * config 142 | * 143 | * @param name 144 | * enum IM_CONFIG_NAME 145 | * @param value 146 | * 147 | * @returns success or else negative error code. 148 | */ 149 | IM_EXPORT_API IM_STATUS imconfig(IM_CONFIG_NAME name, uint64_t value); 150 | 151 | #endif /* #ifndef _im2d_common_h_ */ 152 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/im2d_expand.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Cerf Yu 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _im2d_expand_h_ 19 | #define _im2d_expand_h_ 20 | 21 | #ifdef __cplusplus 22 | 23 | #include "im2d_type.h" 24 | 25 | // #if ANDROID 26 | 27 | // #include 28 | 29 | // using namespace android; 30 | 31 | // IM_API rga_buffer_handle_t importbuffer_GraphicBuffer_handle(buffer_handle_t hnd); 32 | // IM_API rga_buffer_handle_t importbuffer_GraphicBuffer(sp buf); 33 | 34 | // IM_API rga_buffer_t wrapbuffer_handle(buffer_handle_t hnd); 35 | // IM_API rga_buffer_t wrapbuffer_GraphicBuffer(sp buf); 36 | 37 | // #if USE_AHARDWAREBUFFER 38 | // #include 39 | // IM_API rga_buffer_handle_t importbuffer_AHardwareBuffer(AHardwareBuffer *buf); 40 | // IM_API rga_buffer_t wrapbuffer_AHardwareBuffer(AHardwareBuffer *buf); 41 | 42 | // #endif /* #if USE_AHARDWAREBUFFER */ 43 | // #endif /* #if ANDROID */ 44 | 45 | #endif /* #ifdef __cplusplus */ 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/im2d_mpi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Cerf Yu 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | #ifndef _im2d_mpi_hpp_ 19 | #define _im2d_mpi_hpp_ 20 | 21 | #include "im2d_type.h" 22 | 23 | /** 24 | * Create and config an rga ctx for rockit-ko 25 | * 26 | * @param flags 27 | * Some configuration flags for this job 28 | * 29 | * @returns job id. 30 | */ 31 | IM_EXPORT_API im_ctx_id_t imbegin(uint32_t flags); 32 | 33 | /** 34 | * Cancel and delete an rga ctx for rockit-ko 35 | * 36 | * @param flags 37 | * Some configuration flags for this job 38 | * 39 | * @returns success or else negative error code. 40 | */ 41 | IM_EXPORT_API IM_STATUS imcancel(im_ctx_id_t id); 42 | 43 | /** 44 | * process for rockit-ko 45 | * 46 | * @param src 47 | * The input source image and is also the foreground image in blend. 48 | * @param dst 49 | * The output destination image and is also the foreground image in blend. 50 | * @param pat 51 | * The foreground image, or a LUT table. 52 | * @param srect 53 | * The rectangle on the src channel image that needs to be processed. 54 | * @param drect 55 | * The rectangle on the dst channel image that needs to be processed. 56 | * @param prect 57 | * The rectangle on the pat channel image that needs to be processed. 58 | * @param acquire_fence_fd 59 | * @param release_fence_fd 60 | * @param opt 61 | * The image processing options configuration. 62 | * @param usage 63 | * The image processing usage. 64 | * @param ctx_id 65 | * ctx id 66 | * 67 | * @returns success or else negative error code. 68 | */ 69 | #ifdef __cplusplus 70 | IM_API IM_STATUS improcess(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat, 71 | im_rect srect, im_rect drect, im_rect prect, 72 | int acquire_fence_fd, int *release_fence_fd, 73 | im_opt_t *opt, int usage, im_ctx_id_t ctx_id); 74 | #endif 75 | IM_EXPORT_API IM_STATUS improcess_ctx(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat, 76 | im_rect srect, im_rect drect, im_rect prect, 77 | int acquire_fence_fd, int *release_fence_fd, 78 | im_opt_t *opt, int usage, im_ctx_id_t ctx_id); 79 | 80 | #endif /* #ifndef _im2d_mpi_hpp_ */ -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/im2d_version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Cerf Yu 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _RGA_IM2D_VERSION_H_ 20 | #define _RGA_IM2D_VERSION_H_ 21 | 22 | #define RGA_VERSION_STR_HELPER(x) #x 23 | #define RGA_VERSION_STR(x) RGA_VERSION_STR_HELPER(x) 24 | 25 | /* RGA im2d api verison */ 26 | #define RGA_API_MAJOR_VERSION 1 27 | #define RGA_API_MINOR_VERSION 9 28 | #define RGA_API_REVISION_VERSION 1 29 | #define RGA_API_BUILD_VERSION 4 30 | 31 | #define RGA_API_VERSION \ 32 | RGA_VERSION_STR(RGA_API_MAJOR_VERSION) "." \ 33 | RGA_VERSION_STR(RGA_API_MINOR_VERSION) "." \ 34 | RGA_VERSION_STR(RGA_API_REVISION_VERSION) "_[" \ 35 | RGA_VERSION_STR(RGA_API_BUILD_VERSION) "]" 36 | #define RGA_API_FULL_VERSION "rga_api version " RGA_API_VERSION 37 | 38 | /* For header file version verification */ 39 | #define RGA_CURRENT_API_VERSION (\ 40 | (RGA_API_MAJOR_VERSION & 0xff) << 24 | \ 41 | (RGA_API_MINOR_VERSION & 0xff) << 16 | \ 42 | (RGA_API_REVISION_VERSION & 0xff) << 8 | \ 43 | (RGA_API_BUILD_VERSION & 0xff)\ 44 | ) 45 | #define RGA_CURRENT_API_HEADER_VERSION RGA_CURRENT_API_VERSION 46 | 47 | #endif /* _RGA_IM2D_VERSION_H_ */ 48 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/include/rga.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Rockchip Electronics Co., Ltd. 3 | * Authors: 4 | * Zhiqin Wei 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _RGA_DRIVER_H_ 20 | #define _RGA_DRIVER_H_ 21 | 22 | 23 | #ifndef ENABLE 24 | #define ENABLE 1 25 | #endif 26 | 27 | #ifndef DISABLE 28 | #define DISABLE 0 29 | #endif 30 | 31 | #ifdef __cplusplus 32 | extern "C" 33 | { 34 | #endif 35 | 36 | /* In order to be compatible with RK_FORMAT_XX and HAL_PIXEL_FORMAT_XX, 37 | * RK_FORMAT_XX is shifted to the left by 8 bits to distinguish. */ 38 | typedef enum _Rga_SURF_FORMAT { 39 | RK_FORMAT_RGBA_8888 = 0x0 << 8, 40 | RK_FORMAT_RGBX_8888 = 0x1 << 8, 41 | RK_FORMAT_RGB_888 = 0x2 << 8, 42 | RK_FORMAT_BGRA_8888 = 0x3 << 8, 43 | RK_FORMAT_RGB_565 = 0x4 << 8, 44 | RK_FORMAT_RGBA_5551 = 0x5 << 8, 45 | RK_FORMAT_RGBA_4444 = 0x6 << 8, 46 | RK_FORMAT_BGR_888 = 0x7 << 8, 47 | 48 | RK_FORMAT_YCbCr_422_SP = 0x8 << 8, 49 | RK_FORMAT_YCbCr_422_P = 0x9 << 8, 50 | RK_FORMAT_YCbCr_420_SP = 0xa << 8, 51 | RK_FORMAT_YCbCr_420_P = 0xb << 8, 52 | 53 | RK_FORMAT_YCrCb_422_SP = 0xc << 8, 54 | RK_FORMAT_YCrCb_422_P = 0xd << 8, 55 | RK_FORMAT_YCrCb_420_SP = 0xe << 8, 56 | RK_FORMAT_YCrCb_420_P = 0xf << 8, 57 | 58 | RK_FORMAT_BPP1 = 0x10 << 8, 59 | RK_FORMAT_BPP2 = 0x11 << 8, 60 | RK_FORMAT_BPP4 = 0x12 << 8, 61 | RK_FORMAT_BPP8 = 0x13 << 8, 62 | 63 | RK_FORMAT_Y4 = 0x14 << 8, 64 | RK_FORMAT_YCbCr_400 = 0x15 << 8, 65 | 66 | RK_FORMAT_BGRX_8888 = 0x16 << 8, 67 | 68 | RK_FORMAT_YVYU_422 = 0x18 << 8, 69 | RK_FORMAT_YVYU_420 = 0x19 << 8, 70 | RK_FORMAT_VYUY_422 = 0x1a << 8, 71 | RK_FORMAT_VYUY_420 = 0x1b << 8, 72 | RK_FORMAT_YUYV_422 = 0x1c << 8, 73 | RK_FORMAT_YUYV_420 = 0x1d << 8, 74 | RK_FORMAT_UYVY_422 = 0x1e << 8, 75 | RK_FORMAT_UYVY_420 = 0x1f << 8, 76 | 77 | RK_FORMAT_YCbCr_420_SP_10B = 0x20 << 8, 78 | RK_FORMAT_YCrCb_420_SP_10B = 0x21 << 8, 79 | RK_FORMAT_YCbCr_422_SP_10B = 0x22 << 8, 80 | RK_FORMAT_YCrCb_422_SP_10B = 0x23 << 8, 81 | /* For compatibility with misspellings */ 82 | RK_FORMAT_YCbCr_422_10b_SP = RK_FORMAT_YCbCr_422_SP_10B, 83 | RK_FORMAT_YCrCb_422_10b_SP = RK_FORMAT_YCrCb_422_SP_10B, 84 | 85 | RK_FORMAT_BGR_565 = 0x24 << 8, 86 | RK_FORMAT_BGRA_5551 = 0x25 << 8, 87 | RK_FORMAT_BGRA_4444 = 0x26 << 8, 88 | 89 | RK_FORMAT_ARGB_8888 = 0x28 << 8, 90 | RK_FORMAT_XRGB_8888 = 0x29 << 8, 91 | RK_FORMAT_ARGB_5551 = 0x2a << 8, 92 | RK_FORMAT_ARGB_4444 = 0x2b << 8, 93 | RK_FORMAT_ABGR_8888 = 0x2c << 8, 94 | RK_FORMAT_XBGR_8888 = 0x2d << 8, 95 | RK_FORMAT_ABGR_5551 = 0x2e << 8, 96 | RK_FORMAT_ABGR_4444 = 0x2f << 8, 97 | 98 | RK_FORMAT_RGBA2BPP = 0x30 << 8, 99 | 100 | RK_FORMAT_UNKNOWN = 0x100 << 8, 101 | } RgaSURF_FORMAT; 102 | 103 | enum { 104 | yuv2rgb_mode0 = 0x0, /* BT.601 MPEG */ 105 | yuv2rgb_mode1 = 0x1, /* BT.601 JPEG */ 106 | yuv2rgb_mode2 = 0x2, /* BT.709 */ 107 | 108 | rgb2yuv_601_full = 0x1 << 8, 109 | rgb2yuv_709_full = 0x2 << 8, 110 | yuv2yuv_601_limit_2_709_limit = 0x3 << 8, 111 | yuv2yuv_601_limit_2_709_full = 0x4 << 8, 112 | yuv2yuv_709_limit_2_601_limit = 0x5 << 8, 113 | yuv2yuv_709_limit_2_601_full = 0x6 << 8, //not support 114 | yuv2yuv_601_full_2_709_limit = 0x7 << 8, 115 | yuv2yuv_601_full_2_709_full = 0x8 << 8, //not support 116 | yuv2yuv_709_full_2_601_limit = 0x9 << 8, //not support 117 | yuv2yuv_709_full_2_601_full = 0xa << 8, //not support 118 | full_csc_mask = 0xf00, 119 | }; 120 | 121 | enum { 122 | RGA3_SCHEDULER_CORE0 = 1 << 0, 123 | RGA3_SCHEDULER_CORE1 = 1 << 1, 124 | RGA2_SCHEDULER_CORE0 = 1 << 2, 125 | }; 126 | 127 | /* RGA3 rd_mode */ 128 | enum 129 | { 130 | raster_mode = 0x1 << 0, 131 | fbc_mode = 0x1 << 1, 132 | tile_mode = 0x1 << 2, 133 | }; 134 | 135 | #ifdef __cplusplus 136 | } 137 | #endif 138 | 139 | #endif /*_RK29_IPP_DRIVER_H_*/ 140 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/lib/.gitignore: -------------------------------------------------------------------------------- 1 | Android 2 | -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/lib/Linux/aarch64/librga.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MontaukLaw/3588_multi_rtsp_decode/91405545382f0ab3e18f4669e7c819e0281180bd/3rdparty/rga/RK3588/lib/Linux/aarch64/librga.a -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/lib/Linux/aarch64/librga.a_1.9.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MontaukLaw/3588_multi_rtsp_decode/91405545382f0ab3e18f4669e7c819e0281180bd/3rdparty/rga/RK3588/lib/Linux/aarch64/librga.a_1.9.0 -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/lib/Linux/aarch64/librga.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MontaukLaw/3588_multi_rtsp_decode/91405545382f0ab3e18f4669e7c819e0281180bd/3rdparty/rga/RK3588/lib/Linux/aarch64/librga.so -------------------------------------------------------------------------------- /3rdparty/rga/RK3588/lib/Linux/aarch64/librga.so_1.9.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MontaukLaw/3588_multi_rtsp_decode/91405545382f0ab3e18f4669e7c819e0281180bd/3rdparty/rga/RK3588/lib/Linux/aarch64/librga.so_1.9.0 -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 设置最低版本号 2 | cmake_minimum_required(VERSION 3.11 FATAL_ERROR) 3 | # 设置项目名称 4 | # project(rk3588-demo VERSION 0.0.1 LANGUAGES CXX) 5 | project(rk3588-demo) 6 | 7 | # 输出系统信息 8 | message(STATUS "System: ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION}") 9 | 10 | # 设置编译器 11 | set(CMAKE_CXX_STANDARD 11) 12 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 13 | 14 | # 设置库架构 15 | set(LIB_ARCH "aarch64") 16 | set(DEVICE_NAME "RK3588") 17 | 18 | # 19 | link_directories( 20 | mpp_libs 21 | ) 22 | # rknn_api 文件夹路径 23 | set(RKNN_API_PATH ${CMAKE_CURRENT_SOURCE_DIR}/librknn_api) 24 | # rknn_api include 路径 25 | set(RKNN_API_INCLUDE_PATH ${RKNN_API_PATH}/include) 26 | # rknn_api lib 路径 27 | set(RKNN_API_LIB_PATH ${RKNN_API_PATH}/${LIB_ARCH}/librknnrt.so) 28 | 29 | # 寻找OpenCV库,使用自定义的OpenCV_DIR 30 | set(3RDPARTY_PATH ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty) 31 | set(RGA_DIR ${3RDPARTY_PATH}/rga/${DEVICE_NAME}) 32 | set(RGA_LIB ${RGA_DIR}/lib/Linux/${LIB_ARCH}/librga.so) 33 | # set(OpenCV_DIR ${3RDPARTY_PATH}/opencv/opencv-linux-${LIB_ARCH}/share/OpenCV) 34 | find_package(OpenCV REQUIRED) 35 | # 输出OpenCV信息 36 | message(STATUS "include path: ${OpenCV_INCLUDE_DIRS}") 37 | message(STATUS "${OpenCV_VERSION}") 38 | 39 | # 用来搜索头文件的目录 40 | include_directories( 41 | ${OpenCV_INCLUDE_DIRS} 42 | ${RKNN_API_INCLUDE_PATH} 43 | ${CMAKE_CURRENT_SOURCE_DIR}/src 44 | ${CMAKE_CURRENT_SOURCE_DIR}/submodules/ZLMediaKit/api/include 45 | ${RGA_DIR}/include 46 | ${CMAKE_CURRENT_LIST_DIR}/submodules/mpp/inc 47 | ${CMAKE_CURRENT_LIST_DIR}/submodules/mpp/osal/inc 48 | ${CMAKE_CURRENT_LIST_DIR}/submodules/mpp/utils 49 | ${CMAKE_CURRENT_LIST_DIR}/submodules/mpp/mpp/inc 50 | ${CMAKE_CURRENT_LIST_DIR}/submodules/mpp/mpp/base/inc 51 | ${CMAKE_CURRENT_LIST_DIR}/mpp_inc 52 | ) 53 | 54 | # 构建预处理和后处理库 55 | add_library(nn_process SHARED 56 | src/process/preprocess.cpp 57 | src/process/postprocess.cpp 58 | ) 59 | # 链接库 60 | target_link_libraries(nn_process 61 | ${OpenCV_LIBS} 62 | ${RGA_LIB} 63 | ) 64 | 65 | # 构建自定义封装API库 66 | add_library(rknn_engine SHARED src/engine/rknn_engine.cpp) 67 | # 链接库 68 | target_link_libraries(rknn_engine 69 | ${RKNN_API_LIB_PATH} 70 | ) 71 | # yolov85_lib 72 | add_library(yolov8_lib SHARED src/task/yolov8_custom.cpp ) 73 | # 链接库 74 | target_link_libraries(yolov8_lib 75 | rknn_engine 76 | nn_process 77 | ) 78 | 79 | # draw_lib 80 | add_library(draw_lib SHARED src/draw/cv_draw.cpp) 81 | # 链接库 82 | target_link_libraries(draw_lib 83 | ${OpenCV_LIBS} 84 | ) 85 | 86 | # add_executable(yolov8_stream_pool 87 | # src/yolov8_stream_pool.cpp 88 | # src/task/yolov8_thread_pool.cpp 89 | # src/rkmedia/utils/mpp_decoder.cpp 90 | # src/rkmedia/utils/mpp_encoder.cpp 91 | # ) 92 | 93 | # target_link_libraries(yolov8_stream_pool 94 | # rockchip_mpp # 在mpp_libs下,包含了所有的mpp库 95 | # utils # 在mpp_libs下,MPP工具库 96 | # mk_api # 在mpp_libs下,ZLMediaKit API库 97 | # draw_lib 98 | # yolov8_lib 99 | # ) 100 | 101 | ########################## 102 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) 103 | # add_executable(rtsp_pool 104 | # src/rtsp_pool.cpp 105 | # src/rkmedia/utils/mpp_decoder.cpp 106 | # src/rkmedia/utils/mpp_encoder.cpp 107 | # src/mpp_api.cpp 108 | # src/screen_test.cpp 109 | # src/bo.c 110 | # src/dev.c 111 | # src/modeset.c) 112 | 113 | # target_link_libraries(rtsp_pool 114 | # rockchip_mpp # 在mpp_libs下,包含了所有的mpp库 115 | # utils # 在mpp_libs下,MPP工具库 116 | # mk_api # 在mpp_libs下,ZLMediaKit API库 117 | # draw_lib 118 | # yolov8_lib 119 | # drm 120 | # ) 121 | 122 | ############################ 123 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) 124 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/mpp_inc) 125 | include_directories(/usr/include/drm) 126 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) 127 | add_executable(rtsp_single 128 | src/rtsp_single.cpp 129 | src/rkmedia/utils/mpp_decoder.cpp 130 | src/rkmedia/utils/mpp_encoder.cpp 131 | src/screen_test.cpp 132 | src/bo.c 133 | src/dev.c 134 | src/modeset.c 135 | src/mpp_api.cpp 136 | ) 137 | 138 | target_link_libraries(rtsp_single 139 | rockchip_mpp # 在mpp_libs下,包含了所有的mpp库 140 | utils # 在mpp_libs下,MPP工具库 141 | mk_api # 在mpp_libs下,ZLMediaKit API库 142 | draw_lib 143 | yolov8_lib 144 | drm 145 | ) 146 | 147 | # find_package(X11 REQUIRED) 148 | # add_executable(screen_demo 149 | # src/x11_screen_driver.cpp 150 | # ) 151 | 152 | # target_link_libraries(screen_demo X11) 153 | 154 | # add_executable(screen_test 155 | # src/screen_test.cpp 156 | # src/bo.c 157 | # src/dev.c 158 | # src/modeset.c) 159 | # target_link_libraries(screen_test drm) 160 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 多达9-16路RTSP MPP硬解码 2 | RGA缩放 3 | 同屏显示 4 | 5 | 目前是16路解码, 有几路是有问题的, 反正不是正式项目, 大家看着有点启发就好. 6 | 7 | 直接在板子上编译就好 8 | 需要升级rga的lib驱动, mpp的lib 9 | 基于恩培的yolov8_stream_pool项目修改的, 有兴趣还能直接融合推理进来. 10 | 11 | src/rtsp_single.cpp //主程序 12 | src/rkmedia/utils/mpp_decoder.cpp // 解码器 13 | src/rkmedia/utils/mpp_encoder.cpp // 编码器 没用上 14 | src/screen_test.cpp // drm显示 15 | src/bo.c 16 | src/dev.c 17 | src/modeset.c 18 | src/mpp_api.cpp // RGA缩放 19 | 20 | 这里最费劲的就是RGA缩放, 因为不熟. 21 | mpp_decoder_frame_callback这个回调, data里面返回的就是解码后的nv12类型的数据, 里面有几个坑 22 | 1. nv12不是420sp 23 | 2. 高度是16字节对齐的, 也就是说高度是1088, 而不是1080 24 | 3. 分几步, 一个是缩放, 一个是转色彩格式, (如果使用opencv, 还涉及imcopy) 25 | 4. 之前一直因为没有使用importbuffer_virtualaddr, 导致rga内存申请一直报错, 参考librga例程才算是解决了. 26 | 27 | 420sp转rgba才能显示, 当然, 你要推理也是要转成RGB的, 这里使用了task方式, 如果用opencv的话, 是cpu参与, 估计会非常慢, 因为我硬件rga都花了超过40ms, 28 | 29 | 编译: 30 | cmake --build build 31 | 32 | 运行: 33 | ./build/rtsp_single 34 | 35 | ubuntu最好使用非图形化界面 36 | sudo systemctl set-default multi-user.target 37 | sudo rebboot 38 | 39 | 查看rga的内核占用情况: 40 | sudo cat /sys/kernel/debug/rkrga/load 41 | 42 | 查看cpu温度 43 | sudo cat /sys/class/thermal/thermal_zone0/temp 44 | 45 | 查看可能存在的rga报错: 46 | sudo tail /var/log/syslog -n 50 47 | 48 | -------------------------------------------------------------------------------- /copy_mpp_libs.sh: -------------------------------------------------------------------------------- 1 | cp submodules/mpp/build/utils/libutils.a mpp_libs/ 2 | cp ./submodules/ZLMediaKit/release/linux/Debug/libmk_api.so mpp_libs/ 3 | # cp submodules/mpp/build/osal/libosal.a mpp_libs/ 4 | # cp submodules/mpp/build/mpp/hal/dummy/libhal_dummy.a mpp_libs/ 5 | # cp submodules/mpp/build/mpp/legacy/librockchip_vpu* mpp_libs/ 6 | # cp submodules/mpp/build/mpp/librockchip_mpp.so* mpp_libs 7 | -------------------------------------------------------------------------------- /include/bo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Rockchip Electronics S.LSI Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MPP_LINUX_C_BO_H 18 | #define MPP_LINUX_C_BO_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "dev.h" 32 | 33 | #undef USE_ATOMIC_API 34 | struct sp_dev; 35 | 36 | struct sp_bo { 37 | struct sp_dev *dev; 38 | 39 | uint32_t width; 40 | uint32_t height; 41 | uint32_t depth; 42 | uint32_t bpp; 43 | uint32_t format; 44 | uint32_t flags; 45 | 46 | uint32_t fb_id; 47 | uint32_t handle; 48 | void *map_addr; 49 | uint32_t pitch; 50 | uint32_t size; 51 | }; 52 | 53 | int add_fb_sp_bo(struct sp_bo *bo, uint32_t format); 54 | struct sp_bo* create_sp_bo(struct sp_dev *dev, uint32_t width, uint32_t height, 55 | uint32_t depth, uint32_t bpp, uint32_t format, uint32_t flags); 56 | 57 | void fill_bo(struct sp_bo *bo, uint8_t a, uint8_t r, uint8_t g, uint8_t b); 58 | void draw_rect(struct sp_bo *bo, uint32_t x, uint32_t y, uint32_t width, 59 | uint32_t height, uint8_t a, uint8_t r, uint8_t g, uint8_t b); 60 | 61 | void free_sp_bo(struct sp_bo *bo); 62 | 63 | #endif //MPP_LINUX_C_BO_H 64 | -------------------------------------------------------------------------------- /include/dev.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by root on 17-11-7. 3 | // 4 | 5 | #ifndef MPP_LINUX_C_DEV_H 6 | #define MPP_LINUX_C_DEV_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "bo.h" 21 | #include "modeset.h" 22 | 23 | struct sp_bo; 24 | struct sp_dev; 25 | 26 | struct sp_plane { 27 | struct sp_dev *dev; 28 | drmModePlanePtr plane; 29 | struct sp_bo *bo; 30 | int in_use; 31 | uint32_t format; 32 | 33 | /* Property ID's */ 34 | uint32_t crtc_pid; 35 | uint32_t fb_pid; 36 | uint32_t zpos_pid; 37 | uint32_t crtc_x_pid; 38 | uint32_t crtc_y_pid; 39 | uint32_t crtc_w_pid; 40 | uint32_t crtc_h_pid; 41 | uint32_t src_x_pid; 42 | uint32_t src_y_pid; 43 | uint32_t src_w_pid; 44 | uint32_t src_h_pid; 45 | }; 46 | 47 | struct sp_crtc { 48 | drmModeCrtcPtr crtc; 49 | int pipe; 50 | int num_planes; 51 | struct sp_bo *scanout; 52 | }; 53 | 54 | struct sp_dev { 55 | int fd; 56 | 57 | int num_connectors; 58 | drmModeConnectorPtr *connectors; 59 | 60 | int num_encoders; 61 | drmModeEncoderPtr *encoders; 62 | 63 | int num_crtcs; 64 | struct sp_crtc *crtcs; 65 | 66 | int num_planes; 67 | struct sp_plane *planes; 68 | }; 69 | 70 | int is_supported_format(struct sp_plane *plane, uint32_t format); 71 | struct sp_dev* create_sp_dev(void); 72 | void destroy_sp_dev(struct sp_dev *dev); 73 | 74 | #endif //MPP_LINUX_C_DEV_H 75 | -------------------------------------------------------------------------------- /include/drm_display.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRM_DISPLAY_H__ 2 | #define __DRM_DISPLAY_H__ 3 | 4 | // #include "../rkrga/RGA.h" 5 | #include 6 | #include 7 | 8 | extern "C" 9 | { 10 | #include 11 | #include 12 | #include 13 | 14 | #include "vpu.h" 15 | #include "rk_mpi.h" 16 | #include "rk_type.h" 17 | #include "vpu_api.h" 18 | #include "mpp_err.h" 19 | #include "mpp_task.h" 20 | #include "mpp_meta.h" 21 | #include "mpp_frame.h" 22 | #include "mpp_buffer.h" 23 | #include "mpp_packet.h" 24 | #include "rk_mpi_cmd.h" 25 | 26 | #include "bo.h" 27 | #include "dev.h" 28 | #include "modeset.h" 29 | }; 30 | 31 | // #define SZ_4K 4096 32 | #define PKT_SIZE SZ_4K 33 | #define CODEC_ALIGN(x, a) (((x) + (a)-1) & ~((a)-1)) 34 | #define LCD_0_CRTC_ID 184 35 | #define LCD_0_PLANE_ID 170 36 | 37 | #define SCREEN_HEIGHT 1280 38 | #define SCREEN_WIDTH 800 39 | 40 | // lcd的宽度是800, 高度是1280 41 | #define LCD_SCREEN_HEIGHT 1280 42 | #define LCD_SCREEN_WIDTH 800 43 | 44 | #define HDMI_SCREEN_HEIGHT 1080 45 | #define HDMI_SCREEN_WIDTH 1920 46 | 47 | // 1072/800 = 1.34 48 | // 4224/3136 = 1.34, 基本符合长宽比, 因为opencv的策略就是等宽高缩放. 49 | // 但是这个比例不是很好, 会导致显示的时候有黑边 50 | // #define VIDEO_HEIGHT 800 51 | // #define VIDEO_WIDTH 1072 52 | 53 | // 1280/1.34 = 1715 1712能被16整除 54 | #define VIDEO_HEIGHT 960 55 | #define VIDEO_WIDTH 1280 56 | 57 | #define CAM1_VIDEO_WIDTH 1280 58 | #define CAM1_VIDEO_HEIGHT 960 59 | 60 | // #define CAM2_VIDEO_HEIGHT 1080 61 | #define CAM2_VIDEO_HEIGHT 1440 62 | #define CAM2_VIDEO_WIDTH 1920 63 | 64 | #define MODLE_OUTPUT_NUM 3 65 | 66 | // #define VIDEO_HEIGHT 800 67 | // #define VIDEO_WIDTH 1440 68 | 69 | // #define DISPLAY_WIDTH VIDEO_HEIGHT 70 | // #define DISPLAY_HEIGHT 1280 71 | 72 | // 输出的测试图片高宽跟摄像头的输入分辨率高宽正好反过来 73 | #define OUTPUT_IMG_WIDTH VIDEO_HEIGHT 74 | #define OUTPUT_IMG_HEIGHT VIDEO_WIDTH 75 | 76 | #define CAM1_OUTPUT_IMG_WIDTH CAM1_VIDEO_HEIGHT 77 | #define CAM1_OUTPUT_IMG_HEIGHT CAM1_VIDEO_WIDTH 78 | 79 | #define LCD_DATA_HEIGHT CAM1_VIDEO_WIDTH 80 | #define LCD_DATA_WIDTH CAM1_VIDEO_HEIGHT 81 | 82 | #define HDMI_DATA_HEIGHT CAM2_VIDEO_WIDTH 83 | #define HDMI_DATA_WIDTH CAM2_VIDEO_HEIGHT 84 | 85 | // 裁掉的高度部分 86 | #define CORP_HEIGHT (VIDEO_WIDTH - SCREEN_HEIGHT) 87 | 88 | #define OUTPUT_DEVICE_HDMI 1 89 | #define OUTPUT_DEVICE_LCD 2 90 | 91 | #define RGAX_SIZE 92 | #define cxx_log(fmt, ...) \ 93 | do \ 94 | { \ 95 | printf(fmt, ##__VA_ARGS__); \ 96 | } while (0) 97 | 98 | void init_display(); 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /include/modeset.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by root on 17-11-7. 3 | // 4 | 5 | #ifndef MPP_LINUX_C_MODESET_H 6 | #define MPP_LINUX_C_MODESET_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "bo.h" 15 | #include "dev.h" 16 | 17 | struct sp_dev; 18 | struct sp_crtc; 19 | 20 | int initialize_screens(struct sp_dev *dev); 21 | 22 | struct sp_plane* get_sp_plane(struct sp_dev *dev, struct sp_crtc *crtc); 23 | void put_sp_plane(struct sp_plane *plane); 24 | 25 | int set_sp_plane(struct sp_dev *dev, struct sp_plane *plane, 26 | struct sp_crtc *crtc, int x, int y); 27 | 28 | #ifdef USE_ATOMIC_API 29 | int set_sp_plane_pset(struct sp_dev *dev, struct sp_plane *plane, 30 | drmModePropertySetPtr pset, struct sp_crtc *crtc, int x, int y); 31 | #endif 32 | 33 | #endif //MPP_LINUX_C_MODESET_H 34 | -------------------------------------------------------------------------------- /include/mpp_api.h: -------------------------------------------------------------------------------- 1 | #ifndef __MPP_API_H__ 2 | #define __MPP_API_H__ 3 | 4 | #define TOTAL_WINDOW_NUMBER 2 5 | 6 | typedef struct 7 | { 8 | FILE *out_fp; 9 | MppDecoder *decoder; 10 | MppEncoder *encoder; 11 | mk_media media; 12 | mk_pusher pusher; 13 | const char *push_url; 14 | uint64_t pts; 15 | uint64_t dts; 16 | int processId; 17 | char stream_url[256]; 18 | } rknn_app_context_t; 19 | 20 | void mpp_decoder_frame_callback(void *userdata, int width_stride, int height_stride, int width, int height, int format, int fd, void *data); 21 | 22 | int process_video_rtsp(rknn_app_context_t *ctx, const char *url); 23 | 24 | int process_video(rknn_app_context_t *ctx, const char *url); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/screen_test.h: -------------------------------------------------------------------------------- 1 | #ifndef __SCREEN_TEST_H_ 2 | #define __SCREEN_TEST_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | void hdmi_init(); 11 | 12 | void draw_hdmi_screen_rgb(uint8_t *data, uint32_t dataSize); 13 | 14 | void draw_hdmi_screen_rgb_quarter(uint8_t *data, uint32_t dataSize, uint8_t quarter); 15 | 16 | void draw_hdmi_screen_rgb_nine(uint8_t *data, uint32_t dataSize, uint8_t part); 17 | 18 | void draw_hdmi_screen_rgb_dynamic(uint8_t *data, uint32_t dataSize, uint8_t screenNum, uint8_t rows, uint8_t cols); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /librknn_api/aarch64/librknnrt.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MontaukLaw/3588_multi_rtsp_decode/91405545382f0ab3e18f4669e7c819e0281180bd/librknn_api/aarch64/librknnrt.so -------------------------------------------------------------------------------- /librknn_api/armhf/librknnrt.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MontaukLaw/3588_multi_rtsp_decode/91405545382f0ab3e18f4669e7c819e0281180bd/librknn_api/armhf/librknnrt.so -------------------------------------------------------------------------------- /mpp_inc/mpp_compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __MPP_COMPAT_H__ 18 | #define __MPP_COMPAT_H__ 19 | 20 | #include "rk_type.h" 21 | #include "mpp_err.h" 22 | 23 | typedef enum MppCompatId_e { 24 | MPP_COMPAT_INC_FBC_BUF_SIZE, 25 | MPP_COMPAT_ENC_ASYNC_INPUT, 26 | MPP_COMPAT_DEC_FBC_HDR_256_ODD, 27 | MPP_COMPAT_BUTT, 28 | } MppCompatId; 29 | 30 | typedef enum MppCompatType_e { 31 | MPP_COMPAT_BOOL, 32 | MPP_COMPAT_S32, 33 | MPP_COMPAT_TYPE_BUTT, 34 | } MppCompatType; 35 | 36 | typedef struct MppCompat_t MppCompat; 37 | 38 | /* external user can only update value_ext to notify mpp to change its behavior */ 39 | struct MppCompat_t { 40 | const MppCompatId feature_id; 41 | const MppCompatType feature_type; 42 | const RK_S32 value_mpp; 43 | RK_S32 value_usr; 44 | const char *name; 45 | MppCompat * const next; 46 | }; 47 | 48 | #ifdef __cplusplus 49 | extern "C" { 50 | #endif 51 | 52 | MppCompat *mpp_compat_query(void); 53 | MppCompat *mpp_compat_query_by_id(MppCompatId id); 54 | MPP_RET mpp_compat_update(MppCompat *compat, RK_S32 value); 55 | 56 | void mpp_compat_show(void); 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif /*__MPP_COMPAT_H__*/ 63 | -------------------------------------------------------------------------------- /mpp_inc/mpp_err.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __MPP_ERR_H__ 18 | #define __MPP_ERR_H__ 19 | 20 | #define RK_OK 0 21 | #define RK_SUCCESS 0 22 | 23 | typedef enum { 24 | MPP_SUCCESS = RK_SUCCESS, 25 | MPP_OK = RK_OK, 26 | 27 | MPP_NOK = -1, 28 | MPP_ERR_UNKNOW = -2, 29 | MPP_ERR_NULL_PTR = -3, 30 | MPP_ERR_MALLOC = -4, 31 | MPP_ERR_OPEN_FILE = -5, 32 | MPP_ERR_VALUE = -6, 33 | MPP_ERR_READ_BIT = -7, 34 | MPP_ERR_TIMEOUT = -8, 35 | MPP_ERR_PERM = -9, 36 | 37 | MPP_ERR_BASE = -1000, 38 | 39 | /* The error in stream processing */ 40 | MPP_ERR_LIST_STREAM = MPP_ERR_BASE - 1, 41 | MPP_ERR_INIT = MPP_ERR_BASE - 2, 42 | MPP_ERR_VPU_CODEC_INIT = MPP_ERR_BASE - 3, 43 | MPP_ERR_STREAM = MPP_ERR_BASE - 4, 44 | MPP_ERR_FATAL_THREAD = MPP_ERR_BASE - 5, 45 | MPP_ERR_NOMEM = MPP_ERR_BASE - 6, 46 | MPP_ERR_PROTOL = MPP_ERR_BASE - 7, 47 | MPP_FAIL_SPLIT_FRAME = MPP_ERR_BASE - 8, 48 | MPP_ERR_VPUHW = MPP_ERR_BASE - 9, 49 | MPP_EOS_STREAM_REACHED = MPP_ERR_BASE - 11, 50 | MPP_ERR_BUFFER_FULL = MPP_ERR_BASE - 12, 51 | MPP_ERR_DISPLAY_FULL = MPP_ERR_BASE - 13, 52 | } MPP_RET; 53 | 54 | #endif /*__MPP_ERR_H__*/ 55 | -------------------------------------------------------------------------------- /mpp_inc/mpp_log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __MPP_LOG_H__ 18 | #define __MPP_LOG_H__ 19 | 20 | #include "rk_type.h" 21 | #include "mpp_log_def.h" 22 | 23 | /* 24 | * _c function will add condition check 25 | * _f function will add function name to the log 26 | * _cf function will add both function name and condition check 27 | */ 28 | 29 | /* 30 | * mpp runtime log system usage: 31 | * mpp_logf is for fatal logging. For use when aborting 32 | * mpp_loge is for error logging. For use with unrecoverable failures. 33 | * mpp_logw is for warning logging. For use with recoverable failures. 34 | * mpp_logi is for informational logging. 35 | * mpp_logd is for debug logging. 36 | * mpp_logv is for verbose logging 37 | */ 38 | 39 | #define mpp_logf(fmt, ...) _mpp_log_l(MPP_LOG_FATAL, MODULE_TAG, fmt, NULL, ## __VA_ARGS__) 40 | #define mpp_loge(fmt, ...) _mpp_log_l(MPP_LOG_ERROR, MODULE_TAG, fmt, NULL, ## __VA_ARGS__) 41 | #define mpp_logw(fmt, ...) _mpp_log_l(MPP_LOG_WARN, MODULE_TAG, fmt, NULL, ## __VA_ARGS__) 42 | #define mpp_logi(fmt, ...) _mpp_log_l(MPP_LOG_INFO, MODULE_TAG, fmt, NULL, ## __VA_ARGS__) 43 | #define mpp_logd(fmt, ...) _mpp_log_l(MPP_LOG_DEBUG, MODULE_TAG, fmt, NULL, ## __VA_ARGS__) 44 | #define mpp_logv(fmt, ...) _mpp_log_l(MPP_LOG_VERBOSE, MODULE_TAG, fmt, NULL, ## __VA_ARGS__) 45 | 46 | #define mpp_logf_f(fmt, ...) _mpp_log_l(MPP_LOG_FATAL, MODULE_TAG, fmt, __FUNCTION__, ## __VA_ARGS__) 47 | #define mpp_loge_f(fmt, ...) _mpp_log_l(MPP_LOG_ERROR, MODULE_TAG, fmt, __FUNCTION__, ## __VA_ARGS__) 48 | #define mpp_logw_f(fmt, ...) _mpp_log_l(MPP_LOG_WARN, MODULE_TAG, fmt, __FUNCTION__, ## __VA_ARGS__) 49 | #define mpp_logi_f(fmt, ...) _mpp_log_l(MPP_LOG_INFO, MODULE_TAG, fmt, __FUNCTION__, ## __VA_ARGS__) 50 | #define mpp_logd_f(fmt, ...) _mpp_log_l(MPP_LOG_DEBUG, MODULE_TAG, fmt, __FUNCTION__, ## __VA_ARGS__) 51 | #define mpp_logv_f(fmt, ...) _mpp_log_l(MPP_LOG_VERBOSE, MODULE_TAG, fmt, __FUNCTION__, ## __VA_ARGS__) 52 | 53 | #define mpp_logf_c(cond, fmt, ...) do { if (cond) mpp_logf(fmt, ## __VA_ARGS__); } while (0) 54 | #define mpp_loge_c(cond, fmt, ...) do { if (cond) mpp_loge(fmt, ## __VA_ARGS__); } while (0) 55 | #define mpp_logw_c(cond, fmt, ...) do { if (cond) mpp_logw(fmt, ## __VA_ARGS__); } while (0) 56 | #define mpp_logi_c(cond, fmt, ...) do { if (cond) mpp_logi(fmt, ## __VA_ARGS__); } while (0) 57 | #define mpp_logd_c(cond, fmt, ...) do { if (cond) mpp_logd(fmt, ## __VA_ARGS__); } while (0) 58 | #define mpp_logv_c(cond, fmt, ...) do { if (cond) mpp_logv(fmt, ## __VA_ARGS__); } while (0) 59 | 60 | #define mpp_logf_cf(cond, fmt, ...) do { if (cond) mpp_logf_f(fmt, ## __VA_ARGS__); } while (0) 61 | #define mpp_loge_cf(cond, fmt, ...) do { if (cond) mpp_loge_f(fmt, ## __VA_ARGS__); } while (0) 62 | #define mpp_logw_cf(cond, fmt, ...) do { if (cond) mpp_logw_f(fmt, ## __VA_ARGS__); } while (0) 63 | #define mpp_logi_cf(cond, fmt, ...) do { if (cond) mpp_logi_f(fmt, ## __VA_ARGS__); } while (0) 64 | #define mpp_logd_cf(cond, fmt, ...) do { if (cond) mpp_logd_f(fmt, ## __VA_ARGS__); } while (0) 65 | #define mpp_logv_cf(cond, fmt, ...) do { if (cond) mpp_logv_f(fmt, ## __VA_ARGS__); } while (0) 66 | 67 | /* 68 | * mpp runtime log system usage: 69 | * mpp_err is for error status message, it will print for sure. 70 | * mpp_log is for important message like open/close/reset/flush, it will print too. 71 | */ 72 | 73 | #define mpp_log(fmt, ...) mpp_logi(fmt, ## __VA_ARGS__) 74 | #define mpp_err(fmt, ...) mpp_loge(fmt, ## __VA_ARGS__) 75 | 76 | #define mpp_log_f(fmt, ...) mpp_logi_f(fmt, ## __VA_ARGS__) 77 | #define mpp_err_f(fmt, ...) mpp_loge_f(fmt, ## __VA_ARGS__) 78 | 79 | #define mpp_log_c(cond, fmt, ...) do { if (cond) mpp_log(fmt, ## __VA_ARGS__); } while (0) 80 | #define mpp_log_cf(cond, fmt, ...) do { if (cond) mpp_log_f(fmt, ## __VA_ARGS__); } while (0) 81 | 82 | #ifdef __cplusplus 83 | extern "C" { 84 | #endif 85 | 86 | void _mpp_log_l(int level, const char *tag, const char *fmt, const char *func, ...); 87 | 88 | void mpp_set_log_level(int level); 89 | int mpp_get_log_level(void); 90 | 91 | /* deprecated function */ 92 | void _mpp_log(const char *tag, const char *fmt, const char *func, ...); 93 | void _mpp_err(const char *tag, const char *fmt, const char *func, ...); 94 | 95 | #ifdef __cplusplus 96 | } 97 | #endif 98 | 99 | #endif /*__MPP_LOG_H__*/ 100 | -------------------------------------------------------------------------------- /mpp_inc/mpp_log_def.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __MPP_LOG_DEF_H__ 18 | #define __MPP_LOG_DEF_H__ 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #define MPP_LOG_UNKNOWN 0 /* internal use only */ 25 | #define MPP_LOG_FATAL 1 /* fatal error on aborting */ 26 | #define MPP_LOG_ERROR 2 /* error log on unrecoverable failures */ 27 | #define MPP_LOG_WARN 3 /* warning log on recoverable failures */ 28 | #define MPP_LOG_INFO 4 /* Informational log */ 29 | #define MPP_LOG_DEBUG 5 /* Debug log */ 30 | #define MPP_LOG_VERBOSE 6 /* Verbose log */ 31 | #define MPP_LOG_SILENT 7 /* internal use only */ 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | #endif /*__MPP_LOG_DEF_H__*/ 38 | -------------------------------------------------------------------------------- /mpp_inc/mpp_packet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __MPP_PACKET_H__ 18 | #define __MPP_PACKET_H__ 19 | 20 | #include "mpp_meta.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* 27 | * MppPacket interface 28 | * 29 | * mpp_packet_init = mpp_packet_new + mpp_packet_set_data + mpp_packet_set_size 30 | * mpp_packet_copy_init = mpp_packet_init + memcpy 31 | */ 32 | MPP_RET mpp_packet_new(MppPacket *packet); 33 | MPP_RET mpp_packet_init(MppPacket *packet, void *data, size_t size); 34 | MPP_RET mpp_packet_init_with_buffer(MppPacket *packet, MppBuffer buffer); 35 | MPP_RET mpp_packet_copy_init(MppPacket *packet, const MppPacket src); 36 | MPP_RET mpp_packet_deinit(MppPacket *packet); 37 | 38 | /* 39 | * data : ( R/W ) start address of the whole packet memory 40 | * size : ( R/W ) total size of the whole packet memory 41 | * pos : ( R/W ) current access position of the whole packet memory, used for buffer read/write 42 | * length : ( R/W ) the rest length from current position to end of buffer 43 | * NOTE: normally length is updated only by set_pos, 44 | * so set length must be used carefully for special usage 45 | */ 46 | void mpp_packet_set_data(MppPacket packet, void *data); 47 | void mpp_packet_set_size(MppPacket packet, size_t size); 48 | void mpp_packet_set_pos(MppPacket packet, void *pos); 49 | void mpp_packet_set_length(MppPacket packet, size_t size); 50 | 51 | void* mpp_packet_get_data(const MppPacket packet); 52 | void* mpp_packet_get_pos(const MppPacket packet); 53 | size_t mpp_packet_get_size(const MppPacket packet); 54 | size_t mpp_packet_get_length(const MppPacket packet); 55 | 56 | 57 | void mpp_packet_set_pts(MppPacket packet, RK_S64 pts); 58 | RK_S64 mpp_packet_get_pts(const MppPacket packet); 59 | void mpp_packet_set_dts(MppPacket packet, RK_S64 dts); 60 | RK_S64 mpp_packet_get_dts(const MppPacket packet); 61 | 62 | void mpp_packet_set_flag(MppPacket packet, RK_U32 flag); 63 | RK_U32 mpp_packet_get_flag(const MppPacket packet); 64 | 65 | MPP_RET mpp_packet_set_eos(MppPacket packet); 66 | MPP_RET mpp_packet_clr_eos(MppPacket packet); 67 | RK_U32 mpp_packet_get_eos(MppPacket packet); 68 | MPP_RET mpp_packet_set_extra_data(MppPacket packet); 69 | 70 | void mpp_packet_set_buffer(MppPacket packet, MppBuffer buffer); 71 | MppBuffer mpp_packet_get_buffer(const MppPacket packet); 72 | 73 | /* 74 | * data access interface 75 | */ 76 | MPP_RET mpp_packet_read(MppPacket packet, size_t offset, void *data, size_t size); 77 | MPP_RET mpp_packet_write(MppPacket packet, size_t offset, void *data, size_t size); 78 | 79 | /* 80 | * meta data access interface 81 | */ 82 | RK_S32 mpp_packet_has_meta(const MppPacket packet); 83 | MppMeta mpp_packet_get_meta(const MppPacket packet); 84 | 85 | /* 86 | * multi packet sequence interface for slice/split encoding/decoding 87 | * partition - the packet is a part of a while image 88 | * soi - Start Of Image 89 | * eoi - End Of Image 90 | */ 91 | RK_U32 mpp_packet_is_partition(const MppPacket packet); 92 | RK_U32 mpp_packet_is_soi(const MppPacket packet); 93 | RK_U32 mpp_packet_is_eoi(const MppPacket packet); 94 | 95 | /* 96 | * packet segement pack info for 97 | * segment number - number of segment 98 | * segment info - base address of segment info 99 | */ 100 | typedef struct MppPktSeg_t MppPktSeg; 101 | 102 | struct MppPktSeg_t { 103 | RK_S32 index; 104 | RK_S32 type; 105 | RK_U32 offset; 106 | RK_U32 len; 107 | const MppPktSeg *next; 108 | }; 109 | 110 | RK_U32 mpp_packet_get_segment_nb(const MppPacket packet); 111 | const MppPktSeg *mpp_packet_get_segment_info(const MppPacket packet); 112 | 113 | #ifdef __cplusplus 114 | } 115 | #endif 116 | 117 | #endif /*__MPP_PACKET_H__*/ 118 | -------------------------------------------------------------------------------- /mpp_inc/mpp_rc_api.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __MPP_RC_API_H__ 18 | #define __MPP_RC_API_H__ 19 | 20 | #include "mpp_err.h" 21 | #include "rk_venc_rc.h" 22 | #include "mpp_rc_defs.h" 23 | 24 | /* 25 | * Mpp rate control has three parts: 26 | * 27 | * 1. MPI user config module 28 | * MppEncRcCfg structure is provided to user for overall rate control config 29 | * Mpp will receive MppEncRcCfg from user, check parameter and set it to 30 | * encoder. 31 | * 32 | * 2. Encoder rate control module 33 | * Encoder will implement the rate control strategy required by users 34 | * including CBR, VBR, AVBR and so on. 35 | * This module only implement the target bit calculation behavior and 36 | * quality restriction. And the quality level will be controlled by hal. 37 | * 38 | * 3. Hal rate control module 39 | * Hal will implement the rate control on hardware. Hal will calculate the 40 | * QP parameter for hardware according to the frame level target bit 41 | * specified by the encoder. And the report the real bitrate and quality to 42 | * encoder. 43 | * 44 | * The header defines the communication interfaces and structures used between 45 | * MPI, encoder and hal. 46 | */ 47 | 48 | typedef enum RcMode_e { 49 | RC_VBR, 50 | RC_CBR, 51 | RC_FIXQP, 52 | RC_AVBR, 53 | RC_CVBR, 54 | RC_QVBR, 55 | RC_LEARNING, 56 | RC_MODE_BUTT, 57 | } RcMode; 58 | 59 | typedef enum GopMode_e { 60 | NORMAL_P, 61 | SMART_P, 62 | } GopMode; 63 | 64 | /* 65 | * frame rate parameters have great effect on rate control 66 | * 67 | * fps_in_flex 68 | * 0 - fix input frame rate 69 | * 1 - variable input frame rate 70 | * 71 | * fps_in_num 72 | * input frame rate numerator, if 0 then default 30 73 | * 74 | * fps_in_denorm 75 | * input frame rate denorminator, if 0 then default 1 76 | * 77 | * fps_out_flex 78 | * 0 - fix output frame rate 79 | * 1 - variable output frame rate 80 | * 81 | * fps_out_num 82 | * output frame rate numerator, if 0 then default 30 83 | * 84 | * fps_out_denorm 85 | * output frame rate denorminator, if 0 then default 1 86 | */ 87 | typedef struct RcFpsCfg_t { 88 | RK_S32 fps_in_flex; 89 | RK_S32 fps_in_num; 90 | RK_S32 fps_in_denorm; 91 | RK_S32 fps_out_flex; 92 | RK_S32 fps_out_num; 93 | RK_S32 fps_out_denorm; 94 | } RcFpsCfg; 95 | 96 | typedef struct RcSuperframeCfg_t { 97 | MppEncRcSuperFrameMode super_mode; 98 | RK_U32 super_i_thd; 99 | RK_U32 super_p_thd; 100 | MppEncRcPriority rc_priority; 101 | } RcSuperframeCfg; 102 | 103 | typedef struct RcDebreathCfg_t { 104 | RK_U32 enable; 105 | RK_U32 strength; 106 | } RcDebreathCfg; 107 | 108 | typedef struct RcHierQPCfg_t { 109 | RK_S32 hier_qp_en; 110 | RK_S32 hier_qp_delta[4]; 111 | RK_S32 hier_frame_num[4]; 112 | } RcHierQPCfg; 113 | 114 | /* 115 | * Control parameter from external config 116 | * 117 | * It will be updated on rc/prep/gopref config changed. 118 | */ 119 | typedef struct RcCfg_s { 120 | /* encode image size */ 121 | RK_S32 width; 122 | RK_S32 height; 123 | 124 | /* Use rc_mode to find different api */ 125 | RcMode mode; 126 | 127 | RcFpsCfg fps; 128 | 129 | GopMode gop_mode; 130 | /* I frame gop len */ 131 | RK_S32 igop; 132 | /* visual gop len */ 133 | RK_S32 vgop; 134 | 135 | /* bitrate parameter */ 136 | RK_S32 bps_min; 137 | RK_S32 bps_target; 138 | RK_S32 bps_max; 139 | RK_S32 stats_time; 140 | 141 | /* max I frame bit ratio to P frame bit */ 142 | RK_S32 max_i_bit_prop; 143 | RK_S32 min_i_bit_prop; 144 | RK_S32 init_ip_ratio; 145 | /* layer bitrate proportion */ 146 | RK_S32 layer_bit_prop[4]; 147 | 148 | /* quality parameter */ 149 | RK_S32 init_quality; 150 | RK_S32 max_quality; 151 | RK_S32 min_quality; 152 | RK_S32 max_i_quality; 153 | RK_S32 min_i_quality; 154 | RK_S32 i_quality_delta; 155 | RK_S32 vi_quality_delta; 156 | RK_S32 fqp_min_i; 157 | RK_S32 fqp_min_p; 158 | RK_S32 fqp_max_i; 159 | RK_S32 fqp_max_p; 160 | /* layer quality proportion */ 161 | RK_S32 layer_quality_delta[4]; 162 | 163 | /* reencode parameter */ 164 | RK_S32 max_reencode_times; 165 | 166 | /* still / motion desision parameter */ 167 | RK_S32 min_still_prop; 168 | RK_S32 max_still_quality; 169 | 170 | /* 171 | * vbr parameter 172 | * 173 | * vbr_hi_prop - high proportion bitrate for reduce quality 174 | * vbr_lo_prop - low proportion bitrate for increase quality 175 | */ 176 | RK_S32 vbr_hi_prop; 177 | RK_S32 vbr_lo_prop; 178 | 179 | MppEncRcDropFrmMode drop_mode; 180 | RK_U32 drop_thd; 181 | RK_U32 drop_gap; 182 | 183 | RcSuperframeCfg super_cfg; 184 | RcDebreathCfg debreath_cfg; 185 | RcHierQPCfg hier_qp_cfg; 186 | RK_U32 refresh_len; 187 | RK_S32 scene_mode; 188 | RK_U32 fps_chg_prop; 189 | } RcCfg; 190 | 191 | /* 192 | * Different rate control strategy will be implemented by different API config 193 | */ 194 | typedef struct RcImplApi_t { 195 | char *name; 196 | MppCodingType type; 197 | RK_U32 ctx_size; 198 | 199 | MPP_RET (*init)(void *ctx, RcCfg *cfg); 200 | MPP_RET (*deinit)(void *ctx); 201 | 202 | MPP_RET (*check_drop)(void *ctx, EncRcTask *task); 203 | MPP_RET (*check_reenc)(void *ctx, EncRcTask *task); 204 | 205 | /* 206 | * frm_start - frame level rate control frm_start. 207 | * The EncRcTaskInfo will be output to hal for hardware to implement. 208 | * frm_end - frame level rate control frm_end. 209 | * The EncRcTaskInfo is returned for real quality and bitrate. 210 | */ 211 | MPP_RET (*frm_start)(void *ctx, EncRcTask *task); 212 | MPP_RET (*frm_end)(void *ctx, EncRcTask *task); 213 | 214 | /* 215 | * hal_start - hardware level rate control start. 216 | * The EncRcTaskInfo will be output to hal for hardware to implement. 217 | * hal_end - hardware level rate control end. 218 | * The EncRcTaskInfo is returned for real quality and bitrate. 219 | */ 220 | MPP_RET (*hal_start)(void *ctx, EncRcTask *task); 221 | MPP_RET (*hal_end)(void *ctx, EncRcTask *task); 222 | } RcImplApi; 223 | 224 | /* 225 | * structures for RC API register and query 226 | */ 227 | typedef struct RcApiBrief_t { 228 | const char *name; 229 | MppCodingType type; 230 | } RcApiBrief; 231 | 232 | typedef struct RcApiQueryAll_t { 233 | /* input param for query */ 234 | RcApiBrief *brief; 235 | RK_S32 max_count; 236 | 237 | /* output query count */ 238 | RK_S32 count; 239 | } RcApiQueryAll; 240 | 241 | typedef struct RcApiQueryType_t { 242 | /* input param for query */ 243 | RcApiBrief *brief; 244 | RK_S32 max_count; 245 | MppCodingType type; 246 | 247 | /* output query count */ 248 | RK_S32 count; 249 | } RcApiQueryType; 250 | 251 | #ifdef __cplusplus 252 | extern "C" { 253 | #endif 254 | 255 | MPP_RET rc_api_add(const RcImplApi *api); 256 | MPP_RET rc_brief_get_all(RcApiQueryAll *query); 257 | MPP_RET rc_brief_get_by_type(RcApiQueryType *query); 258 | 259 | #ifdef __cplusplus 260 | } 261 | #endif 262 | 263 | #endif /* __MPP_RC_API_H__ */ 264 | -------------------------------------------------------------------------------- /mpp_inc/mpp_rc_defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __MPP_RC_DEFS_H__ 18 | #define __MPP_RC_DEFS_H__ 19 | 20 | #include "rk_venc_ref.h" 21 | 22 | #define MAX_CPB_REFS (8) 23 | 24 | typedef enum EncFrmType_e { 25 | INTER_P_FRAME = 0, 26 | INTER_B_FRAME = 1, 27 | INTRA_FRAME = 2, 28 | INTER_VI_FRAME = 3, 29 | INTRA_RFH_FRAME = 4, 30 | } EncFrmType; 31 | 32 | /* 33 | * EncFrmStatus controls record the encoding frame status and also control 34 | * work flow of encoder. It is the communicat channel between encoder implement 35 | * module, rate control module and hardware module. 36 | * 37 | * bit 0 ~ 31 frame status 38 | * 0 ~ 15 current frame status 39 | * 16 ~ 31 reference frame status 40 | * bit 32 ~ 63 encoding flow control 41 | */ 42 | typedef union EncFrmStatus_u { 43 | struct { 44 | /* 45 | * bit 0 ~ 31 frame status 46 | */ 47 | /* status flag */ 48 | RK_U32 valid : 1; 49 | /* 50 | * 0 - write the reconstructed frame pixel to memory 51 | * 1 - do not write the reconstructed frame pixel to memory 52 | */ 53 | RK_U32 non_recn : 1; 54 | 55 | /* 56 | * 0 - normal frame and normal dpb management 57 | * 1 - save recon frame as first pass extra frame. Used in two pass mode 58 | */ 59 | RK_U32 save_pass1 : 1; 60 | 61 | /* 62 | * 0 - use normal input source frame as input 63 | * 1 - use the previously stored first pass recon frame as input frame 64 | */ 65 | RK_U32 use_pass1 : 1; 66 | 67 | /* reference status flag */ 68 | /* 69 | * 0 - inter frame 70 | * 1 - intra frame 71 | */ 72 | RK_U32 is_intra : 1; 73 | 74 | /* 75 | * Valid when is_intra is true 76 | * 0 - normal intra frame 77 | * 1 - IDR frame 78 | */ 79 | RK_U32 is_idr : 1; 80 | 81 | /* 82 | * 0 - mark as reference frame 83 | * 1 - mark as non-refernce frame 84 | */ 85 | RK_U32 is_non_ref : 1; 86 | 87 | /* 88 | * Valid when is_non_ref is false 89 | * 0 - mark as short-term reference frame 90 | * 1 - mark as long-term refernce frame 91 | */ 92 | RK_U32 is_lt_ref : 1; 93 | 94 | /* bit 8 - 15 */ 95 | RK_U32 lt_idx : 4; 96 | RK_U32 temporal_id : 4; 97 | 98 | /* distance between current frame and reference frame */ 99 | MppEncRefMode ref_mode : 6; 100 | RK_S32 ref_arg : 8; 101 | RK_S32 ref_dist : 2; 102 | 103 | /* 104 | * bit 32 ~ 63 encoder flow control flags 105 | */ 106 | /* 107 | * 0 - normal frame encoding 108 | * 1 - current frame will be dropped 109 | */ 110 | RK_U32 drop : 1; 111 | 112 | /* 113 | * 0 - rate control module does not change frame type parameter 114 | * 1 - rate control module changes frame type parameter reencode is needed 115 | * to reprocess the dpb process. Also this means dpb module will follow 116 | * the frame status parameter provided by rate control module. 117 | */ 118 | RK_U32 re_dpb_proc : 1; 119 | 120 | /* 121 | * 0 - current frame encoding is in normal flow 122 | * 1 - current frame encoding is in reencode flow 123 | */ 124 | RK_U32 reencode : 1; 125 | 126 | /* 127 | * When true current frame size is super large then the frame should be reencoded. 128 | */ 129 | RK_U32 super_frame : 1; 130 | 131 | /* 132 | * When true currnet frame is force to encoded as software skip frame 133 | */ 134 | RK_U32 force_pskip : 1; 135 | 136 | /* 137 | * Current frame is intra refresh frame 138 | */ 139 | RK_U32 is_i_refresh : 1; 140 | /* 141 | * Current frame needs add recovery point prefix 142 | */ 143 | RK_U32 is_i_recovery : 1; 144 | RK_U32 reserved1 : 1; 145 | 146 | /* reencode times */ 147 | RK_U32 reencode_times : 8; 148 | 149 | /* sequential index for each frame */ 150 | RK_U32 seq_idx : 16; 151 | }; 152 | RK_U64 val; 153 | } EncFrmStatus; 154 | 155 | typedef struct EncCpbStatus_t { 156 | RK_S32 seq_idx; 157 | 158 | EncFrmStatus curr; 159 | EncFrmStatus refr; 160 | 161 | /* initial cpb status for current frame encoding */ 162 | EncFrmStatus init[MAX_CPB_REFS]; 163 | /* final cpb status after current frame encoding */ 164 | EncFrmStatus final[MAX_CPB_REFS]; 165 | } EncCpbStatus; 166 | 167 | #define ENC_RC_FORCE_QP (0x00000001) 168 | 169 | typedef struct EncRcForceCfg_t { 170 | RK_U32 force_flag; 171 | RK_S32 force_qp; 172 | RK_U32 reserve[6]; 173 | } EncRcForceCfg; 174 | 175 | /* 176 | * communication channel between rc / hal / hardware 177 | * 178 | * rc -> hal bit_target / bit_max / bit_min 179 | * hal -> hw quality_target / quality_max / quality_min 180 | * hw -> rc / hal bit_real / quality_real / madi / madp 181 | */ 182 | typedef struct EncRcCommonInfo_t { 183 | EncFrmType frame_type; 184 | 185 | /* rc to hal */ 186 | RK_S32 bit_target; 187 | RK_S32 bit_max; 188 | RK_S32 bit_min; 189 | 190 | RK_S32 quality_target; 191 | RK_S32 quality_max; 192 | RK_S32 quality_min; 193 | 194 | /* rc from hardware */ 195 | RK_S32 bit_real; 196 | RK_S32 quality_real; 197 | RK_S32 madi; 198 | RK_S32 madp; 199 | 200 | RK_U32 iblk4_prop; // scale 256 201 | 202 | RK_S64 sse; 203 | RK_U32 lvl64_inter_num; 204 | RK_U32 lvl32_inter_num; 205 | RK_U32 lvl16_inter_num; 206 | RK_U32 lvl8_inter_num; 207 | RK_U32 lvl32_intra_num; 208 | RK_U32 lvl16_intra_num; 209 | RK_U32 lvl8_intra_num; 210 | RK_U32 lvl4_intra_num; 211 | 212 | RK_S32 reserve[5]; 213 | } EncRcTaskInfo; 214 | 215 | typedef struct EncRcTask_s { 216 | EncCpbStatus cpb; 217 | EncFrmStatus frm; 218 | EncRcTaskInfo info; 219 | EncRcForceCfg force; 220 | MppFrame frame; 221 | } EncRcTask; 222 | 223 | #endif /* __MPP_RC_DEFS_H__ */ 224 | -------------------------------------------------------------------------------- /mpp_inc/rk_hdr_meta_com.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __RK_HDR_META_COM_H__ 18 | #define __RK_HDR_META_COM_H__ 19 | 20 | #include "rk_type.h" 21 | 22 | typedef enum HdrCodecType_e { 23 | HDR_AVS2 = 0, 24 | HDR_HEVC = 1, 25 | HDR_H264 = 2, 26 | HDR_AV1 = 3, 27 | HDR_CODEC_BUT, 28 | } HdrCodecType; 29 | 30 | typedef enum HdrFormat_e { 31 | HDR_NONE = 0, 32 | HDR10 = 1, 33 | HLG = 2, 34 | // RESERVED3 = 3, //reserved for more future static hdr format 35 | // RESERVED4 = 4, //reserved for more future static hdr format 36 | HDRVIVID = 5, 37 | // RESERVED6 = 6, //reserved for hdr vivid 38 | // RESERVED7 = 7, //reserved for hdr vivid 39 | HDR10PLUS = 8, 40 | // RESERVED9 = 9, //reserved for hdr10+ 41 | // RESERVED10 = 10,//reserved for hdr10+ 42 | DOLBY = 11, 43 | // RESERVED12 = 12, //reserved for other dynamic hdr format 44 | // RESERVED13 = 13, //reserved for other dynamic hdr format 45 | HDR_FORMAT_MAX, 46 | } HdrFormat; 47 | 48 | typedef enum HdrPayloadFormat_e { 49 | STATIC = 0, 50 | DYNAMIC = 1, 51 | HDR_PAYLOAD_FORMAT_MAX, 52 | } HdrPayloadFormat; 53 | 54 | typedef struct HdrStaticMeta_t { 55 | RK_U32 color_space; 56 | RK_U32 color_primaries; 57 | RK_U32 color_trc; 58 | RK_U32 red_x; 59 | RK_U32 red_y; 60 | RK_U32 green_x; 61 | RK_U32 green_y; 62 | RK_U32 blue_x; 63 | RK_U32 blue_y; 64 | RK_U32 white_point_x; 65 | RK_U32 white_point_y; 66 | RK_U32 min_luminance; 67 | RK_U32 max_luminance; 68 | RK_U32 max_cll; 69 | RK_U32 max_fall; 70 | RK_U32 reserved[4]; 71 | } HdrStaticMeta; 72 | 73 | /* 74 | * HDR metadata format from codec 75 | * 76 | * +----------+ 77 | * | header1 | 78 | * +----------+ 79 | * | | 80 | * | payload | 81 | * | | 82 | * +----------+ 83 | * | header2 | 84 | * +----------+ 85 | * | | 86 | * | payload | 87 | * | | 88 | * +----------+ 89 | * | header3 | 90 | * +----------+ 91 | * | | 92 | * | payload | 93 | * | | 94 | * +----------+ 95 | */ 96 | typedef struct RkMetaHdrHeader_t { 97 | /* For transmission */ 98 | RK_U16 magic; /* magic word for checking overwrite error */ 99 | RK_U16 size; /* total header+payload length including header */ 100 | RK_U16 message_total; /* total message count in current transmission */ 101 | RK_U16 message_index; /* current message index in the transmission */ 102 | 103 | /* For payload identification */ 104 | RK_U16 version; /* payload structure version */ 105 | RK_U16 hdr_format; /* HDR protocol: HDR10, HLG, Dolby, HDRVivid ... */ 106 | RK_U16 hdr_payload_type; /* HDR data type: static data, dynamic data ... */ 107 | RK_U16 video_format; /* video format: H.264, H.265, AVS2 ... */ 108 | 109 | /* For extenstion usage */ 110 | RK_U32 reserve[4]; 111 | 112 | /* payload data aligned to 32bits */ 113 | RK_U32 payload[]; 114 | } RkMetaHdrHeader; 115 | 116 | void fill_hdr_meta_to_frame(MppFrame frame, HdrCodecType codec_type); 117 | 118 | #endif 119 | -------------------------------------------------------------------------------- /mpp_inc/rk_type.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __RK_TYPE_H__ 18 | #define __RK_TYPE_H__ 19 | 20 | #include 21 | 22 | #if defined(_WIN32) && !defined(__MINGW32CE__) 23 | 24 | typedef unsigned char RK_U8; 25 | typedef unsigned short RK_U16; 26 | typedef unsigned int RK_U32; 27 | typedef unsigned long RK_ULONG; 28 | typedef unsigned __int64 RK_U64; 29 | 30 | typedef signed char RK_S8; 31 | typedef signed short RK_S16; 32 | typedef signed int RK_S32; 33 | typedef signed long RK_LONG; 34 | typedef signed __int64 RK_S64; 35 | 36 | #else 37 | 38 | typedef unsigned char RK_U8; 39 | typedef unsigned short RK_U16; 40 | typedef unsigned int RK_U32; 41 | typedef unsigned long RK_ULONG; 42 | typedef unsigned long long int RK_U64; 43 | 44 | 45 | typedef signed char RK_S8; 46 | typedef signed short RK_S16; 47 | typedef signed int RK_S32; 48 | typedef signed long RK_LONG; 49 | typedef signed long long int RK_S64; 50 | 51 | #endif 52 | 53 | #ifndef MODULE_TAG 54 | #define MODULE_TAG NULL 55 | #endif 56 | 57 | /** 58 | * @ingroup rk_mpi 59 | * @brief The type of mpp context 60 | * @details This type is used when calling mpp_init(), which including decoder, 61 | * encoder and Image Signal Process(ISP). So far decoder and encoder 62 | * are supported perfectly, and ISP will be supported in the future. 63 | */ 64 | typedef enum { 65 | MPP_CTX_DEC, /**< decoder */ 66 | MPP_CTX_ENC, /**< encoder */ 67 | MPP_CTX_ISP, /**< isp */ 68 | MPP_CTX_BUTT, /**< undefined */ 69 | } MppCtxType; 70 | 71 | /** 72 | * @ingroup rk_mpi 73 | * @brief Enumeration used to define the possible video compression codings. 74 | * sync with the omx_video.h 75 | * 76 | * @note This essentially refers to file extensions. If the coding is 77 | * being used to specify the ENCODE type, then additional work 78 | * must be done to configure the exact flavor of the compression 79 | * to be used. For decode cases where the user application can 80 | * not differentiate between MPEG-4 and H.264 bit streams, it is 81 | * up to the codec to handle this. 82 | */ 83 | typedef enum { 84 | MPP_VIDEO_CodingUnused, /**< Value when coding is N/A */ 85 | MPP_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */ 86 | MPP_VIDEO_CodingMPEG2, /**< AKA: H.262 */ 87 | MPP_VIDEO_CodingH263, /**< H.263 */ 88 | MPP_VIDEO_CodingMPEG4, /**< MPEG-4 */ 89 | MPP_VIDEO_CodingWMV, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ 90 | MPP_VIDEO_CodingRV, /**< all versions of Real Video */ 91 | MPP_VIDEO_CodingAVC, /**< H.264/AVC */ 92 | MPP_VIDEO_CodingMJPEG, /**< Motion JPEG */ 93 | MPP_VIDEO_CodingVP8, /**< VP8 */ 94 | MPP_VIDEO_CodingVP9, /**< VP9 */ 95 | MPP_VIDEO_CodingVC1 = 0x01000000, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ 96 | MPP_VIDEO_CodingFLV1, /**< Sorenson H.263 */ 97 | MPP_VIDEO_CodingDIVX3, /**< DIVX3 */ 98 | MPP_VIDEO_CodingVP6, 99 | MPP_VIDEO_CodingHEVC, /**< H.265/HEVC */ 100 | MPP_VIDEO_CodingAVSPLUS, /**< AVS+ */ 101 | MPP_VIDEO_CodingAVS, /**< AVS profile=0x20 */ 102 | MPP_VIDEO_CodingAVS2, /**< AVS2 */ 103 | MPP_VIDEO_CodingAV1, /**< av1 */ 104 | MPP_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 105 | MPP_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ 106 | MPP_VIDEO_CodingMax = 0x7FFFFFFF 107 | } MppCodingType; 108 | 109 | /* 110 | * All external interface object list here. 111 | * The interface object is defined as void * for expandability 112 | * The cross include between these objects will introduce extra 113 | * compiling difficulty. So we move them together in this header. 114 | * 115 | * Object interface header list: 116 | * 117 | * MppCtx - rk_mpi.h 118 | * MppParam - rk_mpi.h 119 | * 120 | * MppFrame - mpp_frame.h 121 | * MppPacket - mpp_packet.h 122 | * 123 | * MppBuffer - mpp_buffer.h 124 | * MppBufferGroup - mpp_buffer.h 125 | * 126 | * MppTask - mpp_task.h 127 | * MppMeta - mpp_meta.h 128 | */ 129 | 130 | typedef void* MppCtx; 131 | typedef void* MppParam; 132 | 133 | typedef void* MppFrame; 134 | typedef void* MppPacket; 135 | 136 | typedef void* MppBuffer; 137 | typedef void* MppBufferGroup; 138 | 139 | typedef void* MppTask; 140 | typedef void* MppMeta; 141 | 142 | #endif /*__RK_TYPE_H__*/ 143 | -------------------------------------------------------------------------------- /mpp_inc/rk_vdec_cfg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __RK_VDEC_CFG_H__ 18 | #define __RK_VDEC_CFG_H__ 19 | 20 | #include "rk_type.h" 21 | #include "mpp_err.h" 22 | 23 | typedef void* MppDecCfg; 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | MPP_RET mpp_dec_cfg_init(MppDecCfg *cfg); 30 | MPP_RET mpp_dec_cfg_deinit(MppDecCfg cfg); 31 | 32 | MPP_RET mpp_dec_cfg_set_s32(MppDecCfg cfg, const char *name, RK_S32 val); 33 | MPP_RET mpp_dec_cfg_set_u32(MppDecCfg cfg, const char *name, RK_U32 val); 34 | MPP_RET mpp_dec_cfg_set_s64(MppDecCfg cfg, const char *name, RK_S64 val); 35 | MPP_RET mpp_dec_cfg_set_u64(MppDecCfg cfg, const char *name, RK_U64 val); 36 | MPP_RET mpp_dec_cfg_set_ptr(MppDecCfg cfg, const char *name, void *val); 37 | 38 | MPP_RET mpp_dec_cfg_get_s32(MppDecCfg cfg, const char *name, RK_S32 *val); 39 | MPP_RET mpp_dec_cfg_get_u32(MppDecCfg cfg, const char *name, RK_U32 *val); 40 | MPP_RET mpp_dec_cfg_get_s64(MppDecCfg cfg, const char *name, RK_S64 *val); 41 | MPP_RET mpp_dec_cfg_get_u64(MppDecCfg cfg, const char *name, RK_U64 *val); 42 | MPP_RET mpp_dec_cfg_get_ptr(MppDecCfg cfg, const char *name, void **val); 43 | 44 | void mpp_dec_cfg_show(void); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif /*__RK_VDEC_CFG_H__*/ 51 | -------------------------------------------------------------------------------- /mpp_inc/rk_vdec_cmd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __RK_VDEC_CMD_H__ 18 | #define __RK_VDEC_CMD_H__ 19 | 20 | #include "rk_type.h" 21 | #include "mpp_err.h" 22 | 23 | /* 24 | * decoder query interface is only for debug usage 25 | */ 26 | #define MPP_DEC_QUERY_STATUS (0x00000001) 27 | #define MPP_DEC_QUERY_WAIT (0x00000002) 28 | #define MPP_DEC_QUERY_FPS (0x00000004) 29 | #define MPP_DEC_QUERY_BPS (0x00000008) 30 | #define MPP_DEC_QUERY_DEC_IN_PKT (0x00000010) 31 | #define MPP_DEC_QUERY_DEC_WORK (0x00000020) 32 | #define MPP_DEC_QUERY_DEC_OUT_FRM (0x00000040) 33 | 34 | #define MPP_DEC_QUERY_ALL (MPP_DEC_QUERY_STATUS | \ 35 | MPP_DEC_QUERY_WAIT | \ 36 | MPP_DEC_QUERY_FPS | \ 37 | MPP_DEC_QUERY_BPS | \ 38 | MPP_DEC_QUERY_DEC_IN_PKT | \ 39 | MPP_DEC_QUERY_DEC_WORK | \ 40 | MPP_DEC_QUERY_DEC_OUT_FRM) 41 | 42 | typedef struct MppDecQueryCfg_t { 43 | /* 44 | * 32 bit query flag for query data check 45 | * Each bit represent a query data switch. 46 | * bit 0 - for querying decoder runtime status 47 | * bit 1 - for querying decoder runtime waiting status 48 | * bit 2 - for querying decoder realtime decode fps 49 | * bit 3 - for querying decoder realtime input bps 50 | * bit 4 - for querying decoder input packet count 51 | * bit 5 - for querying decoder start hardware times 52 | * bit 6 - for querying decoder output frame count 53 | */ 54 | RK_U32 query_flag; 55 | 56 | /* 64 bit query data output */ 57 | RK_U32 rt_status; 58 | RK_U32 rt_wait; 59 | RK_U32 rt_fps; 60 | RK_U32 rt_bps; 61 | RK_U32 dec_in_pkt_cnt; 62 | RK_U32 dec_hw_run_cnt; 63 | RK_U32 dec_out_frm_cnt; 64 | } MppDecQueryCfg; 65 | 66 | typedef void* MppExtCbCtx; 67 | typedef MPP_RET (*MppExtCbFunc)(MppExtCbCtx cb_ctx, MppCtx mpp, RK_S32 cmd, void *arg); 68 | 69 | #endif /*__RK_VDEC_CMD_H__*/ 70 | -------------------------------------------------------------------------------- /mpp_inc/rk_venc_cfg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __RK_VENC_CFG_H__ 18 | #define __RK_VENC_CFG_H__ 19 | 20 | #include "rk_type.h" 21 | #include "mpp_err.h" 22 | 23 | typedef void* MppEncCfg; 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | MPP_RET mpp_enc_cfg_init(MppEncCfg *cfg); 30 | MPP_RET mpp_enc_cfg_deinit(MppEncCfg cfg); 31 | 32 | MPP_RET mpp_enc_cfg_set_s32(MppEncCfg cfg, const char *name, RK_S32 val); 33 | MPP_RET mpp_enc_cfg_set_u32(MppEncCfg cfg, const char *name, RK_U32 val); 34 | MPP_RET mpp_enc_cfg_set_s64(MppEncCfg cfg, const char *name, RK_S64 val); 35 | MPP_RET mpp_enc_cfg_set_u64(MppEncCfg cfg, const char *name, RK_U64 val); 36 | MPP_RET mpp_enc_cfg_set_ptr(MppEncCfg cfg, const char *name, void *val); 37 | MPP_RET mpp_enc_cfg_set_st(MppEncCfg cfg, const char *name, void *val); 38 | 39 | MPP_RET mpp_enc_cfg_get_s32(MppEncCfg cfg, const char *name, RK_S32 *val); 40 | MPP_RET mpp_enc_cfg_get_u32(MppEncCfg cfg, const char *name, RK_U32 *val); 41 | MPP_RET mpp_enc_cfg_get_s64(MppEncCfg cfg, const char *name, RK_S64 *val); 42 | MPP_RET mpp_enc_cfg_get_u64(MppEncCfg cfg, const char *name, RK_U64 *val); 43 | MPP_RET mpp_enc_cfg_get_ptr(MppEncCfg cfg, const char *name, void **val); 44 | MPP_RET mpp_enc_cfg_get_st(MppEncCfg cfg, const char *name, void *val); 45 | 46 | void mpp_enc_cfg_show(void); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif /*__RK_VENC_CFG_H__*/ 53 | -------------------------------------------------------------------------------- /mpp_inc/rk_venc_rc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __RK_VENC_RC_H__ 18 | #define __RK_VENC_RC_H__ 19 | 20 | #include "rk_type.h" 21 | 22 | #define MPP_ENC_MIN_BPS (SZ_1K) 23 | #define MPP_ENC_MAX_BPS (SZ_1M * 200) 24 | 25 | /* Rate control parameter */ 26 | typedef enum MppEncRcMode_e { 27 | MPP_ENC_RC_MODE_VBR, 28 | MPP_ENC_RC_MODE_CBR, 29 | MPP_ENC_RC_MODE_FIXQP, 30 | MPP_ENC_RC_MODE_AVBR, 31 | MPP_ENC_RC_MODE_BUTT 32 | } MppEncRcMode; 33 | 34 | typedef enum MppEncRcPriority_e { 35 | MPP_ENC_RC_BY_BITRATE_FIRST, 36 | MPP_ENC_RC_BY_FRM_SIZE_FIRST, 37 | MPP_ENC_RC_PRIORITY_BUTT 38 | } MppEncRcPriority; 39 | 40 | typedef enum MppEncRcDropFrmMode_e { 41 | MPP_ENC_RC_DROP_FRM_DISABLED, 42 | MPP_ENC_RC_DROP_FRM_NORMAL, 43 | MPP_ENC_RC_DROP_FRM_PSKIP, 44 | MPP_ENC_RC_DROP_FRM_BUTT 45 | } MppEncRcDropFrmMode; 46 | 47 | typedef enum MppEncRcSuperFrameMode_t { 48 | MPP_ENC_RC_SUPER_FRM_NONE, 49 | MPP_ENC_RC_SUPER_FRM_DROP, 50 | MPP_ENC_RC_SUPER_FRM_REENC, 51 | MPP_ENC_RC_SUPER_FRM_BUTT 52 | } MppEncRcSuperFrameMode; 53 | 54 | typedef enum MppEncRcGopMode_e { 55 | MPP_ENC_RC_NORMAL_P, 56 | MPP_ENC_RC_SMART_P, 57 | MPP_ENC_RC_GOP_MODE_BUTT, 58 | } MppEncRcGopMode; 59 | 60 | typedef enum MppEncRcIntraRefreshMode_e { 61 | MPP_ENC_RC_INTRA_REFRESH_ROW = 0, 62 | MPP_ENC_RC_INTRA_REFRESH_COL, 63 | MPP_ENC_RC_INTRA_REFRESH_BUTT 64 | } MppEncRcRefreshMode; 65 | 66 | #endif /*__RK_VENC_RC_H__*/ 67 | -------------------------------------------------------------------------------- /mpp_inc/vpu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Rockchip Electronics Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __VPU_H__ 18 | #define __VPU_H__ 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #include "rk_type.h" 25 | 26 | #define VPU_SUCCESS (0) 27 | #define VPU_FAILURE (-1) 28 | 29 | #define VPU_HW_WAIT_OK VPU_SUCCESS 30 | #define VPU_HW_WAIT_ERROR VPU_FAILURE 31 | #define VPU_HW_WAIT_TIMEOUT 1 32 | 33 | // vpu decoder 60 registers, size 240B 34 | #define VPU_REG_NUM_DEC (60) 35 | // vpu post processor 41 registers, size 164B 36 | #define VPU_REG_NUM_PP (41) 37 | // vpu decoder + post processor 101 registers, size 404B 38 | #define VPU_REG_NUM_DEC_PP (VPU_REG_NUM_DEC+VPU_REG_NUM_PP) 39 | // vpu encoder 96 registers, size 384B 40 | #define VPU_REG_NUM_ENC (96) 41 | 42 | typedef enum { 43 | VPU_ENC = 0x0, 44 | VPU_DEC = 0x1, 45 | VPU_PP = 0x2, 46 | VPU_DEC_PP = 0x3, 47 | VPU_DEC_HEVC = 0x4, 48 | VPU_DEC_RKV = 0x5, 49 | VPU_ENC_RKV = 0x6, 50 | VPU_DEC_AVSPLUS = 0x7, 51 | VPU_ENC_VEPU22 = 0x8, 52 | VPU_TYPE_BUTT , 53 | } VPU_CLIENT_TYPE; 54 | 55 | /* Hardware decoder configuration description */ 56 | 57 | typedef struct VPUHwDecConfig { 58 | RK_U32 maxDecPicWidth; /* Maximum video decoding width supported */ 59 | RK_U32 maxPpOutPicWidth; /* Maximum output width of Post-Processor */ 60 | RK_U32 h264Support; /* HW supports h.264 */ 61 | RK_U32 jpegSupport; /* HW supports JPEG */ 62 | RK_U32 mpeg4Support; /* HW supports MPEG-4 */ 63 | RK_U32 customMpeg4Support; /* HW supports custom MPEG-4 features */ 64 | RK_U32 vc1Support; /* HW supports VC-1 Simple */ 65 | RK_U32 mpeg2Support; /* HW supports MPEG-2 */ 66 | RK_U32 ppSupport; /* HW supports post-processor */ 67 | RK_U32 ppConfig; /* HW post-processor functions bitmask */ 68 | RK_U32 sorensonSparkSupport; /* HW supports Sorenson Spark */ 69 | RK_U32 refBufSupport; /* HW supports reference picture buffering */ 70 | RK_U32 vp6Support; /* HW supports VP6 */ 71 | RK_U32 vp7Support; /* HW supports VP7 */ 72 | RK_U32 vp8Support; /* HW supports VP8 */ 73 | RK_U32 avsSupport; /* HW supports AVS */ 74 | RK_U32 jpegESupport; /* HW supports JPEG extensions */ 75 | RK_U32 rvSupport; /* HW supports REAL */ 76 | RK_U32 mvcSupport; /* HW supports H264 MVC extension */ 77 | } VPUHwDecConfig_t; 78 | 79 | /* Hardware encoder configuration description */ 80 | 81 | typedef struct VPUHwEndConfig { 82 | RK_U32 maxEncodedWidth; /* Maximum supported width for video encoding (not JPEG) */ 83 | RK_U32 h264Enabled; /* HW supports H.264 */ 84 | RK_U32 jpegEnabled; /* HW supports JPEG */ 85 | RK_U32 mpeg4Enabled; /* HW supports MPEG-4 */ 86 | RK_U32 vsEnabled; /* HW supports video stabilization */ 87 | RK_U32 rgbEnabled; /* HW supports RGB input */ 88 | RK_U32 reg_size; /* HW bus type in use */ 89 | RK_U32 reserv[2]; 90 | } VPUHwEncConfig_t; 91 | 92 | typedef enum { 93 | // common command 94 | VPU_CMD_REGISTER , 95 | VPU_CMD_REGISTER_ACK_OK , 96 | VPU_CMD_REGISTER_ACK_FAIL , 97 | VPU_CMD_UNREGISTER , 98 | 99 | VPU_SEND_CONFIG , 100 | VPU_SEND_CONFIG_ACK_OK , 101 | VPU_SEND_CONFIG_ACK_FAIL , 102 | 103 | VPU_GET_HW_INFO , 104 | VPU_GET_HW_INFO_ACK_OK , 105 | VPU_GET_HW_INFO_ACK_FAIL , 106 | 107 | VPU_CMD_BUTT , 108 | } VPU_CMD_TYPE; 109 | 110 | int VPUClientInit(VPU_CLIENT_TYPE type); 111 | RK_S32 VPUClientRelease(int socket); 112 | RK_S32 VPUClientSendReg(int socket, RK_U32 *regs, RK_U32 nregs); 113 | RK_S32 VPUClientSendReg2(RK_S32 socket, RK_S32 offset, RK_S32 size, void *param); 114 | RK_S32 VPUClientWaitResult(int socket, RK_U32 *regs, RK_U32 nregs, VPU_CMD_TYPE *cmd, RK_S32 *len); 115 | RK_S32 VPUClientGetHwCfg(int socket, RK_U32 *cfg, RK_U32 cfg_size); 116 | RK_S32 VPUClientGetIOMMUStatus(); 117 | RK_U32 VPUCheckSupportWidth(); 118 | 119 | #ifdef __cplusplus 120 | } 121 | #endif 122 | 123 | #endif /* __VPU_H__ */ 124 | -------------------------------------------------------------------------------- /mpp_libs/libmk_api.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MontaukLaw/3588_multi_rtsp_decode/91405545382f0ab3e18f4669e7c819e0281180bd/mpp_libs/libmk_api.so -------------------------------------------------------------------------------- /mpp_libs/libutils.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MontaukLaw/3588_multi_rtsp_decode/91405545382f0ab3e18f4669e7c819e0281180bd/mpp_libs/libutils.a -------------------------------------------------------------------------------- /rtsp.list: -------------------------------------------------------------------------------- 1 | rtsp://192.168.1.10:554/stream1 2 | rtsp://192.168.1.10:554/stream1 3 | rtsp://192.168.1.10:554/stream1 4 | rtsp://192.168.1.10:554/stream1 5 | rtsp://192.168.1.10:554/stream1 6 | rtsp://192.168.1.10:554/stream1 7 | rtsp://192.168.1.10:554/stream1 8 | rtsp://192.168.1.10:554/stream1 9 | rtsp://192.168.1.10:554/stream1 10 | -------------------------------------------------------------------------------- /src/bo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Rockchip Electronics S.LSI Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "bo.h" 17 | 18 | void fill_bo(struct sp_bo* bo, uint8_t a, uint8_t r, uint8_t g, uint8_t b) 19 | { 20 | draw_rect(bo, 0, 0, bo->width, bo->height, a, r, g, b); 21 | } 22 | 23 | void draw_rect(struct sp_bo* bo, uint32_t x, uint32_t y, uint32_t width, 24 | uint32_t height, uint8_t a, uint8_t r, uint8_t g, uint8_t b) 25 | { 26 | uint32_t i, j, xmax = x + width, ymax = y + height; 27 | 28 | if (xmax > bo->width) 29 | xmax = bo->width; 30 | if (ymax > bo->height) 31 | ymax = bo->height; 32 | 33 | for (i = y; i < ymax; i++) { 34 | uint8_t* row = (uint8_t*)bo->map_addr + i * bo->pitch; 35 | 36 | for (j = x; j < xmax; j++) { 37 | uint8_t* pixel = row + j * 4; 38 | 39 | if (bo->format == DRM_FORMAT_ARGB8888 || bo->format == DRM_FORMAT_XRGB8888) { 40 | pixel[0] = b; 41 | pixel[1] = g; 42 | pixel[2] = r; 43 | pixel[3] = a; 44 | } else if (bo->format == DRM_FORMAT_RGBA8888) { 45 | pixel[0] = r; 46 | pixel[1] = g; 47 | pixel[2] = b; 48 | pixel[3] = a; 49 | } 50 | } 51 | } 52 | } 53 | 54 | int add_fb_sp_bo(struct sp_bo* bo, uint32_t format) 55 | { 56 | int ret; 57 | uint32_t handles[4], pitches[4], offsets[4]; 58 | 59 | handles[0] = bo->handle; 60 | pitches[0] = bo->pitch; 61 | offsets[0] = 0; 62 | 63 | if(format == DRM_FORMAT_NV12 || format == DRM_FORMAT_NV16) { 64 | handles[1] = bo->handle; 65 | pitches[0] = bo->width; 66 | pitches[1] = bo->width; 67 | offsets[1] = bo->width * bo->height; 68 | } 69 | 70 | ret = drmModeAddFB2(bo->dev->fd, bo->width, bo->height, 71 | format, handles, pitches, offsets, 72 | &bo->fb_id, bo->flags); 73 | if (ret) { 74 | printf("failed to create fb ret=%d\n", ret); 75 | return ret; 76 | } 77 | return 0; 78 | } 79 | 80 | static int map_sp_bo(struct sp_bo* bo) 81 | { 82 | int ret; 83 | struct drm_mode_map_dumb md; 84 | 85 | if (bo->map_addr) 86 | return 0; 87 | 88 | md.handle = bo->handle; 89 | ret = drmIoctl(bo->dev->fd, DRM_IOCTL_MODE_MAP_DUMB, &md); 90 | if (ret) { 91 | printf("failed to map sp_bo ret=%d\n", ret); 92 | return ret; 93 | } 94 | 95 | bo->map_addr = mmap(NULL, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, 96 | bo->dev->fd, md.offset); 97 | if (bo->map_addr == MAP_FAILED) { 98 | printf("failed to map bo ret=%d\n", -errno); 99 | return -errno; 100 | } 101 | return 0; 102 | } 103 | 104 | struct sp_bo* create_sp_bo(struct sp_dev* dev, uint32_t width, uint32_t height, 105 | uint32_t depth, uint32_t bpp, uint32_t format, uint32_t flags) 106 | { 107 | int ret; 108 | struct drm_mode_create_dumb cd; 109 | struct sp_bo* bo; 110 | 111 | memset(&cd, 0, sizeof(cd)); 112 | 113 | bo = (struct sp_bo *) calloc(1, sizeof(*bo)); 114 | if (!bo) 115 | return NULL; 116 | 117 | cd.height = height; 118 | cd.width = width; 119 | cd.bpp = bpp; 120 | cd.flags = flags; 121 | 122 | ret = drmIoctl(dev->fd, DRM_IOCTL_MODE_CREATE_DUMB, &cd); 123 | if (ret) { 124 | printf("failed to create sp_bo %d\n", ret); 125 | goto err; 126 | } 127 | 128 | bo->dev = dev; 129 | bo->width = width; 130 | bo->height = height; 131 | bo->depth = depth; 132 | bo->bpp = bpp; 133 | bo->format = format; 134 | bo->flags = flags; 135 | 136 | bo->handle = cd.handle; 137 | bo->pitch = cd.pitch; 138 | bo->size = cd.size; 139 | 140 | ret = add_fb_sp_bo(bo, format); 141 | if (ret) { 142 | printf("failed to add fb ret=%d\n", ret); 143 | goto err; 144 | } 145 | 146 | ret = map_sp_bo(bo); 147 | if (ret) { 148 | printf("failed to map bo ret=%d\n", ret); 149 | goto err; 150 | } 151 | 152 | return bo; 153 | 154 | err: 155 | free_sp_bo(bo); 156 | return NULL; 157 | } 158 | 159 | void free_sp_bo(struct sp_bo* bo) 160 | { 161 | int ret; 162 | struct drm_mode_destroy_dumb dd; 163 | 164 | if (!bo) 165 | return; 166 | 167 | if (bo->map_addr) 168 | munmap(bo->map_addr, bo->size); 169 | 170 | if (bo->fb_id) { 171 | ret = drmModeRmFB(bo->dev->fd, bo->fb_id); 172 | if (ret) 173 | printf("Failed to rmfb ret=%d!\n", ret); 174 | } 175 | 176 | if (bo->handle) { 177 | dd.handle = bo->handle; 178 | ret = drmIoctl(bo->dev->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dd); 179 | if (ret) 180 | printf("Failed to destroy buffer ret=%d\n", ret); 181 | } 182 | 183 | free(bo); 184 | } -------------------------------------------------------------------------------- /src/coco_80_labels_list.txt: -------------------------------------------------------------------------------- 1 | person 2 | bicycle 3 | car 4 | motorcycle 5 | airplane 6 | bus 7 | train 8 | truck 9 | boat 10 | traffic light 11 | fire hydrant 12 | stop sign 13 | parking meter 14 | bench 15 | bird 16 | cat 17 | dog 18 | horse 19 | sheep 20 | cow 21 | elephant 22 | bear 23 | zebra 24 | giraffe 25 | backpack 26 | umbrella 27 | handbag 28 | tie 29 | suitcase 30 | frisbee 31 | skis 32 | snowboard 33 | sports ball 34 | kite 35 | baseball bat 36 | baseball glove 37 | skateboard 38 | surfboard 39 | tennis racket 40 | bottle 41 | wine glass 42 | cup 43 | fork 44 | knife 45 | spoon 46 | bowl 47 | banana 48 | apple 49 | sandwich 50 | orange 51 | broccoli 52 | carrot 53 | hot dog 54 | pizza 55 | donut 56 | cake 57 | chair 58 | couch 59 | potted plant 60 | bed 61 | dining table 62 | toilet 63 | tv 64 | laptop 65 | mouse 66 | remote 67 | keyboard 68 | cell phone 69 | microwave 70 | oven 71 | toaster 72 | sink 73 | refrigerator 74 | book 75 | clock 76 | vase 77 | scissors 78 | teddy bear 79 | hair drier 80 | toothbrush 81 | -------------------------------------------------------------------------------- /src/dev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Rockchip Electronics S.LSI Co. LTD 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "dev.h" 17 | 18 | #if 0 // def USE_ATOMIC_API 19 | static uint32_t get_prop_id(struct sp_dev *dev, 20 | drmModeObjectPropertiesPtr props, const char *name){ 21 | drmModePropertyPtr p; 22 | uint32_t i, prop_id = 0; /* Property ID should always be > 0 */ 23 | 24 | for (i = 0; !prop_id && i < props->count_props; i++) { 25 | p = drmModeGetProperty(dev->fd, props->props[i]); 26 | if (!strcmp(p->name, name)) 27 | prop_id = p->prop_id; 28 | drmModeFreeProperty(p); 29 | } 30 | if (!prop_id) 31 | printf("Could not find %s property\n", name); 32 | return prop_id; 33 | } 34 | #endif 35 | 36 | int is_supported_format(struct sp_plane *plane, uint32_t format) 37 | { 38 | uint32_t i; 39 | 40 | for (i = 0; i < plane->plane->count_formats; i++) 41 | { 42 | if (plane->plane->formats[i] == format) 43 | return 1; 44 | } 45 | return 0; 46 | } 47 | 48 | static int get_supported_format(struct sp_plane *plane, uint32_t *format) 49 | { 50 | uint32_t i; 51 | 52 | for (i = 0; i < plane->plane->count_formats; i++) 53 | { 54 | if (plane->plane->formats[i] == DRM_FORMAT_XRGB8888 || plane->plane->formats[i] == DRM_FORMAT_ARGB8888 || plane->plane->formats[i] == DRM_FORMAT_RGBA8888) 55 | { 56 | *format = plane->plane->formats[i]; 57 | return 0; 58 | } 59 | } 60 | printf("No suitable formats found!\n"); 61 | return -ENOENT; 62 | } 63 | 64 | // 创建显示设备 65 | struct sp_dev *create_sp_dev(void) 66 | { 67 | struct sp_dev *dev; 68 | int ret, fd, i, j; 69 | drmModeRes *r = NULL; 70 | drmModePlaneRes *pr = NULL; 71 | 72 | // 打开设备/dev/dri/card0 73 | fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC); 74 | if (fd < 0) 75 | { 76 | printf("failed to open card0\n"); 77 | return NULL; 78 | } 79 | 80 | // 申请内存 81 | dev = (struct sp_dev *)calloc(1, sizeof(*dev)); 82 | if (!dev) 83 | { 84 | printf("failed to allocate dev\n"); 85 | return NULL; 86 | } 87 | 88 | // 记录显示设备的fd 89 | dev->fd = fd; 90 | 91 | // 设置显示 92 | ret = drmSetClientCap(dev->fd, DRM_CLIENT_CAP_ATOMIC, 1); 93 | if (ret) 94 | { 95 | printf("failed to set client cap atomic\n"); 96 | goto err; 97 | } 98 | ret = drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); 99 | if (ret) 100 | { 101 | printf("failed to set client cap\n"); 102 | goto err; 103 | } 104 | 105 | r = drmModeGetResources(dev->fd); 106 | if (!r) 107 | { 108 | printf("failed to get r\n"); 109 | goto err; 110 | } 111 | 112 | // 获取显示设备总共的connector数量 113 | dev->num_connectors = r->count_connectors; 114 | dev->connectors = (drmModeConnectorPtr *)calloc(dev->num_connectors, sizeof(*dev->connectors)); 115 | if (!dev->connectors) 116 | { 117 | printf("failed to allocate connectors\n"); 118 | goto err; 119 | } 120 | 121 | // 分别获取connector, 就是hdmi/dsi等硬件连接 122 | for (i = 0; i < dev->num_connectors; i++) 123 | { 124 | dev->connectors[i] = drmModeGetConnector(dev->fd, r->connectors[i]); 125 | if (!dev->connectors[i]) 126 | { 127 | printf("failed to get connector %d\n", i); 128 | goto err; 129 | } 130 | } 131 | 132 | printf("encoders number:%d\n", r->count_encoders); 133 | 134 | // 获取编码器(这个编码器是硬件的协议编码器, 跟视频编解码器两回事) 135 | dev->num_encoders = r->count_encoders; 136 | dev->encoders = (drmModeEncoderPtr *)calloc(dev->num_encoders, sizeof(*dev->encoders)); 137 | if (!dev->encoders) 138 | { 139 | printf("failed to allocate encoders\n"); 140 | goto err; 141 | } 142 | 143 | for (i = 0; i < dev->num_encoders; i++) 144 | { 145 | dev->encoders[i] = drmModeGetEncoder(dev->fd, r->encoders[i]); 146 | if (!dev->encoders[i]) 147 | { 148 | printf("failed to get encoder %d\n", i); 149 | goto err; 150 | } 151 | } 152 | 153 | dev->num_crtcs = r->count_crtcs; 154 | dev->crtcs = (struct sp_crtc *)calloc(dev->num_crtcs, sizeof(struct sp_crtc)); 155 | if (!dev->crtcs) 156 | { 157 | printf("failed to allocate crtcs\n"); 158 | goto err; 159 | } 160 | 161 | for (i = 0; i < dev->num_crtcs; i++) 162 | { 163 | dev->crtcs[i].crtc = drmModeGetCrtc(dev->fd, r->crtcs[i]); 164 | if (!dev->crtcs[i].crtc) 165 | { 166 | printf("failed to get crtc %d\n", i); 167 | goto err; 168 | } 169 | dev->crtcs[i].scanout = NULL; 170 | dev->crtcs[i].pipe = i; 171 | dev->crtcs[i].num_planes = 0; 172 | } 173 | 174 | pr = drmModeGetPlaneResources(dev->fd); 175 | if (!pr) 176 | { 177 | printf("failed to get plane resources\n"); 178 | goto err; 179 | } 180 | dev->num_planes = pr->count_planes; 181 | dev->planes = (struct sp_plane *)calloc(dev->num_planes, sizeof(struct sp_plane)); 182 | for (i = 0; i < dev->num_planes; i++) 183 | { 184 | drmModeObjectPropertiesPtr props; 185 | struct sp_plane *plane = &dev->planes[i]; 186 | 187 | plane->dev = dev; 188 | plane->plane = drmModeGetPlane(dev->fd, pr->planes[i]); 189 | if (!plane->plane) 190 | { 191 | printf("failed to get plane %d\n", i); 192 | goto err; 193 | } 194 | plane->bo = NULL; 195 | plane->in_use = 0; 196 | 197 | ret = get_supported_format(plane, &plane->format); 198 | if (ret) 199 | { 200 | printf("failed to get supported format: %d\n", ret); 201 | goto err; 202 | } 203 | 204 | for (j = 0; j < dev->num_crtcs; j++) 205 | { 206 | if (plane->plane->possible_crtcs & (1 << j)) 207 | dev->crtcs[j].num_planes++; 208 | } 209 | } 210 | 211 | if (pr) 212 | drmModeFreePlaneResources(pr); 213 | if (r) 214 | drmModeFreeResources(r); 215 | 216 | return dev; 217 | err: 218 | if (pr) 219 | drmModeFreePlaneResources(pr); 220 | if (r) 221 | drmModeFreeResources(r); 222 | destroy_sp_dev(dev); 223 | return NULL; 224 | } 225 | 226 | void destroy_sp_dev(struct sp_dev *dev) 227 | { 228 | int i; 229 | 230 | if (dev->planes) 231 | { 232 | for (i = 0; i < dev->num_planes; i++) 233 | { 234 | if (dev->planes[i].in_use) 235 | put_sp_plane(&dev->planes[i]); 236 | if (dev->planes[i].plane) 237 | drmModeFreePlane(dev->planes[i].plane); 238 | if (dev->planes[i].bo) 239 | free_sp_bo(dev->planes[i].bo); 240 | } 241 | free(dev->planes); 242 | } 243 | if (dev->crtcs) 244 | { 245 | for (i = 0; i < dev->num_crtcs; i++) 246 | { 247 | if (dev->crtcs[i].crtc) 248 | drmModeFreeCrtc(dev->crtcs[i].crtc); 249 | if (dev->crtcs[i].scanout) 250 | free_sp_bo(dev->crtcs[i].scanout); 251 | } 252 | free(dev->crtcs); 253 | } 254 | if (dev->encoders) 255 | { 256 | for (i = 0; i < dev->num_encoders; i++) 257 | { 258 | if (dev->encoders[i]) 259 | drmModeFreeEncoder(dev->encoders[i]); 260 | } 261 | free(dev->encoders); 262 | } 263 | if (dev->connectors) 264 | { 265 | for (i = 0; i < dev->num_connectors; i++) 266 | { 267 | if (dev->connectors[i]) 268 | drmModeFreeConnector(dev->connectors[i]); 269 | } 270 | free(dev->connectors); 271 | } 272 | 273 | close(dev->fd); 274 | free(dev); 275 | } 276 | -------------------------------------------------------------------------------- /src/draw/cv_draw.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "cv_draw.h" 3 | 4 | #include "utils/logging.h" 5 | 6 | // 在img上画出检测结果 7 | void DrawDetections(cv::Mat &img, const std::vector &objects) 8 | { 9 | NN_LOG_DEBUG("draw %ld objects", objects.size()); 10 | for (const auto &object : objects) 11 | { 12 | cv::rectangle(img, object.box, object.color, 2); 13 | // class name with confidence 14 | std::string draw_string = object.className + " " + std::to_string(object.confidence); 15 | 16 | cv::putText(img, draw_string, cv::Point(object.box.x, object.box.y - 5), cv::FONT_HERSHEY_SIMPLEX, 1, 17 | cv::Scalar(255, 0, 255), 2); 18 | } 19 | } -------------------------------------------------------------------------------- /src/draw/cv_draw.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef RK3588_DEMO_CV_DRAW_H 4 | #define RK3588_DEMO_CV_DRAW_H 5 | 6 | #include 7 | 8 | #include "types/yolo_datatype.h" 9 | 10 | // draw detections on img 11 | void DrawDetections(cv::Mat& img, const std::vector& objects); 12 | 13 | #endif //RK3588_DEMO_CV_DRAW_H 14 | -------------------------------------------------------------------------------- /src/engine/engine.h: -------------------------------------------------------------------------------- 1 | // 接口定义 2 | 3 | #ifndef RK3588_DEMO_ENGINE_H 4 | #define RK3588_DEMO_ENGINE_H 5 | 6 | #include "types/error.h" 7 | #include "types/datatype.h" 8 | 9 | #include 10 | #include 11 | 12 | class NNEngine 13 | { 14 | public: 15 | // 这里全部使用纯虚函数(=0),作用是将NNEngine定义为一个抽象类,不能实例化,只能作为基类使用 16 | // 具体实现需要在子类中实现,这里的实现只是为了定义接口 17 | // 用这种方式实现封装,可以使得不同的引擎的接口一致,方便使用;也可以隐藏不同引擎的实现细节,方便维护 18 | virtual ~NNEngine(){}; // 析构函数 19 | virtual nn_error_e LoadModelFile(const char *model_file) = 0; // 加载模型文件,=0表示纯虚函数,必须在子类中实现 20 | virtual const std::vector &GetInputShapes() = 0; // 获取输入张量的形状 21 | virtual const std::vector &GetOutputShapes() = 0; // 获取输出张量的形状 22 | virtual nn_error_e Run(std::vector &inputs, std::vector &outpus, bool want_float) = 0; // 运行模型 23 | 24 | }; 25 | 26 | std::shared_ptr CreateRKNNEngine(); // 创建RKNN引擎 27 | 28 | #endif // RK3588_DEMO_ENGINE_H 29 | -------------------------------------------------------------------------------- /src/engine/rknn_engine.cpp: -------------------------------------------------------------------------------- 1 | // rknn_engine.h的实现 2 | 3 | #include "rknn_engine.h" 4 | 5 | #include 6 | 7 | #include "utils/engine_helper.h" 8 | #include "utils/logging.h" 9 | 10 | static const int g_max_io_num = 10; // 最大输入输出张量的数量 11 | 12 | /** 13 | * @brief 加载模型文件、初始化rknn context、获取rknn版本信息、获取输入输出张量的信息 14 | * @param model_file 模型文件路径 15 | * @return nn_error_e 错误码 16 | */ 17 | nn_error_e RKEngine::LoadModelFile(const char *model_file) 18 | { 19 | int model_len = 0; // 模型文件大小 20 | auto model = load_model(model_file, &model_len); // 加载模型文件 21 | if (model == nullptr) 22 | { 23 | NN_LOG_ERROR("load model file %s fail!", model_file); 24 | return NN_LOAD_MODEL_FAIL; // 返回错误码:加载模型文件失败 25 | } 26 | int ret = rknn_init(&rknn_ctx_, model, model_len, 0, NULL); // 初始化rknn context 27 | if (ret < 0) 28 | { 29 | NN_LOG_ERROR("rknn_init fail! ret=%d", ret); 30 | return NN_RKNN_INIT_FAIL; // 返回错误码:初始化rknn context失败 31 | } 32 | // 打印初始化成功信息 33 | NN_LOG_INFO("rknn_init success!"); 34 | ctx_created_ = true; 35 | 36 | // 获取rknn版本信息 37 | rknn_sdk_version version; 38 | ret = rknn_query(rknn_ctx_, RKNN_QUERY_SDK_VERSION, &version, sizeof(rknn_sdk_version)); 39 | if (ret < 0) 40 | { 41 | NN_LOG_ERROR("rknn_query fail! ret=%d", ret); 42 | return NN_RKNN_QUERY_FAIL; 43 | } 44 | // 打印rknn版本信息 45 | NN_LOG_INFO("RKNN API version: %s", version.api_version); 46 | NN_LOG_INFO("RKNN Driver version: %s", version.drv_version); 47 | 48 | // 获取输入输出个数 49 | rknn_input_output_num io_num; 50 | ret = rknn_query(rknn_ctx_, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num)); 51 | if (ret != RKNN_SUCC) 52 | { 53 | NN_LOG_ERROR("rknn_query fail! ret=%d", ret); 54 | return NN_RKNN_QUERY_FAIL; 55 | } 56 | NN_LOG_INFO("model input num: %d, output num: %d", io_num.n_input, io_num.n_output); 57 | 58 | // 保存输入输出个数 59 | input_num_ = io_num.n_input; 60 | output_num_ = io_num.n_output; 61 | 62 | // 输入属性 63 | NN_LOG_INFO("input tensors:"); 64 | rknn_tensor_attr input_attrs[io_num.n_input]; 65 | memset(input_attrs, 0, sizeof(input_attrs)); 66 | for (int i = 0; i < io_num.n_input; i++) 67 | { 68 | input_attrs[i].index = i; 69 | ret = rknn_query(rknn_ctx_, RKNN_QUERY_INPUT_ATTR, &(input_attrs[i]), sizeof(rknn_tensor_attr)); 70 | if (ret != RKNN_SUCC) 71 | { 72 | NN_LOG_ERROR("rknn_query fail! ret=%d", ret); 73 | return NN_RKNN_QUERY_FAIL; 74 | } 75 | print_tensor_attr(&(input_attrs[i])); 76 | // set input_shapes_ 77 | in_shapes_.push_back(rknn_tensor_attr_convert(input_attrs[i])); 78 | } 79 | 80 | // 输出属性 81 | NN_LOG_INFO("output tensors:"); 82 | rknn_tensor_attr output_attrs[io_num.n_output]; 83 | memset(output_attrs, 0, sizeof(output_attrs)); 84 | for (int i = 0; i < io_num.n_output; i++) 85 | { 86 | output_attrs[i].index = i; 87 | ret = rknn_query(rknn_ctx_, RKNN_QUERY_OUTPUT_ATTR, &(output_attrs[i]), sizeof(rknn_tensor_attr)); 88 | if (ret != RKNN_SUCC) 89 | { 90 | NN_LOG_ERROR("rknn_query fail! ret=%d", ret); 91 | return NN_RKNN_QUERY_FAIL; 92 | } 93 | print_tensor_attr(&(output_attrs[i])); 94 | // set output_shapes_ 95 | out_shapes_.push_back(rknn_tensor_attr_convert(output_attrs[i])); 96 | } 97 | 98 | return NN_SUCCESS; 99 | } 100 | 101 | // 获取输入张量的形状 102 | const std::vector &RKEngine::GetInputShapes() 103 | { 104 | return in_shapes_; 105 | } 106 | 107 | // 获取输出张量的形状 108 | const std::vector &RKEngine::GetOutputShapes() 109 | { 110 | return out_shapes_; 111 | } 112 | 113 | /** 114 | * @brief 运行模型,获得推理结果 115 | * @param inputs 输入张量 116 | * @param outputs 输出张量 117 | * @param want_float 是否需要float类型的输出 118 | * @return nn_error_e 错误码 119 | */ 120 | nn_error_e RKEngine::Run(std::vector &inputs, std::vector &outputs, bool want_float) 121 | { 122 | // 检查输入输出张量的数量是否匹配 123 | if (inputs.size() != input_num_) 124 | { 125 | NN_LOG_ERROR("inputs num not match! inputs.size()=%ld, input_num_=%d", inputs.size(), input_num_); 126 | return NN_IO_NUM_NOT_MATCH; 127 | } 128 | if (outputs.size() != output_num_) 129 | { 130 | NN_LOG_ERROR("outputs num not match! outputs.size()=%ld, output_num_=%d", outputs.size(), output_num_); 131 | return NN_IO_NUM_NOT_MATCH; 132 | } 133 | 134 | // 设置rknn inputs 135 | rknn_input rknn_inputs[g_max_io_num]; 136 | for (int i = 0; i < inputs.size(); i++) 137 | { 138 | // 将自定义的tensor_data_s转换为rknn_input 139 | rknn_inputs[i] = tensor_data_to_rknn_input(inputs[i]); 140 | } 141 | int ret = rknn_inputs_set(rknn_ctx_, (uint32_t)inputs.size(), rknn_inputs); 142 | if (ret < 0) 143 | { 144 | NN_LOG_ERROR("rknn_inputs_set fail! ret=%d", ret); 145 | return NN_RKNN_INPUT_SET_FAIL; 146 | } 147 | 148 | // 推理 149 | NN_LOG_DEBUG("rknn running..."); 150 | ret = rknn_run(rknn_ctx_, nullptr); 151 | if (ret < 0) 152 | { 153 | NN_LOG_ERROR("rknn_run fail! ret=%d", ret); 154 | return NN_RKNN_RUNTIME_ERROR; 155 | } 156 | 157 | // 获得输出 158 | rknn_output rknn_outputs[g_max_io_num]; 159 | memset(rknn_outputs, 0, sizeof(rknn_outputs)); 160 | for (int i = 0; i < output_num_; ++i) 161 | { 162 | rknn_outputs[i].want_float = want_float ? 1 : 0; 163 | } 164 | ret = rknn_outputs_get(rknn_ctx_, output_num_, rknn_outputs, NULL); 165 | if (ret < 0) 166 | { 167 | printf("rknn_outputs_get fail! ret=%d\n", ret); 168 | NN_LOG_ERROR("rknn_outputs_get fail! ret=%d", ret); 169 | return NN_RKNN_OUTPUT_GET_FAIL; 170 | } 171 | 172 | NN_LOG_DEBUG("output num: %d", output_num_); 173 | // copy rknn outputs to tensor_data_s 174 | for (int i = 0; i < output_num_; ++i) 175 | { 176 | // 将rknn_output转换为自定义的tensor_data_s 177 | rknn_output_to_tensor_data(rknn_outputs[i], outputs[i]); 178 | NN_LOG_DEBUG("output[%d] size=%d", i, outputs[i].attr.size); 179 | free(rknn_outputs[i].buf); // 释放缓存 180 | } 181 | return NN_SUCCESS; 182 | } 183 | 184 | // 析构函数 185 | RKEngine::~RKEngine() 186 | { 187 | if (ctx_created_) 188 | { 189 | rknn_destroy(rknn_ctx_); 190 | NN_LOG_INFO("rknn context destroyed!"); 191 | } 192 | } 193 | 194 | // 创建RKNN引擎 195 | std::shared_ptr CreateRKNNEngine() 196 | { 197 | return std::make_shared(); 198 | } 199 | -------------------------------------------------------------------------------- /src/engine/rknn_engine.h: -------------------------------------------------------------------------------- 1 | // 继承自NNEngine,实现NNEngine的接口 2 | 3 | #ifndef RK3588_DEMO_RKNN_ENGINE_H 4 | #define RK3588_DEMO_RKNN_ENGINE_H 5 | 6 | #include "engine.h" 7 | 8 | #include 9 | 10 | #include 11 | 12 | // 继承自NNEngine,实现NNEngine的接口 13 | class RKEngine : public NNEngine 14 | { 15 | public: 16 | RKEngine() : rknn_ctx_(0), ctx_created_(false), input_num_(0), output_num_(0){}; // 构造函数,初始化 17 | ~RKEngine() override; // 析构函数 18 | 19 | nn_error_e LoadModelFile(const char *model_file) override; // 加载模型文件 20 | const std::vector &GetInputShapes() override; // 获取输入张量的形状 21 | const std::vector &GetOutputShapes() override; // 获取输出张量的形状 22 | nn_error_e Run(std::vector &inputs, std::vector &outputs, bool want_float) override; // 运行模型 23 | 24 | private: 25 | // rknn context 26 | rknn_context rknn_ctx_; // rknn context 27 | bool ctx_created_; // rknn context是否创建 28 | 29 | uint32_t input_num_; // 输入的数量 30 | uint32_t output_num_; // 输出的数量 31 | 32 | std::vector in_shapes_; // 输入张量的形状 33 | std::vector out_shapes_; // 输出张量的形状 34 | }; 35 | 36 | #endif // RK3588_DEMO_RKNN_ENGINE_H 37 | -------------------------------------------------------------------------------- /src/media/ffmpeg_source.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "mpi_dec.h" 4 | extern "C" 5 | { 6 | #include 7 | } 8 | 9 | static int g_source_width; 10 | static int g_source_height; 11 | 12 | static int ready = 0; 13 | 14 | extern int decode_simple(MpiDecLoopData *data, AVPacket *av_packet); 15 | 16 | void get_source_shape(int *width, int *height) 17 | { 18 | while (!ready) 19 | { 20 | // sleep 1 seconds 21 | sleep(1); 22 | } 23 | *width = g_source_width; 24 | *height = g_source_height; 25 | } 26 | 27 | void deInit(MppPacket *packet, MppFrame *frame, MppCtx ctx, char *buf, MpiDecLoopData data) 28 | { 29 | if (packet) 30 | { 31 | mpp_packet_deinit(packet); 32 | packet = NULL; 33 | } 34 | 35 | if (frame) 36 | { 37 | mpp_frame_deinit(frame); 38 | frame = NULL; 39 | } 40 | 41 | if (ctx) 42 | { 43 | mpp_destroy(ctx); 44 | ctx = NULL; 45 | } 46 | 47 | if (buf) 48 | { 49 | mpp_free(buf); 50 | buf = NULL; 51 | } 52 | 53 | if (data.pkt_grp) 54 | { 55 | mpp_buffer_group_put(data.pkt_grp); 56 | data.pkt_grp = NULL; 57 | } 58 | 59 | if (data.frm_grp) 60 | { 61 | mpp_buffer_group_put(data.frm_grp); 62 | data.frm_grp = NULL; 63 | } 64 | 65 | if (data.fp_output) 66 | { 67 | fclose(data.fp_output); 68 | data.fp_output = NULL; 69 | } 70 | 71 | if (data.fp_input) 72 | { 73 | fclose(data.fp_input); 74 | data.fp_input = NULL; 75 | } 76 | } 77 | 78 | 79 | int init_ffmpeg_source(const char *filepath) 80 | { 81 | AVFormatContext *pFormatCtx = NULL; 82 | AVDictionary *options = NULL; 83 | AVPacket *av_packet = NULL; 84 | 85 | // av_register_all(); 86 | printf("avformat_network_init start\n"); 87 | avformat_network_init(); 88 | // 设置读流相关的配置信息 89 | av_dict_set(&options, "buffer_size", "1024000", 0); // 设置缓存大小 90 | av_dict_set(&options, "rtsp_transport", "udp", 0); // 以udp的方式打开, 91 | av_dict_set(&options, "stimeout", "5000000", 0); // 设置超时断开链接时间,单位us 92 | av_dict_set(&options, "max_delay", "500000", 0); // 设置最大时延 93 | 94 | printf("avformat_alloc_context start\n"); 95 | 96 | pFormatCtx = avformat_alloc_context(); // 用来申请AVFormatContext类型变量并初始化默认参数,申请的空间 97 | 98 | printf("avformat_open_input start\n"); 99 | 100 | // 打开网络流或文件流 101 | if (avformat_open_input(&pFormatCtx, filepath, NULL, &options) != 0) 102 | { 103 | printf("Couldn't open input stream.\n"); 104 | return 0; 105 | } 106 | 107 | printf("avformat_find_stream_info start\n"); 108 | 109 | // 获取视频文件信息 110 | if (avformat_find_stream_info(pFormatCtx, NULL) < 0) 111 | { 112 | printf("Couldn't find stream information.\n"); 113 | return 0; 114 | } 115 | 116 | printf("avformat_find_stream_info end\n"); 117 | 118 | // 查找码流中是否有视频流 119 | int videoindex = -1; 120 | unsigned i = 0; 121 | for (i = 0; i < pFormatCtx->nb_streams; i++) 122 | if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) 123 | { 124 | videoindex = i; 125 | break; 126 | } 127 | if (videoindex == -1) 128 | { 129 | printf("Didn't find a video stream.\n"); 130 | return 0; 131 | } 132 | 133 | // 获取图像宽高 134 | int srcWidth = pFormatCtx->streams[videoindex]->codecpar->width; 135 | int srcHeight = pFormatCtx->streams[videoindex]->codecpar->height; 136 | 137 | g_source_width = srcWidth; 138 | g_source_height = srcHeight; 139 | 140 | printf("srcWidth is %d, srcHeight is %d\n", srcWidth, srcHeight); 141 | 142 | av_packet = (AVPacket *)av_malloc(sizeof(AVPacket)); // 申请空间,存放的每一帧数据 (h264、h265) 143 | av_new_packet(av_packet, srcWidth * srcHeight); 144 | 145 | /// setup mpp decoder 146 | MPP_RET ret = MPP_OK; 147 | size_t file_size = 0; 148 | 149 | // ctx 是mpp的上下文信息 150 | MppCtx ctx = NULL; 151 | // mpi 是mpp的api,调用具体的功能时通过API进行调用 152 | MppApi *mpi = NULL; 153 | 154 | // 这里的packet 和 frame实际上并没有使用到,可以删除 155 | // packet 是编码的流数据 156 | MppPacket packet = NULL; 157 | // frame 用于存放解码后的数据 158 | MppFrame frame = NULL; 159 | 160 | MpiCmd mpi_cmd = MPP_CMD_BASE; 161 | MppParam param = NULL; 162 | RK_U32 need_split = 1; 163 | // MppPollType timeout = 5; 164 | 165 | // paramter for resource malloc 166 | RK_U32 width = srcWidth; 167 | RK_U32 height = srcHeight; 168 | MppCodingType type = MPP_VIDEO_CodingAVC; 169 | 170 | // resources 171 | char *buf = NULL; 172 | size_t packet_size = 8 * 1024; 173 | // packet 和 frame 的数据都是放在 MppBuffer中 174 | MppBuffer pkt_buf = NULL; 175 | MppBuffer frm_buf = NULL; 176 | 177 | // 这里定义执行decode循环需要的数据,实际上等于是类里面的成员变量 178 | MpiDecLoopData g_dec_loop_data; 179 | 180 | mpp_log("mpi_dec_test start\n"); 181 | memset(&g_dec_loop_data, 0, sizeof(g_dec_loop_data)); 182 | 183 | // 以下 fp_output 相关代码实际上并不需要, 保留用于测试 184 | g_dec_loop_data.fp_output = fopen("./tenoutput.yuv", "w+b"); 185 | if (NULL == g_dec_loop_data.fp_output) 186 | { 187 | mpp_err("failed to open output file %s\n", "tenoutput.yuv"); 188 | deInit(&packet, &frame, ctx, buf, g_dec_loop_data); 189 | } 190 | 191 | mpp_log("mpi_dec_test decoder test start w %d h %d type %d\n", width, height, type); 192 | 193 | // 创建一个用于解码的上下文和mpp api 194 | ret = mpp_create(&ctx, &mpi); 195 | 196 | if (MPP_OK != ret) 197 | { 198 | mpp_err("mpp_create failed\n"); 199 | deInit(&packet, &frame, ctx, buf, g_dec_loop_data); 200 | } 201 | 202 | // NOTE: decoder split mode need to be set before init 203 | // 设置decoder的模式 204 | mpi_cmd = MPP_DEC_SET_PARSER_SPLIT_MODE; 205 | param = &need_split; 206 | // control是用于控制编解码的行为的api, 下面一个一个调用control实际上就是在一个参数一个参数的进行配置 207 | ret = mpi->control(ctx, mpi_cmd, param); 208 | if (MPP_OK != ret) 209 | { 210 | mpp_err("mpi->control failed\n"); 211 | deInit(&packet, &frame, ctx, buf, g_dec_loop_data); 212 | } 213 | 214 | mpi_cmd = MPP_SET_INPUT_BLOCK; 215 | param = &need_split; 216 | ret = mpi->control(ctx, mpi_cmd, param); 217 | if (MPP_OK != ret) 218 | { 219 | mpp_err("mpi->control failed\n"); 220 | deInit(&packet, &frame, ctx, buf, g_dec_loop_data); 221 | } 222 | 223 | ret = mpp_init(ctx, MPP_CTX_DEC, type); 224 | if (MPP_OK != ret) 225 | { 226 | mpp_err("mpp_init failed\n"); 227 | deInit(&packet, &frame, ctx, buf, g_dec_loop_data); 228 | } 229 | 230 | g_dec_loop_data.ctx = ctx; 231 | g_dec_loop_data.mpi = mpi; 232 | g_dec_loop_data.eos = 0; 233 | g_dec_loop_data.packet_size = packet_size; 234 | g_dec_loop_data.frame = frame; 235 | g_dec_loop_data.frame_count = 0; 236 | 237 | ready = 1; 238 | 239 | // 初始化完成后就可以开始从ffmpeg中读取视频流了,然后把视频流扔到解码的代码中。 240 | while (1) 241 | { 242 | if (av_read_frame(pFormatCtx, av_packet) >= 0) 243 | { 244 | if (av_packet->stream_index == videoindex) 245 | { 246 | printf("--------------\ndata size is: %d\n-------------", av_packet->size); 247 | decode_simple(&g_dec_loop_data, av_packet); 248 | } 249 | if (av_packet != NULL) 250 | av_packet_unref(av_packet); 251 | printf("%d", i); 252 | } 253 | } 254 | } -------------------------------------------------------------------------------- /src/media/media_buffer.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "media_buffer.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class MediaBuffer 10 | { 11 | public: 12 | MediaBuffer() {} 13 | ~MediaBuffer(); 14 | 15 | void push_src_media(cv::Mat img) 16 | { 17 | if (img.empty() || img.rows == 0 || img.cols == 0) 18 | { 19 | return; 20 | } 21 | std::lock_guard lock(mutex1_); 22 | src_buffer_.push_back(img); 23 | if (src_buffer_.size() > buffer_limit_) 24 | { 25 | src_buffer_.pop_front(); 26 | } 27 | } 28 | 29 | cv::Mat pop_src_media() 30 | { 31 | while (src_buffer_.empty()) 32 | { 33 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); 34 | } 35 | std::unique_lock lock(mutex1_); 36 | cv::Mat img = src_buffer_.front(); 37 | src_buffer_.pop_front(); 38 | return img; 39 | } 40 | 41 | void push_out_media(cv::Mat img) 42 | { 43 | if (img.empty() || img.rows == 0 || img.cols == 0) 44 | { 45 | return; 46 | } 47 | std::lock_guard lock(mutex2_); 48 | out_buffer_.push_back(img); 49 | if (out_buffer_.size() > buffer_limit_) 50 | { 51 | out_buffer_.pop_front(); 52 | } 53 | } 54 | 55 | cv::Mat pop_out_media() 56 | { 57 | while (out_buffer_.empty()) 58 | { 59 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); 60 | } 61 | std::unique_lock lock(mutex2_); 62 | cv::Mat img = out_buffer_.front(); 63 | out_buffer_.pop_front(); 64 | return img; 65 | } 66 | 67 | private: 68 | int buffer_limit_ = 10; 69 | std::mutex mutex1_; 70 | std::mutex mutex2_; 71 | std::deque src_buffer_; 72 | std::deque out_buffer_; 73 | }; 74 | 75 | static MediaBuffer *g_media_buffer = nullptr; 76 | 77 | void init_media_buffer() 78 | { 79 | g_media_buffer = new MediaBuffer(); 80 | } 81 | 82 | void push_src_media(cv::Mat img) 83 | { 84 | printf("push_src_media.....\n"); 85 | while (g_media_buffer == nullptr) 86 | { 87 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 88 | } 89 | g_media_buffer->push_src_media(img); 90 | } 91 | 92 | cv::Mat pop_src_media() 93 | { 94 | printf("pop_src_media.....\n"); 95 | while (g_media_buffer == nullptr) 96 | { 97 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 98 | } 99 | return g_media_buffer->pop_src_media(); 100 | } 101 | 102 | void push_out_media(cv::Mat img) 103 | { 104 | printf("push_out_media.....\n"); 105 | while (g_media_buffer == nullptr) 106 | { 107 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 108 | } 109 | g_media_buffer->push_out_media(img); 110 | } 111 | 112 | cv::Mat pop_out_media() 113 | { 114 | printf("pop_out_media.....\n"); 115 | while (g_media_buffer == nullptr) 116 | { 117 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 118 | } 119 | return g_media_buffer->pop_out_media(); 120 | } -------------------------------------------------------------------------------- /src/media/media_buffer.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | void init_media_buffer(); 5 | 6 | void push_src_media(cv::Mat img); 7 | 8 | cv::Mat pop_src_media(); 9 | 10 | void push_out_media(cv::Mat img); 11 | 12 | cv::Mat pop_out_media(); -------------------------------------------------------------------------------- /src/media/mpi_dec.cpp: -------------------------------------------------------------------------------- 1 | #include "mpi_dec.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "media_buffer.h" 14 | 15 | #define MPI_DEC_STREAM_SIZE (SZ_4K) 16 | #define MPI_DEC_LOOP_COUNT 4 17 | #define MAX_FILE_NAME_LENGTH 256 18 | 19 | void YUV420SP2Mat(MppFrame frame, cv::Mat &rgbImg) 20 | { 21 | RK_U32 width = 0; 22 | RK_U32 height = 0; 23 | RK_U32 h_stride = 0; 24 | RK_U32 v_stride = 0; 25 | 26 | MppBuffer buffer = NULL; 27 | RK_U8 *base = NULL; 28 | 29 | width = mpp_frame_get_width(frame); 30 | height = mpp_frame_get_height(frame); 31 | h_stride = mpp_frame_get_hor_stride(frame); 32 | v_stride = mpp_frame_get_ver_stride(frame); 33 | buffer = mpp_frame_get_buffer(frame); 34 | mpp_log("width = %d\n", width); 35 | mpp_log("height = %d\n", height); 36 | mpp_log("h_stride = %d\n", h_stride); 37 | mpp_log("v_stride = %d\n", v_stride); 38 | 39 | base = (RK_U8 *)mpp_buffer_get_ptr(buffer); 40 | RK_U32 buf_size = mpp_frame_get_buf_size(frame); 41 | size_t base_length = mpp_buffer_get_size(buffer); 42 | // mpp_log("base_length = %d\n",base_length); 43 | 44 | RK_U32 i; 45 | RK_U8 *base_y = base; 46 | RK_U8 *base_c = base + h_stride * v_stride; 47 | 48 | cv::Mat yuvImg; 49 | yuvImg.create(height * 3 / 2, width, CV_8UC1); 50 | 51 | // 转为YUV420p格式 52 | int idx = 0; 53 | for (i = 0; i < height; i++, base_y += h_stride) 54 | { 55 | // fwrite(base_y, 1, width, fp); 56 | memcpy(yuvImg.data + idx, base_y, width); 57 | idx += width; 58 | } 59 | for (i = 0; i < height / 2; i++, base_c += h_stride) 60 | { 61 | // fwrite(base_c, 1, width, fp); 62 | memcpy(yuvImg.data + idx, base_c, width); 63 | idx += width; 64 | } 65 | // 这里的转码需要转为RGB 3通道, RGBA四通道则不能检测成功 66 | cv::cvtColor(yuvImg, rgbImg, CV_YUV420sp2RGB); 67 | } 68 | 69 | int frame_null = 0; 70 | int count = 0; 71 | 72 | size_t mpp_buffer_group_usage(MppBufferGroup group) 73 | { 74 | if (NULL == group) 75 | { 76 | mpp_err_f("input invalid group %p\n", group); 77 | return MPP_BUFFER_MODE_BUTT; 78 | } 79 | 80 | MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; 81 | return p->usage; 82 | } 83 | 84 | int decode_simple(MpiDecLoopData *data, AVPacket *av_packet) 85 | // int decode_simple(MpiDecLoopData *data, void* pdata, int len, uint32_t pts, uint32_t dts) 86 | { 87 | RK_U32 pkt_done = 0; 88 | RK_U32 pkt_eos = 0; 89 | RK_U32 err_info = 0; 90 | MPP_RET ret = MPP_OK; 91 | MppCtx ctx = data->ctx; 92 | MppApi *mpi = data->mpi; 93 | // char *buf = g_dec_loop_data->buf; 94 | MppPacket packet = NULL; 95 | MppFrame frame = NULL; 96 | size_t read_size = 0; 97 | size_t packet_size = data->packet_size; 98 | 99 | // 首先是将av packet中的数据拷贝到 mpp 的packet中 100 | ret = mpp_packet_init(&packet, av_packet->data, av_packet->size); 101 | if (ret < 0) 102 | { 103 | mpp_err("mpp_packet_init failed\n"); 104 | return ret; 105 | } 106 | mpp_packet_set_pts(packet, av_packet->pts); 107 | // mpp_packet_set_dts(packet, dts); 108 | 109 | do 110 | { 111 | RK_S32 times = 5; 112 | // send the packet first if packet is not done 113 | if (!pkt_done) 114 | { 115 | mpp_log("decode_simple read packet\n"); 116 | // 把packet扔给mpp进行解码 117 | ret = mpi->decode_put_packet(ctx, packet); 118 | if (MPP_OK == ret) 119 | { 120 | pkt_done = 1; 121 | mpp_log("decode_simple read packet success\n"); 122 | } 123 | else 124 | { 125 | mpp_err("decode_simple read packet failed\n"); 126 | break; 127 | } 128 | } 129 | else 130 | { 131 | mpp_log("decode_simple flush\n"); 132 | } 133 | 134 | // then get all available frame and release 135 | do 136 | { 137 | RK_S32 get_frm = 0; 138 | RK_U32 frm_eos = 0; 139 | 140 | try_again: 141 | // 获取解码后的frame 142 | ret = mpi->decode_get_frame(ctx, &frame); 143 | if (MPP_ERR_TIMEOUT == ret) 144 | { 145 | if (times > 0) 146 | { 147 | times--; 148 | msleep(2); 149 | goto try_again; 150 | } 151 | mpp_err("decode_get_frame failed too much time\n"); 152 | } 153 | if (MPP_OK != ret) 154 | { 155 | mpp_err("decode_get_frame failed ret %d\n", ret); 156 | break; 157 | } 158 | 159 | if (frame) 160 | { 161 | if (mpp_frame_get_info_change(frame)) 162 | { 163 | RK_U32 width = mpp_frame_get_width(frame); 164 | RK_U32 height = mpp_frame_get_height(frame); 165 | RK_U32 hor_stride = mpp_frame_get_hor_stride(frame); 166 | RK_U32 ver_stride = mpp_frame_get_ver_stride(frame); 167 | RK_U32 buf_size = mpp_frame_get_buf_size(frame); 168 | 169 | mpp_log("decode_get_frame get info changed found\n"); 170 | mpp_log("decoder require buffer w:h [%d:%d] stride [%d:%d] buf_size %d \n", 171 | width, height, hor_stride, ver_stride, buf_size); 172 | 173 | ret = mpp_buffer_group_get_internal(&data->frm_grp, MPP_BUFFER_TYPE_ION); 174 | if (ret) 175 | { 176 | mpp_err("get mpp buffer group failed ret %d\n", ret); 177 | break; 178 | } 179 | mpi->control(ctx, MPP_DEC_SET_EXT_BUF_GROUP, data->frm_grp); 180 | 181 | mpi->control(ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL); 182 | } 183 | else 184 | { 185 | err_info = mpp_frame_get_errinfo(frame) | mpp_frame_get_discard(frame); 186 | if (err_info) 187 | { 188 | mpp_log("decoder_get_frame get err info:%d discard:%d.\n", 189 | mpp_frame_get_errinfo(frame), mpp_frame_get_discard(frame)); 190 | } 191 | data->frame_count++; 192 | mpp_log("decode_get_frame get frame %d\n", data->frame_count); 193 | if (data->fp_output && !err_info) 194 | { 195 | cv::Mat rgbImg; 196 | // 把frame转为rgb格式,用于yolov5推理 197 | YUV420SP2Mat(frame, rgbImg); 198 | // 放入图片buffer中 199 | push_src_media(rgbImg); 200 | } 201 | } 202 | frm_eos = mpp_frame_get_eos(frame); 203 | mpp_frame_deinit(&frame); 204 | 205 | frame = NULL; 206 | get_frm = 1; 207 | } 208 | else 209 | { 210 | mpp_log("decode_get_frame found no frame\n"); 211 | } 212 | 213 | // try get runtime frame memory usage 214 | if (data->frm_grp) 215 | { 216 | size_t usage = mpp_buffer_group_usage(data->frm_grp); 217 | if (usage > data->max_usage) 218 | data->max_usage = usage; 219 | } 220 | 221 | // if last packet is send but last frame is not found continue 222 | if (pkt_eos && pkt_done && !frm_eos) 223 | { 224 | msleep(10); 225 | continue; 226 | } 227 | 228 | if (frm_eos) 229 | { 230 | mpp_log("found last frame\n"); 231 | break; 232 | } 233 | 234 | if (data->frame_num > 0 && data->frame_count >= data->frame_num) 235 | { 236 | data->eos = 1; 237 | break; 238 | } 239 | 240 | if (get_frm) 241 | continue; 242 | break; 243 | } while (1); 244 | 245 | if (data->frame_num > 0 && data->frame_count >= data->frame_num) 246 | { 247 | data->eos = 1; 248 | mpp_log("reach max frame number %d\n", data->frame_count); 249 | break; 250 | } 251 | 252 | if (pkt_done) 253 | break; 254 | 255 | /* 256 | * why sleep here: 257 | * mpi->decode_put_packet will failed when packet in internal queue is 258 | * full,waiting the package is consumed .Usually hardware decode one 259 | * frame which resolution is 1080p needs 2 ms,so here we sleep 3ms 260 | * * is enough. 261 | */ 262 | msleep(3); 263 | } while (1); 264 | mpp_packet_deinit(&packet); 265 | 266 | return ret; 267 | } 268 | -------------------------------------------------------------------------------- /src/media/mpi_dec.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef RK3588_DEMO_MPI_DEC_H 3 | #define RK3588_DEMO_MPI_DEC_H 4 | 5 | #include "rk_mpi.h" 6 | #include "mpp_log.h" 7 | #include "mpp_mem.h" 8 | #include "mpp_env.h" 9 | #include "mpp_time.h" 10 | #include "mpp_common.h" 11 | 12 | #include "mpp_frame.h" 13 | #include "mpp_buffer_impl.h" 14 | #include "mpp_frame_impl.h" 15 | 16 | #define MPI_DEC_STREAM_SIZE (SZ_4K) 17 | #define MPI_DEC_LOOP_COUNT 4 18 | #define MAX_FILE_NAME_LENGTH 256 19 | 20 | typedef struct 21 | { 22 | MppCtx ctx; 23 | MppApi *mpi; 24 | RK_U32 eos; 25 | char *buf; 26 | 27 | MppBufferGroup frm_grp; 28 | MppBufferGroup pkt_grp; 29 | MppPacket packet; 30 | size_t packet_size; 31 | MppFrame frame; 32 | 33 | FILE *fp_input; 34 | FILE *fp_output; 35 | RK_S32 frame_count; 36 | RK_S32 frame_num; 37 | size_t max_usage; 38 | } MpiDecLoopData; 39 | 40 | typedef struct 41 | { 42 | char file_input[MAX_FILE_NAME_LENGTH]; 43 | char file_output[MAX_FILE_NAME_LENGTH]; 44 | MppCodingType type; 45 | MppFrameFormat format; 46 | RK_U32 width; 47 | RK_U32 height; 48 | RK_U32 debug; 49 | 50 | RK_U32 have_input; 51 | RK_U32 have_output; 52 | 53 | RK_U32 simple; 54 | RK_S32 timeout; 55 | RK_S32 frame_num; 56 | size_t max_usage; 57 | } MpiDecTestCmd; 58 | 59 | #endif // RK3588_DEMO_MPI_DEC_H 60 | -------------------------------------------------------------------------------- /src/media/nn_media.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "nn_media.h" 4 | -------------------------------------------------------------------------------- /src/media/nn_media.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef RK3588_DEMO_NN_MEDIA_H 4 | #define RK3588_DEMO_NN_MEDIA_H 5 | 6 | #include "types/error.h" 7 | #include "types/media_dtype.h" 8 | 9 | class NNMedia 10 | { 11 | 12 | public: 13 | nn_error_e SetInputType(nn_media_type_e type); 14 | nn_error_e SetOutputType(nn_media_type_e type); 15 | 16 | nn_error_e SetInputRTSP(const char *url); 17 | nn_error_e SetOutputRTSP(const char *url); 18 | 19 | nn_error_e SetInputFile(const char *path); 20 | 21 | nn_error_e GetSourceData(); 22 | nn_error_e PushOutputData(); 23 | 24 | private: 25 | }; 26 | 27 | #endif // RK3588_DEMO_NN_MEDIA_H 28 | -------------------------------------------------------------------------------- /src/media/zlmedia_worker.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "zlmedia_worker.h" 3 | 4 | #include 5 | 6 | // 所有的api介绍都可以在对应头文件找到 7 | 8 | void API_CALL PushResultCB(void *user_data, int err_code, const char *err_msg) 9 | { 10 | printf("err_code:%d\n", err_code); 11 | printf("err_msg:%s\n", err_msg); 12 | } 13 | 14 | void API_CALL MediasourceRegistCB(void *user_data, mk_media_source sender, int regist) 15 | { 16 | printf("mk_media_source:%x\n", sender); 17 | printf("regist type:%x\n", regist); 18 | 19 | if (regist == 1) 20 | { 21 | ZLMediaWorker *ptr = (ZLMediaWorker *)user_data; 22 | ptr->ZLM_PusherInit(); 23 | ptr->ZLM_PusherStart(ptr->ZLM_GetPushUrl().c_str()); 24 | } 25 | } 26 | 27 | // extern int decode_func(void* data, int len, uint32_t pts, uint32_t dts); 28 | 29 | void API_CALL on_track_frame_out(void *user_data, mk_frame frame) 30 | { 31 | void *ptr = (void *)mk_frame_get_data(frame); 32 | int len = (int)mk_frame_get_data_size(frame); 33 | uint32_t pts = mk_frame_get_pts(frame); 34 | uint32_t dts = mk_frame_get_dts(frame); 35 | // decode_func(ptr, len, pts, dts); 36 | } 37 | 38 | void API_CALL PlayerDataCB(void *user_data, int err_code, const char *err_msg, mk_track tracks[], int track_count) 39 | { 40 | if (err_code != 0) 41 | { 42 | printf("err_code:%d\n", err_code); 43 | printf("err_msg:%s\n", err_msg); 44 | return; 45 | } 46 | else 47 | { 48 | for (int i = 0; i < track_count; ++i) 49 | { 50 | if (mk_track_is_video(tracks[i])) 51 | { 52 | mk_track_add_delegate(tracks[i], on_track_frame_out, user_data); 53 | } 54 | } 55 | } 56 | } 57 | 58 | void API_CALL StreamDataCB(void *user_data, int track_type, int codec_id, void *data, int len, uint32_t dts, uint32_t pts) 59 | { 60 | // 忽略音频 61 | if (track_type != 0) 62 | { 63 | return; 64 | } 65 | 66 | ZLMediaWorker *ptr = (ZLMediaWorker *)user_data; 67 | mk_media pMedia = ptr->ZLM_GetMediaHandle(); 68 | mk_media_input_h264(pMedia, data, len, dts, pts); 69 | // decode_func(data, len, pts, dts); 70 | return; 71 | } 72 | 73 | ZLMediaWorker::ZLMediaWorker() 74 | { 75 | } 76 | 77 | ZLMediaWorker::~ZLMediaWorker() 78 | { 79 | } 80 | 81 | void ZLMediaWorker::ZLM_MediaInit(int width, int height) 82 | { 83 | mk_config config; 84 | config.ini = NULL; 85 | config.ini_is_path = 0; 86 | config.log_level = 0; 87 | config.log_mask = LOG_CONSOLE; 88 | config.ssl = NULL; 89 | config.ssl_is_path = 1; 90 | config.ssl_pwd = NULL; 91 | config.thread_num = 0; 92 | 93 | mk_env_init(&config); 94 | _mk_MediaHandle = mk_media_create( 95 | "__defaultVhost__", "live", "camera1", 96 | 0, 0, 1); 97 | mk_media_init_video(_mk_MediaHandle, 0, width, height, 25, 0); 98 | mk_media_set_on_regist(_mk_MediaHandle, MediasourceRegistCB, this); 99 | mk_media_init_complete(_mk_MediaHandle); 100 | } 101 | 102 | mk_media ZLMediaWorker::ZLM_GetMediaHandle() 103 | { 104 | return _mk_MediaHandle; 105 | } 106 | 107 | void ZLMediaWorker::ZLM_PusherInit() 108 | { 109 | _mk_PusherHandle = mk_pusher_create("rtmp", "__defaultVhost__", "live", "camera1"); 110 | mk_pusher_set_on_result(_mk_PusherHandle, PushResultCB, this); 111 | } 112 | 113 | void ZLMediaWorker::ZLM_PusherStart(std::string strPushUrl) 114 | { 115 | mk_pusher_publish(_mk_PusherHandle, strPushUrl.c_str()); 116 | } 117 | 118 | void ZLMediaWorker::ZLM_SetPushUrl(std::string strPushUrl) 119 | { 120 | _strPushUrl = strPushUrl; 121 | } 122 | 123 | std::string ZLMediaWorker::ZLM_GetPushUrl() 124 | { 125 | return _strPushUrl; 126 | } 127 | 128 | void ZLMediaWorker::ZLM_SetSrcUrl(std::string strSrcUrl) 129 | { 130 | _strSrcUrl = strSrcUrl; 131 | _mk_PlayerHandle = mk_player_create(); 132 | mk_player_play(_mk_PlayerHandle, strSrcUrl.c_str()); 133 | mk_player_set_on_result(_mk_PlayerHandle, PlayerDataCB, this); 134 | } 135 | 136 | static ZLMediaWorker *g_pZLMediaWorker = nullptr; 137 | 138 | void init_zlmediakit(int width, int height, std::string strPushUrl) 139 | { 140 | g_pZLMediaWorker = new ZLMediaWorker(); 141 | g_pZLMediaWorker->ZLM_SetPushUrl(strPushUrl); 142 | g_pZLMediaWorker->ZLM_MediaInit(width, height); 143 | } 144 | 145 | void stream_data(void *data, int len, uint32_t dts, uint32_t pts) 146 | { 147 | while (g_pZLMediaWorker == nullptr) 148 | { 149 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 150 | } 151 | mk_media pMedia = g_pZLMediaWorker->ZLM_GetMediaHandle(); 152 | mk_media_input_h264(pMedia, data, len, dts, pts); 153 | } -------------------------------------------------------------------------------- /src/media/zlmedia_worker.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef RK3588_DEMO_ZLMEDIA_WORKER_H 4 | #define RK3588_DEMO_ZLMEDIA_WORKER_H 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "mk_media.h" 12 | #include "mk_player.h" 13 | #include "mk_pusher.h" 14 | 15 | class ZLMediaWorker 16 | { 17 | public: 18 | ZLMediaWorker(); 19 | ~ZLMediaWorker(); 20 | 21 | void ZLM_MediaInit(int width, int height); 22 | mk_media ZLM_GetMediaHandle(); 23 | void ZLM_PusherInit(); 24 | void ZLM_PusherStart(std::string strPushUrl); 25 | void ZLM_SetPushUrl(std::string strPushUrl); 26 | void ZLM_SetSrcUrl(std::string strSrcUrl); 27 | std::string ZLM_GetPushUrl(); 28 | 29 | private: 30 | mk_player _mk_PlayerHandle; 31 | mk_media _mk_MediaHandle; 32 | mk_pusher _mk_PusherHandle; 33 | 34 | std::string _strPushUrl; 35 | std::string _strSrcUrl; 36 | }; 37 | 38 | void init_zlmediakit(int width, int height, std::string strPushUrl); 39 | 40 | void stream_data(void *data, int len, uint32_t dts, uint32_t pts); 41 | 42 | #endif // RK3588_DEMO_ZLMEDIA_WORKER_H 43 | -------------------------------------------------------------------------------- /src/process/postprocess.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef RK3588_DEMO_POSTPROCESS_H 3 | #define RK3588_DEMO_POSTPROCESS_H 4 | 5 | #include 6 | #include 7 | 8 | int get_top(float *pfProb, float *pfMaxProb, uint32_t *pMaxClass, uint32_t outputCount, uint32_t topNum); 9 | 10 | namespace yolo 11 | { 12 | int GetConvDetectionResult(float **pBlob, std::vector &DetectiontRects); // 浮点数版本 13 | int GetConvDetectionResultInt8(int8_t **pBlob, std::vector &qnt_zp, std::vector &qnt_scale, std::vector &DetectiontRects); // int8版本 14 | } 15 | 16 | #endif // RK3588_DEMO_POSTPROCESS_H 17 | -------------------------------------------------------------------------------- /src/process/preprocess.cpp: -------------------------------------------------------------------------------- 1 | // 预处理 2 | 3 | #include "preprocess.h" 4 | 5 | #include "utils/logging.h" 6 | #include "im2d.h" 7 | #include "rga.h" 8 | 9 | // opencv 版本的 letterbox 10 | LetterBoxInfo letterbox(const cv::Mat &img, cv::Mat &img_letterbox, float wh_ratio) 11 | { 12 | 13 | // img has to be 3 channels 14 | if (img.channels() != 3) 15 | { 16 | NN_LOG_ERROR("img has to be 3 channels"); 17 | exit(-1); 18 | } 19 | float img_width = img.cols; 20 | float img_height = img.rows; 21 | 22 | int letterbox_width = 0; 23 | int letterbox_height = 0; 24 | 25 | LetterBoxInfo info; 26 | int padding_hor = 0; 27 | int padding_ver = 0; 28 | 29 | if (img_width / img_height > wh_ratio) 30 | { 31 | info.hor = false; 32 | letterbox_width = img_width; 33 | letterbox_height = img_width / wh_ratio; 34 | info.pad = (letterbox_height - img_height) / 2.f; 35 | padding_hor = 0; 36 | padding_ver = info.pad; 37 | } 38 | else 39 | { 40 | info.hor = true; 41 | letterbox_width = img_height * wh_ratio; 42 | letterbox_height = img_height; 43 | info.pad = (letterbox_width - img_width) / 2.f; 44 | padding_hor = info.pad; 45 | padding_ver = 0; 46 | } 47 | /* 48 | * Padding an image. 49 | dst_img 50 | -------------- ---------------------------- 51 | | | | top_border | 52 | | src_image | => | | 53 | | | | -------------- | 54 | -------------- |left_ | |right_| 55 | |border| dst_rect |border| 56 | | | | | 57 | | -------------- | 58 | | bottom_border | 59 | ---------------------------- 60 | */ 61 | // 使用cv::copyMakeBorder函数进行填充边界 62 | cv::copyMakeBorder(img, img_letterbox, padding_ver, padding_ver, padding_hor, padding_hor, cv::BORDER_CONSTANT, cv::Scalar(0, 0, 0)); 63 | return info; 64 | } 65 | 66 | // opencv resize 67 | void cvimg2tensor(const cv::Mat &img, uint32_t width, uint32_t height, tensor_data_s &tensor) 68 | { 69 | // img has to be 3 channels 70 | if (img.channels() != 3) 71 | { 72 | NN_LOG_ERROR("img has to be 3 channels"); 73 | exit(-1); 74 | } 75 | // BGR to RGB 76 | cv::Mat img_rgb; 77 | cv::cvtColor(img, img_rgb, cv::COLOR_BGR2RGB); 78 | // resize img 79 | cv::Mat img_resized; 80 | // resize img 81 | cv::resize(img_rgb, img_resized, cv::Size(width, height), 0, 0, cv::INTER_LINEAR); 82 | // BGR to RGB 83 | memcpy(tensor.data, img_resized.data, tensor.attr.size); 84 | } 85 | 86 | // rga 版本的 resize 87 | void cvimg2tensor_rga(const cv::Mat &img, uint32_t width, uint32_t height, tensor_data_s &tensor) 88 | { 89 | // img has to be 3 channels 90 | if (img.channels() != 3) 91 | { 92 | NN_LOG_ERROR("img has to be 3 channels"); 93 | exit(-1); 94 | } 95 | 96 | cv::Mat img_rgb; 97 | cv::cvtColor(img, img_rgb, cv::COLOR_BGR2RGB); 98 | 99 | im_rect src_rect; 100 | im_rect dst_rect; 101 | memset(&src_rect, 0, sizeof(src_rect)); 102 | memset(&dst_rect, 0, sizeof(dst_rect)); 103 | rga_buffer_t src = wrapbuffer_virtualaddr((void *)img_rgb.data, img.cols, img.rows, RK_FORMAT_RGB_888); 104 | rga_buffer_t dst = wrapbuffer_virtualaddr((void *)tensor.data, width, height, RK_FORMAT_RGB_888); 105 | int ret = imcheck(src, dst, src_rect, dst_rect); 106 | if (IM_STATUS_NOERROR != ret) 107 | { 108 | NN_LOG_ERROR("%d, check error! %s", __LINE__, imStrError((IM_STATUS)ret)); 109 | exit(-1); 110 | } 111 | imresize(src, dst); 112 | } 113 | 114 | // rga 版本的 letterbox 115 | LetterBoxInfo letterbox_rga(const cv::Mat &img, cv::Mat &img_letterbox, float wh_ratio) 116 | { 117 | // img has to be 3 channels 118 | if (img.channels() != 3) 119 | { 120 | NN_LOG_ERROR("img has to be 3 channels"); 121 | exit(-1); 122 | } 123 | float img_width = img.cols; 124 | float img_height = img.rows; 125 | 126 | int letterbox_width = 0; 127 | int letterbox_height = 0; 128 | 129 | LetterBoxInfo info; 130 | int padding_hor = 0; 131 | int padding_ver = 0; 132 | 133 | if (img_width / img_height > wh_ratio) 134 | { 135 | info.hor = false; 136 | letterbox_width = img_width; 137 | letterbox_height = img_width / wh_ratio; 138 | info.pad = (letterbox_height - img_height) / 2.f; 139 | padding_hor = 0; 140 | padding_ver = info.pad; 141 | } 142 | else 143 | { 144 | info.hor = true; 145 | letterbox_width = img_height * wh_ratio; 146 | letterbox_height = img_height; 147 | info.pad = (letterbox_width - img_width) / 2.f; 148 | padding_hor = info.pad; 149 | padding_ver = 0; 150 | } 151 | // rga add border 152 | img_letterbox = cv::Mat::zeros(letterbox_height, letterbox_width, CV_8UC3); 153 | 154 | im_rect src_rect; 155 | im_rect dst_rect; 156 | memset(&src_rect, 0, sizeof(src_rect)); 157 | memset(&dst_rect, 0, sizeof(dst_rect)); 158 | 159 | // NN_LOG_INFO("img size: %d, %d", img.cols, img.rows); 160 | 161 | rga_buffer_t src = wrapbuffer_virtualaddr((void *)img.data, img.cols, img.rows, RK_FORMAT_RGB_888); 162 | rga_buffer_t dst = wrapbuffer_virtualaddr((void *)img_letterbox.data, img_letterbox.cols, img_letterbox.rows, RK_FORMAT_RGB_888); 163 | int ret = imcheck(src, dst, src_rect, dst_rect); 164 | if (IM_STATUS_NOERROR != ret) 165 | { 166 | NN_LOG_ERROR("%d, check error! %s", __LINE__, imStrError((IM_STATUS)ret)); 167 | exit(-1); 168 | } 169 | 170 | immakeBorder(src, dst, padding_ver, padding_ver, padding_hor, padding_hor, 0, 0, 0); 171 | 172 | return info; 173 | } -------------------------------------------------------------------------------- /src/process/preprocess.h: -------------------------------------------------------------------------------- 1 | // 预处理 2 | 3 | #ifndef RK3588_DEMO_PREPROCESS_H 4 | #define RK3588_DEMO_PREPROCESS_H 5 | 6 | #include 7 | #include "types/datatype.h" 8 | 9 | struct LetterBoxInfo 10 | { 11 | bool hor; 12 | int pad; 13 | }; 14 | 15 | LetterBoxInfo letterbox(const cv::Mat &img, cv::Mat &img_letterbox, float wh_ratio); 16 | LetterBoxInfo letterbox_rga(const cv::Mat& img, cv::Mat& img_letterbox, float wh_ratio); 17 | void cvimg2tensor(const cv::Mat &img, uint32_t width, uint32_t height, tensor_data_s &tensor); 18 | void cvimg2tensor_rga(const cv::Mat &img, uint32_t width, uint32_t height, tensor_data_s &tensor); 19 | 20 | #endif // RK3588_DEMO_PREPROCESS_H 21 | -------------------------------------------------------------------------------- /src/rkmedia/drm_func.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRM_FUNC_H__ 2 | #define __DRM_FUNC_H__ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include // open function 8 | #include // close function 9 | #include 10 | #include 11 | 12 | 13 | #include 14 | #include "libdrm/drm_fourcc.h" 15 | #include "xf86drm.h" 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | typedef int (* FUNC_DRM_IOCTL)(int fd, unsigned long request, void *arg); 22 | 23 | typedef struct _drm_context{ 24 | void *drm_handle; 25 | FUNC_DRM_IOCTL io_func; 26 | } drm_context; 27 | 28 | /* memory type definitions. */ 29 | enum drm_rockchip_gem_mem_type 30 | { 31 | /* Physically Continuous memory and used as default. */ 32 | ROCKCHIP_BO_CONTIG = 1 << 0, 33 | /* cachable mapping. */ 34 | ROCKCHIP_BO_CACHABLE = 1 << 1, 35 | /* write-combine mapping. */ 36 | ROCKCHIP_BO_WC = 1 << 2, 37 | ROCKCHIP_BO_SECURE = 1 << 3, 38 | ROCKCHIP_BO_MASK = ROCKCHIP_BO_CONTIG | ROCKCHIP_BO_CACHABLE | 39 | ROCKCHIP_BO_WC | ROCKCHIP_BO_SECURE 40 | }; 41 | 42 | int drm_init(drm_context *drm_ctx); 43 | 44 | void* drm_buf_alloc(drm_context *drm_ctx,int drm_fd, int TexWidth, int TexHeight,int bpp,int *fd,unsigned int *handle,size_t *actual_size); 45 | 46 | int drm_buf_destroy(drm_context *drm_ctx,int drm_fd,int buf_fd, int handle,void *drm_buf,size_t size); 47 | 48 | void drm_deinit(drm_context *drm_ctx, int drm_fd); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | #endif /*__DRM_FUNC_H__*/ -------------------------------------------------------------------------------- /src/rkmedia/rga_func.h: -------------------------------------------------------------------------------- 1 | #ifndef __RGA_FUNC_H__ 2 | #define __RGA_FUNC_H__ 3 | 4 | #include 5 | #include "RgaApi.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef int(* FUNC_RGA_INIT)(); 12 | typedef void(* FUNC_RGA_DEINIT)(); 13 | typedef int(* FUNC_RGA_BLIT)(rga_info_t *, rga_info_t *, rga_info_t *); 14 | 15 | typedef struct _rga_context{ 16 | void *rga_handle; 17 | FUNC_RGA_INIT init_func; 18 | FUNC_RGA_DEINIT deinit_func; 19 | FUNC_RGA_BLIT blit_func; 20 | } rga_context; 21 | 22 | int RGA_init(rga_context* rga_ctx); 23 | 24 | void img_resize_fast(rga_context *rga_ctx, int src_fd, int src_w, int src_h, uint64_t dst_phys, int dst_w, int dst_h); 25 | 26 | void img_resize_slow(rga_context *rga_ctx, void *src_virt, int src_w, int src_h, void *dst_virt, int dst_w, int dst_h); 27 | 28 | int RGA_deinit(rga_context* rga_ctx); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | #endif/*__RGA_FUNC_H__*/ 34 | -------------------------------------------------------------------------------- /src/rkmedia/utils/drawing.h: -------------------------------------------------------------------------------- 1 | #ifndef DRAWING_MODULE_ 2 | #define DRAWING_MODULE_ 3 | 4 | void draw_rectangle_yuv420sp(unsigned char* yuv420sp, int w, int h, int rx, int ry, int rw, int rh, unsigned int color, int thickness); 5 | 6 | void draw_image_yuv420sp(unsigned char* yuv420sp, int w, int h, unsigned char* draw_img, int rx, int ry, int rw, int rh); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/rkmedia/utils/mpp_decoder.h: -------------------------------------------------------------------------------- 1 | #ifndef __MPP_DECODER_H__ 2 | #define __MPP_DECODER_H__ 3 | 4 | #include 5 | #include "rk_mpi.h" 6 | #include "mpp_frame.h" 7 | #include 8 | #include 9 | 10 | #define MPI_DEC_STREAM_SIZE (SZ_4K) 11 | #define MPI_DEC_LOOP_COUNT 4 12 | #define MAX_FILE_NAME_LENGTH 256 13 | 14 | typedef void (*MppDecoderFrameCallback)(void *userdata, int width_stride, 15 | int height_stride, int width, int height, 16 | int format, int fd, void *data); 17 | 18 | typedef struct 19 | { 20 | MppCtx ctx; 21 | MppApi *mpi; 22 | RK_U32 eos; 23 | char *buf; 24 | 25 | MppBufferGroup frm_grp; 26 | MppBufferGroup pkt_grp; 27 | MppPacket packet; 28 | size_t packet_size; 29 | MppFrame frame; 30 | 31 | RK_S32 frame_count; 32 | RK_S32 frame_num; 33 | size_t max_usage; 34 | } MpiDecLoopData; 35 | 36 | class MppDecoder 37 | { 38 | public: 39 | MppCtx mpp_ctx = NULL; 40 | MppApi *mpp_mpi = NULL; 41 | MppDecoder(); 42 | ~MppDecoder(); 43 | int Init(int video_type, int fps, void *userdata); 44 | int SetCallback(MppDecoderFrameCallback callback); 45 | int decode(uint8_t *pkt_data, int pkt_size, int pkt_eos); 46 | int Reset(); 47 | 48 | private: 49 | // base flow context 50 | MpiCmd mpi_cmd = MPP_CMD_BASE; 51 | MppParam mpp_param1 = NULL; 52 | RK_U32 need_split = 1; 53 | RK_U32 width_mpp; 54 | RK_U32 height_mpp; 55 | MppCodingType mpp_type; 56 | size_t packet_size = 2400 * 1300 * 3 / 2; 57 | MpiDecLoopData loop_data; 58 | // bool vedio_type;//判断vedio是h264/h265 59 | MppPacket packet = NULL; 60 | MppFrame frame = NULL; 61 | pthread_t th = 0; 62 | MppDecoderFrameCallback callback; 63 | int fps = -1; 64 | unsigned long last_frame_time_ms = 0; 65 | 66 | void *userdata = NULL; 67 | }; 68 | 69 | size_t mpp_frame_get_buf_size(const MppFrame s); 70 | size_t mpp_buffer_group_usage(MppBufferGroup group); 71 | 72 | #endif //__MPP_DECODER_H__ 73 | -------------------------------------------------------------------------------- /src/rkmedia/utils/mpp_encoder.h: -------------------------------------------------------------------------------- 1 | #ifndef __MPP_ENCODER_H__ 2 | #define __MPP_ENCODER_H__ 3 | 4 | #include "mpp_frame.h" 5 | #include "rk_mpi.h" 6 | #include 7 | #include 8 | 9 | typedef void (*MppEncoderFrameCallback)(void* userdata, const char* data, int size); 10 | 11 | typedef struct 12 | { 13 | RK_U32 width; 14 | RK_U32 height; 15 | RK_U32 hor_stride; 16 | RK_U32 ver_stride; 17 | MppFrameFormat fmt; 18 | MppCodingType type; 19 | 20 | RK_U32 osd_enable; 21 | RK_U32 osd_mode; 22 | RK_U32 split_mode; 23 | RK_U32 split_arg; 24 | RK_U32 split_out; 25 | 26 | RK_U32 user_data_enable; 27 | RK_U32 roi_enable; 28 | 29 | // rate control runtime parameter 30 | RK_S32 fps_in_flex; 31 | RK_S32 fps_in_den; 32 | RK_S32 fps_in_num; 33 | RK_S32 fps_out_flex; 34 | RK_S32 fps_out_den; 35 | RK_S32 fps_out_num; 36 | RK_S32 bps; 37 | RK_S32 bps_max; 38 | RK_S32 bps_min; 39 | RK_S32 rc_mode; 40 | RK_S32 gop_mode; 41 | RK_S32 gop_len; 42 | RK_S32 vi_len; 43 | 44 | /* general qp control */ 45 | RK_S32 qp_init; 46 | RK_S32 qp_max; 47 | RK_S32 qp_max_i; 48 | RK_S32 qp_min; 49 | RK_S32 qp_min_i; 50 | RK_S32 qp_max_step; /* delta qp between each two P frame */ 51 | RK_S32 qp_delta_ip; /* delta qp between I and P */ 52 | RK_S32 qp_delta_vi; /* delta qp between vi and P */ 53 | 54 | RK_U32 constraint_set; 55 | RK_U32 rotation; 56 | RK_U32 mirroring; 57 | RK_U32 flip; 58 | 59 | MppEncHeaderMode header_mode; 60 | MppEncSeiMode sei_mode; 61 | } MppEncoderParams; 62 | 63 | class MppEncoder { 64 | public: 65 | MppEncoder(); 66 | ~MppEncoder(); 67 | int Init(MppEncoderParams& params, void* userdata); 68 | int SetCallback(MppEncoderFrameCallback callback); 69 | int Encode(void* mpp_buf, char* enc_buf, int max_size); 70 | int GetHeader(char* enc_buf, int max_size); 71 | int Reset(); 72 | void* ImportBuffer(int index, size_t size, int fd, int type); 73 | size_t GetFrameSize(); 74 | void* GetInputFrameBuffer(); 75 | int GetInputFrameBufferFd(void* mpp_buffer); 76 | void* GetInputFrameBufferAddr(void* mpp_buffer); 77 | private: 78 | int InitParams(MppEncoderParams& params); 79 | int SetupEncCfg(); 80 | 81 | MppCtx mpp_ctx = NULL; 82 | MppApi* mpp_mpi = NULL; 83 | RK_S32 chn = 0; 84 | 85 | MppEncoderFrameCallback callback = NULL; 86 | 87 | // global flow control flag 88 | // RK_U32 frm_eos = 0; 89 | // RK_U32 pkt_eos = 0; 90 | // RK_U32 frm_pkt_cnt = 0; 91 | // RK_S32 frame_num = 0; 92 | // RK_S32 frame_count = 0; 93 | // RK_U64 stream_size = 0; 94 | 95 | /* encoder config set */ 96 | MppEncCfg cfg = NULL; 97 | MppEncPrepCfg prep_cfg; 98 | MppEncRcCfg rc_cfg; 99 | MppEncCodecCfg codec_cfg; 100 | MppEncSliceSplit split_cfg; 101 | MppEncOSDPltCfg osd_plt_cfg; 102 | MppEncOSDPlt osd_plt; 103 | MppEncOSDData osd_data; 104 | // RoiRegionCfg roi_region; 105 | MppEncROICfg roi_cfg; 106 | 107 | // input / output 108 | MppBufferGroup buf_grp = NULL; 109 | MppBuffer frm_buf = NULL; 110 | MppBuffer pkt_buf = NULL; 111 | MppBuffer md_info = NULL; 112 | 113 | // MppEncRoiCtx roi_ctx; 114 | 115 | // resources 116 | size_t header_size; 117 | size_t frame_size; 118 | size_t mdinfo_size; 119 | /* NOTE: packet buffer may overflow */ 120 | size_t packet_size; 121 | 122 | MppEncoderParams enc_params; 123 | 124 | void* userdata = NULL; 125 | }; 126 | 127 | #endif //__MPP_ENCODER_H__ 128 | -------------------------------------------------------------------------------- /src/rtsp_pool.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "im2d.h" 10 | #include "rga.h" 11 | #include "RgaUtils.h" 12 | 13 | #include "rknn_api.h" 14 | 15 | #include "rkmedia/utils/mpp_decoder.h" 16 | #include "rkmedia/utils/mpp_encoder.h" 17 | 18 | #include "mk_mediakit.h" 19 | #include "task/yolov8_custom.h" 20 | #include "draw/cv_draw.h" 21 | #include "task/yolov8_thread_pool.h" 22 | 23 | #include "mpp_api.h" 24 | 25 | bool playing = true; 26 | 27 | void *rtps_process(void *arg) 28 | { 29 | int status = 0; 30 | int ret; 31 | 32 | char *stream_url = (char *)arg; // "rtsp://192.168.1.7:554/stream1"; // 视频流地址 33 | 34 | rknn_app_context_t app_ctx; 35 | memset(&app_ctx, 0, sizeof(rknn_app_context_t)); // 初始化上下文 36 | 37 | // MPP 解码器 38 | if (app_ctx.decoder == NULL) 39 | { 40 | MppDecoder *decoder = new MppDecoder(); // 创建解码器 41 | decoder->Init(264, 25, &app_ctx); // 初始化解码器 42 | decoder->SetCallback(mpp_decoder_frame_callback); // 设置回调函数,用来处理解码后的数据 43 | app_ctx.decoder = decoder; // 将解码器赋值给上下文 44 | } 45 | 46 | printf("app_ctx=%p decoder=%p\n", &app_ctx, app_ctx.decoder); 47 | 48 | // 读取视频流 49 | process_video(&app_ctx, stream_url); 50 | 51 | printf("waiting finish\n"); 52 | usleep(3 * 1000 * 1000); 53 | 54 | // 释放资源 55 | if (app_ctx.decoder != nullptr) 56 | { 57 | delete (app_ctx.decoder); 58 | app_ctx.decoder = nullptr; 59 | } 60 | if (app_ctx.encoder != nullptr) 61 | { 62 | delete (app_ctx.encoder); 63 | app_ctx.encoder = nullptr; 64 | } 65 | 66 | return nullptr; 67 | } 68 | 69 | int main(int argc, char **argv) 70 | { 71 | 72 | pthread_t rtspPid1; 73 | pthread_t rtspPid2; 74 | pthread_t rtspPid3; 75 | pthread_t rtspPid4; 76 | pthread_t rtspPid5; 77 | pthread_t rtspPid6; 78 | pthread_t rtspPid7; 79 | pthread_t rtspPid8; 80 | 81 | pthread_create(&rtspPid1, NULL, rtps_process, (void *)"rtsp://192.168.1.7:554/stream1"); 82 | pthread_create(&rtspPid2, NULL, rtps_process, (void *)"rtsp://192.168.1.7:554/stream1"); 83 | pthread_create(&rtspPid3, NULL, rtps_process, (void *)"rtsp://192.168.1.7:554/stream1"); 84 | pthread_create(&rtspPid4, NULL, rtps_process, (void *)"rtsp://192.168.1.7:554/stream1"); 85 | pthread_create(&rtspPid5, NULL, rtps_process, (void *)"rtsp://192.168.1.7:554/stream1"); 86 | pthread_create(&rtspPid6, NULL, rtps_process, (void *)"rtsp://192.168.1.7:554/stream1"); 87 | pthread_create(&rtspPid7, NULL, rtps_process, (void *)"rtsp://192.168.1.7:554/stream1"); 88 | pthread_create(&rtspPid8, NULL, rtps_process, (void *)"rtsp://192.168.1.7:554/stream1"); 89 | getchar(); 90 | getchar(); 91 | playing = false; 92 | 93 | pthread_join(rtspPid1, NULL); 94 | pthread_join(rtspPid2, NULL); 95 | pthread_join(rtspPid3, NULL); 96 | pthread_join(rtspPid4, NULL); 97 | pthread_join(rtspPid5, NULL); 98 | pthread_join(rtspPid6, NULL); 99 | pthread_join(rtspPid7, NULL); 100 | pthread_join(rtspPid8, NULL); 101 | 102 | return 0; 103 | } 104 | -------------------------------------------------------------------------------- /src/task/yolov8_custom.cpp: -------------------------------------------------------------------------------- 1 | #include "yolov8_custom.h" 2 | #include 3 | #include "utils/logging.h" 4 | #include "process/preprocess.h" 5 | #include "process/postprocess.h" 6 | 7 | // define global classes 8 | static std::vector g_classes = { 9 | "person", "bicycle", "car", "motorbike ", "aeroplane ", "bus ", "train", "truck ", "boat", "traffic light", 10 | "fire hydrant", "stop sign ", "parking meter", "bench", "bird", "cat", "dog ", "horse ", "sheep", "cow", "elephant", 11 | "bear", "zebra ", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite", 12 | "baseball bat", "baseball glove", "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup", "fork", "knife ", 13 | "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza ", "donut", "cake", "chair", "sofa", 14 | "pottedplant", "bed", "diningtable", "toilet ", "tvmonitor", "laptop ", "mouse ", "remote ", "keyboard ", "cell phone", "microwave ", 15 | "oven ", "toaster", "sink", "refrigerator ", "book", "clock", "vase", "scissors ", "teddy bear ", "hair drier", "toothbrush "}; 16 | // static std::vector g_classes = { 17 | // "pedestrians", "riders", "partially-visible-person", "ignore-regions", "crowd"}; 18 | 19 | Yolov8Custom::Yolov8Custom() 20 | { 21 | engine_ = CreateRKNNEngine(); 22 | input_tensor_.data = nullptr; 23 | want_float_ = false; // 是否使用浮点数版本的后处理 24 | ready_ = false; 25 | } 26 | 27 | Yolov8Custom::~Yolov8Custom() 28 | { 29 | // release input tensor and output tensor 30 | NN_LOG_DEBUG("release input tensor"); 31 | if (input_tensor_.data != nullptr) 32 | { 33 | free(input_tensor_.data); 34 | input_tensor_.data = nullptr; 35 | } 36 | NN_LOG_DEBUG("release output tensor"); 37 | for (auto &tensor : output_tensors_) 38 | { 39 | if (tensor.data != nullptr) 40 | { 41 | free(tensor.data); 42 | tensor.data = nullptr; 43 | } 44 | } 45 | } 46 | 47 | nn_error_e Yolov8Custom::LoadModel(const char *model_path) 48 | { 49 | auto ret = engine_->LoadModelFile(model_path); 50 | if (ret != NN_SUCCESS) 51 | { 52 | NN_LOG_ERROR("yolov8 load model file failed"); 53 | return ret; 54 | } 55 | // get input tensor 56 | auto input_shapes = engine_->GetInputShapes(); 57 | 58 | // check number of input and n_dims 59 | if (input_shapes.size() != 1) 60 | { 61 | NN_LOG_ERROR("yolov8 input tensor number is not 1, but %ld", input_shapes.size()); 62 | return NN_RKNN_INPUT_ATTR_ERROR; 63 | } 64 | nn_tensor_attr_to_cvimg_input_data(input_shapes[0], input_tensor_); 65 | input_tensor_.data = malloc(input_tensor_.attr.size); 66 | 67 | auto output_shapes = engine_->GetOutputShapes(); 68 | if (output_shapes.size() != 6) 69 | { 70 | NN_LOG_ERROR("yolov8 output tensor number is not 6, but %ld", output_shapes.size()); 71 | return NN_RKNN_OUTPUT_ATTR_ERROR; 72 | } 73 | if (output_shapes[0].type == NN_TENSOR_FLOAT16) 74 | { 75 | want_float_ = true; 76 | NN_LOG_WARNING("yolov8 output tensor type is float16, want type set to float32"); 77 | } 78 | for (int i = 0; i < output_shapes.size(); i++) 79 | { 80 | tensor_data_s tensor; 81 | tensor.attr.n_elems = output_shapes[i].n_elems; 82 | tensor.attr.n_dims = output_shapes[i].n_dims; 83 | for (int j = 0; j < output_shapes[i].n_dims; j++) 84 | { 85 | tensor.attr.dims[j] = output_shapes[i].dims[j]; 86 | } 87 | // output tensor needs to be float32 88 | tensor.attr.type = want_float_ ? NN_TENSOR_FLOAT : output_shapes[i].type; 89 | tensor.attr.index = 0; 90 | tensor.attr.size = output_shapes[i].n_elems * nn_tensor_type_to_size(tensor.attr.type); 91 | tensor.data = malloc(tensor.attr.size); 92 | output_tensors_.push_back(tensor); 93 | out_zps_.push_back(output_shapes[i].zp); 94 | out_scales_.push_back(output_shapes[i].scale); 95 | } 96 | 97 | ready_ = true; 98 | return NN_SUCCESS; 99 | } 100 | 101 | nn_error_e Yolov8Custom::Preprocess(const cv::Mat &img, const std::string process_type, cv::Mat &image_letterbox) 102 | { 103 | 104 | // 预处理包含:letterbox、归一化、BGR2RGB、NCWH 105 | // 其中RKNN会做:归一化、NCWH转换(详见课程文档),所以这里只需要做letterbox、BGR2RGB 106 | 107 | // 比例 108 | float wh_ratio = (float)input_tensor_.attr.dims[2] / (float)input_tensor_.attr.dims[1]; 109 | 110 | // lettorbox 111 | 112 | if (process_type == "opencv") 113 | { 114 | // BGR2RGB,resize,再放入input_tensor_中 115 | letterbox_info_ = letterbox(img, image_letterbox, wh_ratio); 116 | cvimg2tensor(image_letterbox, input_tensor_.attr.dims[2], input_tensor_.attr.dims[1], input_tensor_); 117 | } 118 | else if (process_type == "rga") 119 | { 120 | // rga resize 121 | letterbox_info_ = letterbox_rga(img, image_letterbox, wh_ratio); 122 | // save img 123 | // cv::imwrite("rga.jpg", image_letterbox); 124 | cvimg2tensor_rga(image_letterbox, input_tensor_.attr.dims[2], input_tensor_.attr.dims[1], input_tensor_); 125 | } 126 | 127 | return NN_SUCCESS; 128 | } 129 | 130 | nn_error_e Yolov8Custom::Inference() 131 | { 132 | std::vector inputs; 133 | inputs.push_back(input_tensor_); 134 | return engine_->Run(inputs, output_tensors_, want_float_); 135 | } 136 | 137 | nn_error_e Yolov8Custom::Postprocess(const cv::Mat &img, std::vector &objects) 138 | { 139 | void *output_data[6]; 140 | for (int i = 0; i < 6; i++) 141 | { 142 | output_data[i] = (void *)output_tensors_[i].data; 143 | } 144 | std::vector DetectiontRects; 145 | if (want_float_) 146 | { 147 | // 使用浮点数版本的后处理,他也支持量化的模型 148 | yolo::GetConvDetectionResult((float **)output_data, DetectiontRects); 149 | } 150 | else 151 | { 152 | // 使用量化版本的后处理,只能处理量化的模型 153 | yolo::GetConvDetectionResultInt8((int8_t **)output_data, out_zps_, out_scales_, DetectiontRects); 154 | } 155 | 156 | int img_width = img.cols; 157 | int img_height = img.rows; 158 | for (int i = 0; i < DetectiontRects.size(); i += 6) 159 | { 160 | int classId = int(DetectiontRects[i + 0]); 161 | float conf = DetectiontRects[i + 1]; 162 | int xmin = int(DetectiontRects[i + 2] * float(img_width) + 0.5); 163 | int ymin = int(DetectiontRects[i + 3] * float(img_height) + 0.5); 164 | int xmax = int(DetectiontRects[i + 4] * float(img_width) + 0.5); 165 | int ymax = int(DetectiontRects[i + 5] * float(img_height) + 0.5); 166 | Detection result; 167 | result.class_id = classId; 168 | result.confidence = conf; 169 | 170 | std::random_device rd; 171 | std::mt19937 gen(rd()); 172 | std::uniform_int_distribution dis(100, 255); 173 | result.color = cv::Scalar(dis(gen), 174 | dis(gen), 175 | dis(gen)); 176 | 177 | result.className = g_classes[result.class_id]; 178 | result.box = cv::Rect(xmin, ymin, xmax - xmin, ymax - ymin); 179 | 180 | objects.push_back(result); 181 | } 182 | 183 | return NN_SUCCESS; 184 | } 185 | void letterbox_decode(std::vector &objects, bool hor, int pad) 186 | { 187 | for (auto &obj : objects) 188 | { 189 | if (hor) 190 | { 191 | obj.box.x -= pad; 192 | } 193 | else 194 | { 195 | obj.box.y -= pad; 196 | } 197 | } 198 | } 199 | 200 | nn_error_e Yolov8Custom::Run(const cv::Mat &img, std::vector &objects) 201 | { 202 | 203 | // letterbox后的图像 204 | cv::Mat image_letterbox; 205 | // 预处理,支持opencv或rga 206 | Preprocess(img, "opencv", image_letterbox); 207 | // Preprocess(img, "rga", image_letterbox); 208 | // 推理 209 | Inference(); 210 | // 后处理 211 | Postprocess(image_letterbox, objects); 212 | 213 | letterbox_decode(objects, letterbox_info_.hor, letterbox_info_.pad); 214 | 215 | return NN_SUCCESS; 216 | } -------------------------------------------------------------------------------- /src/task/yolov8_custom.h: -------------------------------------------------------------------------------- 1 | #ifndef RK3588_DEMO_YOLOV8_CUSTOM_H 2 | #define RK3588_DEMO_YOLOV8_CUSTOM_H 3 | 4 | #include "engine/engine.h" 5 | 6 | #include 7 | 8 | #include 9 | #include "process/preprocess.h" 10 | #include "types/yolo_datatype.h" 11 | 12 | class Yolov8Custom 13 | { 14 | public: 15 | Yolov8Custom(); 16 | ~Yolov8Custom(); 17 | 18 | nn_error_e LoadModel(const char *model_path); 19 | 20 | nn_error_e Run(const cv::Mat &img, std::vector &objects); 21 | 22 | private: 23 | nn_error_e Preprocess(const cv::Mat &img, const std::string process_type, cv::Mat &image_letterbox); 24 | nn_error_e Inference(); 25 | nn_error_e Postprocess(const cv::Mat &img, std::vector &objects); 26 | 27 | bool ready_; 28 | LetterBoxInfo letterbox_info_; 29 | tensor_data_s input_tensor_; 30 | std::vector output_tensors_; 31 | bool want_float_; 32 | std::vector out_zps_; 33 | std::vector out_scales_; 34 | std::shared_ptr engine_; 35 | }; 36 | 37 | #endif // RK3588_DEMO_YOLOV8_CUSTOM_H 38 | -------------------------------------------------------------------------------- /src/task/yolov8_thread_pool.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "yolov8_thread_pool.h" 3 | #include "draw/cv_draw.h" 4 | // 构造函数 5 | Yolov8ThreadPool::Yolov8ThreadPool() { stop = false; } 6 | 7 | // 析构函数 8 | Yolov8ThreadPool::~Yolov8ThreadPool() 9 | { 10 | // stop all threads 11 | stop = true; 12 | cv_task.notify_all(); 13 | for (auto &thread : threads) 14 | { 15 | if (thread.joinable()) 16 | { 17 | thread.join(); 18 | } 19 | } 20 | } 21 | // 初始化:加载模型,创建线程,参数:模型路径,线程数量 22 | nn_error_e Yolov8ThreadPool::setUp(std::string &model_path, int num_threads) 23 | { 24 | // 遍历线程数量,创建模型实例,放入vector 25 | // 这些线程加载的模型是同一个 26 | for (size_t i = 0; i < num_threads; ++i) 27 | { 28 | std::shared_ptr Yolov8 = std::make_shared(); 29 | Yolov8->LoadModel(model_path.c_str()); 30 | Yolov8_instances.push_back(Yolov8); 31 | } 32 | // 遍历线程数量,创建线程 33 | for (size_t i = 0; i < num_threads; ++i) 34 | { 35 | threads.emplace_back(&Yolov8ThreadPool::worker, this, i); 36 | } 37 | return NN_SUCCESS; 38 | } 39 | 40 | // 线程函数。参数:线程id 41 | void Yolov8ThreadPool::worker(int id) 42 | { 43 | while (!stop) 44 | { 45 | std::pair task; 46 | std::shared_ptr instance = Yolov8_instances[id]; // 获取模型实例 47 | { 48 | // 获取任务 49 | std::unique_lock lock(mtx1); 50 | cv_task.wait(lock, [&] 51 | { return !tasks.empty() || stop; }); 52 | 53 | if (stop) 54 | { 55 | return; 56 | } 57 | 58 | task = tasks.front(); 59 | tasks.pop(); 60 | } 61 | // 运行模型 62 | std::vector detections; 63 | instance->Run(task.second, detections); 64 | 65 | { 66 | // 保存结果 67 | std::lock_guard lock(mtx2); 68 | results.insert({task.first, detections}); 69 | DrawDetections(task.second, detections); 70 | img_results.insert({task.first, task.second}); 71 | // cv_result.notify_one(); 72 | } 73 | } 74 | } 75 | // 提交任务,参数:图片,id(帧号) 76 | nn_error_e Yolov8ThreadPool::submitTask(const cv::Mat &img, int id) 77 | { 78 | // 如果任务队列中的任务数量大于10,等待,避免内存占用过多 79 | while (tasks.size() > 10) 80 | { 81 | // sleep 1ms 82 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); 83 | } 84 | 85 | { 86 | // 保存任务 87 | std::lock_guard lock(mtx1); 88 | tasks.push({id, img}); 89 | } 90 | cv_task.notify_one(); 91 | return NN_SUCCESS; 92 | } 93 | 94 | // 获取结果,参数:检测框,id(帧号) 95 | nn_error_e Yolov8ThreadPool::getTargetResult(std::vector &objects, int id) 96 | { 97 | // 如果没有结果,等待 98 | while (results.find(id) == results.end()) 99 | { 100 | // sleep 1ms 101 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); 102 | } 103 | std::lock_guard lock(mtx2); 104 | objects = results[id]; 105 | // remove from map 106 | results.erase(id); 107 | img_results.erase(id); 108 | 109 | return NN_SUCCESS; 110 | } 111 | 112 | // 获取结果(图片),参数:图片,id(帧号) 113 | nn_error_e Yolov8ThreadPool::getTargetImgResult(cv::Mat &img, int id) 114 | { 115 | int loop_cnt = 0; 116 | // 如果没有结果,等待 117 | while (img_results.find(id) == img_results.end()) 118 | { 119 | // 等待 5ms x 1000 = 5s 120 | std::this_thread::sleep_for(std::chrono::milliseconds(5)); 121 | loop_cnt++; 122 | if (loop_cnt > 1000) 123 | { 124 | NN_LOG_ERROR("getTargetImgResult timeout"); 125 | return NN_TIMEOUT; 126 | } 127 | } 128 | std::lock_guard lock(mtx2); 129 | img = img_results[id]; 130 | // remove from map 131 | img_results.erase(id); 132 | results.erase(id); 133 | 134 | return NN_SUCCESS; 135 | } 136 | 137 | nn_error_e Yolov8ThreadPool::getTargetResultNonBlock(std::vector &objects, int id) 138 | { 139 | if (results.find(id) == results.end()) 140 | { 141 | return NN_RESULT_NOT_READY; 142 | } 143 | std::lock_guard lock(mtx2); 144 | objects = results[id]; 145 | // remove from map 146 | results.erase(id); 147 | img_results.erase(id); 148 | 149 | return NN_SUCCESS; 150 | } 151 | 152 | // 停止所有线程 153 | void Yolov8ThreadPool::stopAll() 154 | { 155 | stop = true; 156 | cv_task.notify_all(); 157 | } -------------------------------------------------------------------------------- /src/task/yolov8_thread_pool.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef RK3588_DEMO_Yolov8_THREAD_POOL_H 4 | #define RK3588_DEMO_Yolov8_THREAD_POOL_H 5 | 6 | #include "yolov8_custom.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | class Yolov8ThreadPool 17 | { 18 | private: 19 | std::queue> tasks; // 用来存放任务 20 | std::vector> Yolov8_instances; // 模型实例 21 | std::map> results; // 用来存放结果(检测框) 22 | std::map img_results; // 用来存放结果(图片) 23 | std::vector threads; // 线程池 24 | std::mutex mtx1; 25 | std::mutex mtx2; 26 | std::condition_variable cv_task; 27 | bool stop; 28 | 29 | void worker(int id); 30 | 31 | public: 32 | Yolov8ThreadPool(); // 构造函数 33 | ~Yolov8ThreadPool(); // 析构函数 34 | 35 | nn_error_e setUp(std::string &model_path, int num_threads = 12); // 初始化 36 | nn_error_e submitTask(const cv::Mat &img, int id); // 提交任务 37 | nn_error_e getTargetResult(std::vector &objects, int id); // 获取结果(检测框) 38 | nn_error_e getTargetImgResult(cv::Mat &img, int id); // 获取结果(图片) 39 | nn_error_e getTargetResultNonBlock(std::vector &objects, int id); // 获取结果(检测框)非阻塞 40 | void stopAll(); // 停止所有线程 41 | }; 42 | 43 | #endif // RK3588_DEMO_Yolov8_THREAD_POOL_H 44 | -------------------------------------------------------------------------------- /src/types/datatype.h: -------------------------------------------------------------------------------- 1 | // 定义数据类型 2 | 3 | #ifndef RK3588_DEMO_DATATYPE_H 4 | #define RK3588_DEMO_DATATYPE_H 5 | 6 | #include 7 | #include 8 | 9 | #include "utils/logging.h" 10 | #include "types/error.h" 11 | 12 | typedef enum _tensor_layout 13 | { 14 | NN_TENSORT_LAYOUT_UNKNOWN = 0, 15 | NN_TENSOR_NCHW = 1, 16 | NN_TENSOR_NHWC = 2, 17 | NN_TENSOR_OTHER = 3, 18 | } tensor_layout_e; 19 | 20 | typedef enum _tensor_datatype 21 | { 22 | NN_TENSOR_INT8 = 1, 23 | NN_TENSOR_UINT8 = 2, 24 | NN_TENSOR_FLOAT = 3, 25 | NN_TENSOR_FLOAT16 = 4, 26 | } tensor_datatype_e; 27 | 28 | static const int g_max_num_dims = 4; 29 | 30 | 31 | typedef struct 32 | { 33 | uint32_t index; 34 | uint32_t n_dims; 35 | uint32_t dims[g_max_num_dims]; 36 | uint32_t n_elems; 37 | uint32_t size; 38 | tensor_datatype_e type; 39 | tensor_layout_e layout; 40 | int32_t zp; 41 | float scale; 42 | } tensor_attr_s; 43 | 44 | typedef struct 45 | { 46 | tensor_attr_s attr; 47 | void *data; 48 | } tensor_data_s; 49 | 50 | 51 | 52 | static size_t nn_tensor_type_to_size(tensor_datatype_e type) 53 | { 54 | switch (type) 55 | { 56 | case NN_TENSOR_INT8: 57 | return sizeof(int8_t); 58 | case NN_TENSOR_UINT8: 59 | return sizeof(uint8_t); 60 | case NN_TENSOR_FLOAT: 61 | return sizeof(float); 62 | case NN_TENSOR_FLOAT16: 63 | return sizeof(uint16_t); 64 | default: 65 | NN_LOG_ERROR("unsupported tensor type"); 66 | exit(-1); 67 | } 68 | } 69 | 70 | static void nn_tensor_attr_to_cvimg_input_data(const tensor_attr_s &attr, tensor_data_s &data) 71 | { 72 | if (attr.n_dims != 4) 73 | { 74 | NN_LOG_ERROR("unsupported input dims"); 75 | exit(-1); 76 | } 77 | data.attr.n_dims = attr.n_dims; 78 | data.attr.index = 0; 79 | data.attr.type = NN_TENSOR_UINT8; 80 | data.attr.layout = NN_TENSOR_NHWC; 81 | if (attr.layout == NN_TENSOR_NCHW) 82 | { 83 | data.attr.dims[0] = attr.dims[0]; 84 | data.attr.dims[1] = attr.dims[2]; 85 | data.attr.dims[2] = attr.dims[3]; 86 | data.attr.dims[3] = attr.dims[1]; 87 | } 88 | else if (attr.layout == NN_TENSOR_NHWC) 89 | { 90 | data.attr.dims[0] = attr.dims[0]; 91 | data.attr.dims[1] = attr.dims[1]; 92 | data.attr.dims[2] = attr.dims[2]; 93 | data.attr.dims[3] = attr.dims[3]; 94 | } 95 | else 96 | { 97 | NN_LOG_ERROR("unsupported input layout"); 98 | exit(-1); 99 | } 100 | // multiply all dims 101 | data.attr.n_elems = data.attr.dims[0] * data.attr.dims[1] * 102 | data.attr.dims[2] * data.attr.dims[3]; 103 | data.attr.size = data.attr.n_elems * sizeof(uint8_t); 104 | } 105 | 106 | #endif // RK3588_DEMO_DATATYPE_H 107 | -------------------------------------------------------------------------------- /src/types/error.h: -------------------------------------------------------------------------------- 1 | // 错误码定义 2 | 3 | #ifndef RK3588_DEMO_ERROR_H 4 | #define RK3588_DEMO_ERROR_H 5 | 6 | typedef enum 7 | { 8 | NN_SUCCESS = 0, // 成功 9 | NN_LOAD_MODEL_FAIL = -1, // 加载模型失败 10 | NN_RKNN_INIT_FAIL = -2, // rknn初始化失败 11 | NN_RKNN_QUERY_FAIL = -3, // rknn查询失败 12 | NN_RKNN_INPUT_SET_FAIL = -4, // rknn设置输入数据失败 13 | NN_RKNN_RUNTIME_ERROR = -5, // rknn运行时错误 14 | NN_IO_NUM_NOT_MATCH = -6, // 输入输出数量不匹配 15 | NN_RKNN_OUTPUT_GET_FAIL = -7, // rknn获取输出数据失败 16 | NN_RKNN_INPUT_ATTR_ERROR = -8, // rknn输入数据属性错误 17 | NN_RKNN_OUTPUT_ATTR_ERROR = -9, // rknn输出数据属性错误 18 | NN_RKNN_MODEL_NOT_LOAD = -10, // rknn模型未加载 19 | NN_STOPED = -11, // 程序已停止 20 | NN_TIMEOUT = -12, // 超时 21 | NN_RESULT_NOT_READY = -13 22 | } nn_error_e; 23 | 24 | #endif // RK3588_DEMO_ERROR_H 25 | -------------------------------------------------------------------------------- /src/types/media_dtype.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef RK3588_DEMO_MEDIA_DTYPE_H 4 | #define RK3588_DEMO_MEDIA_DTYPE_H 5 | 6 | typedef enum 7 | { 8 | NN_MEDIA_NONE = 0, 9 | NN_MEDIA_V4L2 = 1, 10 | NN_MEDIA_RTSP = 2, 11 | NN_MEDIA_FILE = 3, 12 | NN_MEDIA_IMAGE = 4, 13 | NN_MEDIA_OSD = 5, 14 | } nn_media_type_e; 15 | 16 | #endif // RK3588_DEMO_MEDIA_DTYPE_H 17 | -------------------------------------------------------------------------------- /src/types/yolo_datatype.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef RK3588_DEMO_NN_DATATYPE_H 4 | #define RK3588_DEMO_NN_DATATYPE_H 5 | 6 | #include 7 | 8 | typedef struct _nn_object_s { 9 | float x; 10 | float y; 11 | float w; 12 | float h; 13 | float score; 14 | int class_id; 15 | } nn_object_s; 16 | 17 | struct Detection 18 | { 19 | int class_id{0}; 20 | std::string className{}; 21 | float confidence{0.0}; 22 | cv::Scalar color{}; 23 | cv::Rect box{}; 24 | }; 25 | 26 | #endif //RK3588_DEMO_NN_DATATYPE_H 27 | -------------------------------------------------------------------------------- /src/utils/engine_helper.h: -------------------------------------------------------------------------------- 1 | // 辅助函数 2 | 3 | #ifndef RK3588_DEMO_ENGINE_HELPER_H 4 | #define RK3588_DEMO_ENGINE_HELPER_H 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include "utils/logging.h" 15 | #include "types/datatype.h" 16 | 17 | /** 18 | * @brief 加载模型文件 19 | * @param filename 模型文件路径 20 | * @param model_size 模型文件大小,会在函数内部赋值 21 | * @return unsigned char* 模型文件数据 22 | */ 23 | static unsigned char *load_model(const char *filename, int *model_size) 24 | { 25 | FILE *fp = fopen(filename, "rb"); 26 | if (fp == nullptr) 27 | { 28 | NN_LOG_ERROR("fopen %s fail!", filename); 29 | return nullptr; 30 | } 31 | fseek(fp, 0, SEEK_END); 32 | int model_len = ftell(fp); 33 | unsigned char *model = (unsigned char *)malloc(model_len); 34 | fseek(fp, 0, SEEK_SET); 35 | if (model_len != fread(model, 1, model_len, fp)) 36 | { 37 | NN_LOG_ERROR("fread %s fail!", filename); 38 | free(model); 39 | return nullptr; 40 | } 41 | *model_size = model_len; 42 | if (fp) 43 | { 44 | fclose(fp); 45 | } 46 | return model; 47 | } 48 | 49 | static void print_tensor_attr(rknn_tensor_attr *attr) 50 | { 51 | NN_LOG_INFO(" index=%d, name=%s, n_dims=%d, dims=[%d, %d, %d, %d], n_elems=%d, size=%d, fmt=%s, type=%s, qnt_type=%s, " 52 | "zp=%d, scale=%f", 53 | attr->index, attr->name, attr->n_dims, attr->dims[0], attr->dims[1], attr->dims[2], attr->dims[3], 54 | attr->n_elems, attr->size, get_format_string(attr->fmt), get_type_string(attr->type), 55 | get_qnt_type_string(attr->qnt_type), attr->zp, attr->scale); 56 | } 57 | 58 | static tensor_layout_e rknn_layout_convert(rknn_tensor_format fmt) 59 | { 60 | switch (fmt) 61 | { 62 | case RKNN_TENSOR_NCHW: 63 | return NN_TENSOR_NCHW; 64 | case RKNN_TENSOR_NHWC: 65 | return NN_TENSOR_NHWC; 66 | default: 67 | return NN_TENSOR_OTHER; 68 | } 69 | } 70 | 71 | static rknn_tensor_format rknn_layout_convert(tensor_layout_e fmt) 72 | { 73 | switch (fmt) 74 | { 75 | case NN_TENSOR_NCHW: 76 | return RKNN_TENSOR_NCHW; 77 | case NN_TENSOR_NHWC: 78 | return RKNN_TENSOR_NHWC; 79 | default: 80 | NN_LOG_ERROR("unsupported nn layout: %d\n", fmt); 81 | // exit program 82 | exit(1); 83 | } 84 | } 85 | 86 | static rknn_tensor_type rknn_type_convert(tensor_datatype_e type) 87 | { 88 | switch (type) 89 | { 90 | case NN_TENSOR_UINT8: 91 | return RKNN_TENSOR_UINT8; 92 | case NN_TENSOR_FLOAT: 93 | return RKNN_TENSOR_FLOAT32; 94 | default: 95 | NN_LOG_ERROR("unsupported nn type: %d\n", type); 96 | // exit program 97 | exit(1); 98 | } 99 | } 100 | 101 | static tensor_datatype_e rknn_type_convert(rknn_tensor_type type) 102 | { 103 | switch (type) 104 | { 105 | case RKNN_TENSOR_UINT8: 106 | return NN_TENSOR_UINT8; 107 | case RKNN_TENSOR_FLOAT32: 108 | return NN_TENSOR_FLOAT; 109 | case RKNN_TENSOR_INT8: 110 | return NN_TENSOR_INT8; 111 | case RKNN_TENSOR_FLOAT16: 112 | return NN_TENSOR_FLOAT16; 113 | default: 114 | NN_LOG_ERROR("unsupported rknn type: %d\n", type); 115 | // exit program 116 | exit(1); 117 | } 118 | } 119 | 120 | static tensor_attr_s rknn_tensor_attr_convert(const rknn_tensor_attr &attr) 121 | { 122 | tensor_attr_s shape; 123 | shape.n_dims = attr.n_dims; 124 | shape.index = attr.index; 125 | for (int i = 0; i < attr.n_dims; ++i) 126 | { 127 | shape.dims[i] = attr.dims[i]; 128 | } 129 | shape.size = attr.size; 130 | shape.n_elems = attr.n_elems; 131 | // set layout 132 | shape.layout = rknn_layout_convert(attr.fmt); 133 | shape.type = rknn_type_convert(attr.type); 134 | shape.zp = attr.zp; 135 | shape.scale = attr.scale; 136 | return shape; 137 | } 138 | 139 | 140 | 141 | static rknn_input tensor_data_to_rknn_input(const tensor_data_s &data) 142 | { 143 | rknn_input input; 144 | memset(&input, 0, sizeof(input)); 145 | // set default not passthrough 146 | input.index = data.attr.index; 147 | input.type = rknn_type_convert(data.attr.type); 148 | input.size = data.attr.size; 149 | input.fmt = rknn_layout_convert(data.attr.layout); 150 | input.buf = data.data; 151 | return input; 152 | } 153 | 154 | static void rknn_output_to_tensor_data(const rknn_output &output, tensor_data_s &data) 155 | { 156 | data.attr.index = output.index; 157 | data.attr.size = output.size; 158 | NN_LOG_DEBUG("output size: %d", output.size); 159 | NN_LOG_DEBUG("output want_float: %d", output.want_float); 160 | memcpy(data.data, output.buf, output.size); 161 | } 162 | 163 | #endif // RK3588_DEMO_ENGINE_HELPER_H 164 | -------------------------------------------------------------------------------- /src/utils/logging.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef RK3588_DEMO_LOGGING_H 3 | #define RK3588_DEMO_LOGGING_H 4 | 5 | // a logging wrapper so it can be easily replaced 6 | #include 7 | 8 | // log level from low to high 9 | // 0: no log 10 | // 1: error 11 | // 2: error, warning 12 | // 3: error, warning, info 13 | // 4: error, warning, info, debug 14 | static int32_t g_log_level = 3; 15 | 16 | // a printf wrapper so the msg can be formatted with %d %s, etc. 17 | 18 | #define NN_LOG_ERROR(...) \ 19 | do \ 20 | { \ 21 | if (g_log_level >= 1) \ 22 | { \ 23 | printf("[NN_ERROR] "); \ 24 | printf(__VA_ARGS__); \ 25 | printf("\n"); \ 26 | } \ 27 | } while (0) 28 | 29 | #define NN_LOG_WARNING(...) \ 30 | do \ 31 | { \ 32 | if (g_log_level >= 2) \ 33 | { \ 34 | printf("[NN_WARNING] "); \ 35 | printf(__VA_ARGS__); \ 36 | printf("\n"); \ 37 | } \ 38 | } while (0) 39 | 40 | #define NN_LOG_INFO(...) \ 41 | do \ 42 | { \ 43 | if (g_log_level >= 3) \ 44 | { \ 45 | printf("[NN_INFO] "); \ 46 | printf(__VA_ARGS__); \ 47 | printf("\n"); \ 48 | } \ 49 | } while (0) 50 | 51 | #define NN_LOG_DEBUG(...) \ 52 | do \ 53 | { \ 54 | if (g_log_level >= 4) \ 55 | { \ 56 | printf("[NN_DEBUG] "); \ 57 | printf(__VA_ARGS__); \ 58 | printf("\n"); \ 59 | } \ 60 | } while (0) 61 | 62 | #endif // RK3588_DEMO_LOGGING_H 63 | -------------------------------------------------------------------------------- /src/x11_screen_driver.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main_() 7 | { 8 | Display *display; 9 | Window root_window; 10 | GC gc; 11 | XImage *ximage; 12 | 13 | int screen; 14 | unsigned char *data; // 这里假设您有RGB888格式的图像数据 15 | 16 | int width = 640; // 图像宽度 17 | int height = 480; // 图像高度 18 | 19 | // 初始化Xlib 20 | display = XOpenDisplay(NULL); 21 | if (!display) 22 | { 23 | printf("Unable to open X display.\n"); 24 | return 1; 25 | } 26 | screen = DefaultScreen(display); 27 | root_window = RootWindow(display, screen); 28 | 29 | // 创建图形上下文 30 | gc = XCreateGC(display, root_window, 0, NULL); 31 | 32 | // 创建XImage对象并设置数据 33 | data = (unsigned char *)malloc(width * height * 3); // 3 bytes per pixel (RGB888) 34 | // 在这里将RGB888格式的图像数据填充到"data"数组中 35 | 36 | ximage = XCreateImage(display, DefaultVisual(display, screen), 37 | 24, ZPixmap, 0, (char *)data, width, height, 32, 0); 38 | 39 | // 创建X11窗口 40 | Window window = XCreateSimpleWindow(display, root_window, 0, 0, width, height, 0, 41 | BlackPixel(display, screen), WhitePixel(display, screen)); 42 | XMapWindow(display, window); 43 | 44 | // 设置XImage数据到窗口上 45 | XPutImage(display, window, gc, ximage, 0, 0, 0, 0, width, height); 46 | XFlush(display); 47 | 48 | // 等待用户关闭窗口 49 | XEvent event; 50 | while (1) 51 | { 52 | XNextEvent(display, &event); 53 | if (event.type == DestroyNotify) 54 | { 55 | break; 56 | } 57 | } 58 | 59 | // 清理资源 60 | XDestroyWindow(display, window); 61 | XFreeGC(display, gc); 62 | XCloseDisplay(display); 63 | free(data); 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /weights/yolov8s.float.rknn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MontaukLaw/3588_multi_rtsp_decode/91405545382f0ab3e18f4669e7c819e0281180bd/weights/yolov8s.float.rknn --------------------------------------------------------------------------------