├── CMakeLists.txt ├── LICENSE ├── README.md ├── app ├── CMakeLists.txt ├── common │ ├── CMakeLists.txt │ ├── include │ │ ├── xin_config_file.h │ │ └── xin_encoder_option.h │ └── source │ │ ├── xin_config_file.c │ │ └── xin_encoder_option.c └── encoder │ ├── CMakeLists.txt │ └── source │ └── xin_app_enc.c ├── build └── make-solutions.bat ├── lib ├── xin26x.exp └── xin26x.lib ├── testbin ├── VvcDecoderApp.exe ├── xin26x.dll └── xin26x_test.exe ├── third_party ├── CMakeLists.txt └── getopt │ ├── LICENSE │ ├── getopt.c │ └── getopt.h └── video_api ├── video_common └── include │ └── xin_typedef.h └── video_encoder ├── include ├── xin26x_encoder_api.h ├── xin26x_logger.h └── xin26x_params.h └── xin26x_encoder.def /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #================================================================================= 2 | # The required version of cmake 3 | #================================================================================= 4 | cmake_minimum_required(VERSION 2.8) 5 | 6 | 7 | #================================================================================= 8 | # Project Name 9 | #================================================================================= 10 | project(xin26x) 11 | 12 | #================================================================================= 13 | # Project version number 14 | #================================================================================= 15 | set(XIN26X_VERSION_MAJOR 1) 16 | set(XIN26X_VERSION_MINOR 0) 17 | 18 | #================================================================================= 19 | # Options 20 | #================================================================================= 21 | OPTION(64BIT "ON for 64 bit executable, OFF for 32 bit executable" ON) 22 | OPTION(BUILD_SHARED_LIBS "ON builds dynamic libraries, OFF builds static libraries" OFF) 23 | OPTION(ARM_PLATFORM "ON build for ARM platform" OFF) 24 | 25 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/testbin) 26 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/testbin) 27 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBUGINFO ${CMAKE_SOURCE_DIR}/testbin) 28 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_SOURCE_DIR}/testbin) 29 | 30 | if(ARM_PLATFORM) 31 | set( MY_CPU "arm" ) 32 | add_definitions(-DMATCH_NEON_CODE) 33 | add_definitions(-DCPU_TYPE_ARM) 34 | else() 35 | set( MY_CPU "x86" ) 36 | add_definitions(-DMATCH_SSE_CODE) 37 | endif() 38 | 39 | #================================================================================= 40 | # Windows - Visual Studio 41 | #================================================================================= 42 | if(WIN32) 43 | 44 | set(CUSTOM_BUILD_FLAGS "${CUSTOM_BUILD_FLAGS} -W4 /arch:AVX") 45 | 46 | if(64BIT) 47 | add_definitions(-D__x86_64__) 48 | endif(64BIT) 49 | 50 | add_definitions( -DVC -D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_MBCS) 51 | 52 | endif() 53 | 54 | 55 | #================================================================================= 56 | # Mac - natively build on Mac 57 | #================================================================================= 58 | if(CMAKE_SYSTEM_NAME MATCHES "Darwin" AND (NOT IOS)) 59 | 60 | set(CUSTOM_BUILD_FLAGS "${CUSTOM_BUILD_FLAGS} -Wall -fno-strict-aliasing -pthread -march=corei7") 61 | 62 | if(64BIT) 63 | set(CUSTOM_BUILD_FLAGS "${CUSTOM_BUILD_FLAGS} -m64") 64 | add_definitions(-D__x86_64__) 65 | else() 66 | set(CUSTOM_BUILD_FLAGS "${CUSTOM_BUILD_FLAGS} -m32") 67 | endif() 68 | 69 | add_definitions(-D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=0) 70 | 71 | endif() 72 | 73 | 74 | #================================================================================= 75 | # Linux x86 - natively build on Linux 76 | #================================================================================= 77 | if(UNIX AND (NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")) 78 | 79 | set(CUSTOM_BUILD_FLAGS "${CUSTOM_BUILD_FLAGS} -Wall -fno-strict-aliasing -pthread") 80 | 81 | if(64BIT) 82 | set(CUSTOM_BUILD_FLAGS "${CUSTOM_BUILD_FLAGS} -m64") 83 | add_definitions(-D__x86_64__) 84 | else() 85 | set(CUSTOM_BUILD_FLAGS "${CUSTOM_BUILD_FLAGS} -m32") 86 | endif(64BIT) 87 | 88 | add_definitions(-D_FILE_OFFSET_BITS=64) 89 | 90 | endif() 91 | 92 | #================================================================================= 93 | # H26X Library Name 94 | #================================================================================= 95 | if (64BIT) 96 | set (XIN26X_LIB "xin26x") 97 | else() 98 | set (XIN26X_LIB "xin26x") 99 | endif() 100 | 101 | set(CMAKE_LINK_DEF_FILE "${PROJECT_SOURCE_DIR}/video_api/h26x_encoder/xin26x_encoder.def") 102 | 103 | 104 | #================================================================================= 105 | # Build Type 106 | #================================================================================= 107 | add_definitions(${MY_DEFINITIONS}) 108 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${CUSTOM_BUILD_FLAGS} ") 109 | if (WIN32) 110 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${CUSTOM_BUILD_FLAGS} -Oi -GL ") 111 | else (WIN32) 112 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${CUSTOM_BUILD_FLAGS} ") 113 | endif(WIN32) 114 | set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_PROFILE} ${CUSTOM_BUILD_FLAGS} ") 115 | set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${CUSTOM_BUILD_FLAGS} ") 116 | set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} ${CUSTOM_BUILD_FLAGS} ") 117 | 118 | 119 | #================================================================================= 120 | # All the subdirectories need to be compiled 121 | #================================================================================= 122 | add_subdirectory(app) 123 | 124 | #================================================================================= 125 | # Message 126 | #================================================================================= 127 | 128 | MESSAGE(STATUS "CMAKE_HOST_SYSTEM_NAME: " ${CMAKE_HOST_SYSTEM_NAME}) 129 | MESSAGE(STATUS "CMAKE_HOST_SYSTEM_VERSION: " ${CMAKE_HOST_SYSTEM_VERSION}) 130 | MESSAGE(STATUS "CMAKE_HOST_SYSTEM_PROCESSOR: " ${CMAKE_HOST_SYSTEM_PROCESSOR}) 131 | MESSAGE(STATUS "CMAKE_HOST_SYSTEM: " ${CMAKE_HOST_SYSTEM}) 132 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2024, Pig Peppa 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | xin26x 2 | ======= 3 | - Xin26x is an univeral video encoder framework, which can accommodate all video coding standard on this planet so far. 4 | - It is optimized for real time video communication, live streaming application and offline video encoding. 5 | - It currently supports HEVC, AV1(I frame), VVC video coding standards. 6 | - It is a very high performance encoder. 7 | - It is well-structured for understandability, maintainability and scalability. 8 | - It is written from scratch and has a plain C API to enable a simple integration into other software. 9 | - It is very small footprint encoder, it takes very small memory requirement under restricted mode. 10 | 11 | Encoder Usage 12 | ---------- 13 | xin26x_test.exe -i input.yuv -w 1280 -h 720 -f 30 -a 2 -p 1 -r 1 -b 2000000 -o test.bin 14 | xin26x_test.exe -i input.yuv -w 1280 -h 720 -f 30 -a 2 -p 1 -r 0 -q 32 -o test.bin 15 | 16 | Building Project 17 | ---------- 18 | - Our Windows build use CMake and Visual Studio. The workable version is CMake3.5 or above and Visual Studio 2022. 19 | - Run make-solutions.bat under build folder, building projects will be generated under this folder. 20 | - In addition, we put a pre-built win64 exe under folder testbin, you can run it on win64 without build. 21 | 22 | Basic Parameters 23 | ---------- 24 | -i/--input 25 | which specifies input YUV file name. Currently we accept YUV 420 video format. 26 | 27 | -a/--algmode 28 | which specifies algorithm mode. 0: H265 1: AV1 2: H266 29 | 30 | -w/--width 31 | which specifies input YUV luma width. 32 | 33 | -h/--height 34 | which specifies input YUV luma height. 35 | 36 | -f/--framerate 37 | which specifies the frame rate of the input video. 38 | 39 | -t/--temporallayer 40 | which specifies temporal layer number. It works under all P frame sequence. 41 | 42 | -p/--preset 43 | which specifies the encoding preset, trading off compression efficiency against encoding speed. [0, 6] Big number means high quality but low encoder speed. 44 | 45 | -o/--output 46 | which specifies output bitstream file name. For HEVC and VVC, the output file accord with Annex B specification. For AV1, the output file accord with OBU format. 47 | 48 | -R/--recon 49 | which specifies reconstruction YUV file name. It is not a must input parameter. 50 | 51 | -r/--ratecontrol 52 | which specifies rate control mode. 0: rate control is off (fixed qp), 1: rate control is on. 53 | 54 | -b/--bitrate 55 | which specifies target bitrate. It works under rate control is on. 56 | 57 | -q/--qp 58 | which specifies quantization paramter. It works under rate control is off. 59 | 60 | -n/--framenumber 61 | which specifies how many frames to be encoded. 62 | 63 | -B/--bframes 64 | which specifies how many B frames in a gop. Currently, we support 1, 3 and 7. 65 | 66 | -W/--wpp 67 | which specifies whether wavefront parallel processing is enabled. 0: disable 1: enable. 68 | 69 | -F/--fpp 70 | which specifies whether frame parallel processing is enabled. 0: disable 1: enable. 71 | 72 | -T/--thread 73 | which specifies thread number in thread pool. It is decided by local system if this number is 0. 74 | 75 | --refframes 76 | which specifies how many frames is used for reference. 77 | 78 | --signbithide 79 | which specifies whether sign bit hidden coding tool is used in encoder. 0: off 1: on. 80 | 81 | -d/--rdoq 82 | which specifies whether rate distortion optimization quantization is enabled. 0: disable 1: enable. 83 | 84 | Api Usage 85 | ----------------- 86 | Please refer to xin_app_enc.c. 87 | 88 | Performance Comparison 89 | ----------------- 90 | 91 | Offline Comparison(Xin26x vs X265) 92 | ----------------- 93 | 94 | | INPUT YUV BD-PSNR (dB) | x265 veryslow | xin265 p1 | xin265 p4 | xin265 p6 | xin266 p1 | xin266 p4 | xin266 p6 | 95 | | -----------------------------------| --------------| ----------| ----------| ----------| ----------| ----------| ----------| 96 | | pedestrian_area | 0 | -0.37 | 0.34 | 0.54 | -0.1 | 0.67 | 0.85 | 97 | | B_Kimono1_1920x1080_24 | 0 | -0.50 | 0.25 | 0.4 | -0.16 | 0.67 | 0.86 | 98 | | B_ParkScene_1920x1080_24 | 0 | -0.47 | 0.39 | 0.61 | -0.13 | 0.84 | 1.07 | 99 | | B_BasketballDrive_1920x1080_50 | 0 | -0.61 | 0.10 | 0.27 | -0.30 | 0.50 | 0.68 | 100 | | B_BQTerrace_1920x1080_60 | 0 | -0.17 | 0.57 | 0.71 | 0.32 | 0.73 | 0.93 | 101 | | B_Cactus_1920x1080_50 | 0 | -0.38 | 0.49 | 0.68 | 0.08 | 0.78 | 0.98 | 102 | | Overall | 0 | -0.42 | 0.36 | 0.54 | -0.05 | 0.70 | 0.90 | 103 | 104 | ----------------- 105 | 106 | | INPUT YUV BD-RATE (%) | x265 veryslow | xin265 p1 | xin265 p4 | xin265 p6 | xin266 p1 | xin266 p4 | xin266 p6 | 107 | | -----------------------------------| --------------| ----------| ----------| ----------| ----------| ----------| ----------| 108 | | pedestrian_area | 0 | 18.9 | -16 | -24.82 | 4.59 | -30.66 | -37.92 | 109 | | B_Kimono1_1920x1080_24 | 0 | 22.3 | -10.08 | -15.74 | 6.73 | -26.11 | -32.13 | 110 | | B_ParkScene_1920x1080_24 | 0 | 17.45 | -12.76 | -19.24 | 4.21 | -25.96 | -31.83 | 111 | | B_BasketballDrive_1920x1080_50 | 0 | 33.35 | -4.83 | -12.67 | 15.27 | -23.00 | -30.72 | 112 | | B_BQTerrace_1920x1080_60 | 0 | 20.4 | -48.67 | -57.19 | -29.89 | -58.49 | -67.56 | 113 | | B_Cactus_1920x1080_50 | 0 | 24.56 | -25.44 | -35.36 | -4.48 | -40.14 | -49.09 | 114 | | Overall | 0 | 22.83 | -19.63 | -27.5 | -0.6 | -34.06 | -41.54 | 115 | 116 | Offline encoder parameters for xin26x and x265 are as follows: 117 | 118 | x265 veryslow 119 | x265.exe -o test.bin --input-res 1920x1080 --fps 30 --frames frames --bitrate kbitrate --tune psnr -p veryslow input.yuv 120 | 121 | xin265 p1 122 | xin26x_test.exe -o test.bin -i input.yuv -w 1920 -h 1080 -f 30 -n frames -r 6 -b bitrate -p 1 -a 0 123 | 124 | xin265 p4 125 | xin26x_test.exe -o test.bin -i input.yuv -w 1920 -h 1080 -f 30 -n frames -r 6 -b bitrate -p 4 -a 0 126 | 127 | xin265 p6 128 | xin26x_test.exe -o test.bin -i input.yuv -w 1920 -h 1080 -f 30 -n frames -r 6 -b bitrate -p 6 -a 0 129 | 130 | xin266 p1 131 | xin26x_test.exe -o test.bin -i input.yuv -w 1920 -h 1080 -f 30 -n frames -r 6 -b bitrate -p 1 -a 2 132 | 133 | xin266 p4 134 | xin26x_test.exe -o test.bin -i input.yuv -w 1920 -h 1080 -f 30 -n frames -r 6 -b bitrate -p 4 -a 2 135 | 136 | xin266 p6 137 | xin26x_test.exe -o test.bin -i input.yuv -w 1920 -h 1080 -f 30 -n frames -r 6 -b bitrate -p 6 -a 2 138 | 139 | In above table, we set x265(veryslow) as a reference, others are compared with x265(veryslow). x265 is 2020/12/25 version. 140 | 141 | Lowdelay Comparison(Xin265) 142 | ----------------- 143 | 144 | Single thread for IPPPPPPPPP under suitbale bitrate 145 | 146 | | B_BasketballDrive_1920x1080_50.yuv | FPS | PSNR | Encoder parameters| 147 | | -----------------------------------| --------------| -------------| ------------------| 148 | | xin26x | 20.68 | 36.929 | xin26x_test.exe -i B_BasketballDrive_1920x1080_50.yuv -a 0 -o test.265 -w 1920 -h 1080 -b 3000000 -f 30 -I 0 --wpp 0 --thread 1 --preset 3 --bframes 0 -n 500 | 149 | | x265 | 7.96 | 36.913 | x265.exe --preset fast -I -1 --input-res 1920x1080 --input B_BasketballDrive_1920x1080_50.yuv test.265 --bitrate 3000 --fps 30 --pools 1 --bframes 0 --frame-threads 0 --no-wpp --tune psnr -f 500 | 150 | 151 | | pedestrian_area.yuv | FPS | PSNR | Encoder parameters| 152 | | -----------------------------------| --------------| -------------| ------------------| 153 | | xin26x | 39.203 | 39.719 | xin26x_test.exe -i pedestrian_area.yuv -a 0 -o test.265 -w 1920 -h 1080 -b 2000000 -f 30 -I 0 --wpp 0 --thread 1 --preset 0 --bframes 0 | 154 | | x265 | 8.35 | 39.707 | x265.exe --preset fast -I -1 --input-res 1920x1080 --input pedestrian_area.yuv test.265 --bitrate 2000 --fps 30 --pools 1 --bframes 0 --frame-threads 0 --no-wpp --tune psnr | 155 | 156 | | E_KristenAndSara_1280x720_60.yuv | FPS | PSNR | Encoder parameters| 157 | | -----------------------------------| --------------| -------------| ------------------| 158 | | xin26x | 103.68 | 43.218 | xin26x_test.exe -i E_KristenAndSara_1280x720_60.yuv -a 0 -o test.265 -w 1280 -h 720 -b 1000000 -f 30 -I 0 --wpp 0 --thread 1 --preset 0 --bframes 0 | 159 | | x265 | 23.56 | 43.183 | x265.exe --preset fast -I -1 --input-res 1280x720 --input E_KristenAndSara_1280x720_60.yuv test.265 --bitrate 1000 --fps 30 --pools 1 --bframes 0 --frame-threads 0 --no-wpp --tune psnr | 160 | 161 | | sc_desktop_1920x1080_60_8bit_420.yuv | FPS | PSNR | Encoder parameters| 162 | | -------------------------------------| --------------| -------------| ------------------| 163 | | xin26x | 39.48 | 40.082 | xin26x_test.exe -i sc_desktop_1920x1080_60_8bit_420.yuv -a 0 -o test.265 -w 1920 -h 1080 -b 2000000 -f 30 -I 0 --wpp 0 --thread 1 --preset 0 --bframes 0 -s 1 | 164 | | x265 | 16.83 | 29.817 | x265.exe --preset fast -I -1 --input-res 1920x1080 --input sc_desktop_1920x1080_60_8bit_420.yuv test.265 --bitrate 2000 --fps 30 --pools 1 --bframes 0 --frame-threads 0 --no-wpp --tune psnr | 165 | 166 | For a encoder, we normally take a tradeoff between picture quality and encoder sppeed. For a RTC encoder, performance on unit core or whole system capacity is more important. The performance of xin26x(HEVC) is x4 compared to x265 under single unit core. One important thing is that, the screen content coding performance of xin26x(HEVC) outperform x265 greatly both for speed and quality. 167 | 168 | I would like to note that, to make fair comparison to x265, the lookahead and cu-tree are both enabled. In addition, ABR is adopted in both xin26x and x265. When it comes to real RTC world, none of these coding tools can be applied, so there will be a inevitable loss of PSNR for RTC encoder. But the speed for a real RTC encoder should be faster than the data in the table. 169 | 170 | Processor Support 171 | ----------------- 172 | - Intel x86 with AVX2 support. 173 | 174 | Known Issues 175 | ----------------- 176 | - Max resolution we support is 3860x2160. 177 | - Max temporal layer we support is 3. 178 | - For AV1, the outputted frame are all IDR. Please ignore encoder speed, currently AV1 encoder is pure C code, without SIMD or multi-thread optimization. 179 | - Under evaluation mode, only ABR is supported. 180 | - For VVC, please use vtm 10 to decode the bitstream. You can download vtm 10 from https://vcgit.hhi.fraunhofer.de/jvet/VVCSoftware_VTM/-/releases/VTM-10.0 181 | 182 | Todo Lists 183 | ----------------- 184 | 185 | Xin26x 186 | ----------------- 187 | - 2 pass coding tool support. 188 | - 16 and 32 picture gop size support. 189 | - Preprocessing algorithm refactor. 190 | - Rate contronl algorithm refine. 191 | - Encoder structre refactor for offline coding consideration. 192 | - 10 bit encoder support. 193 | - Fast algorithm optimization. 194 | 195 | HEVC 196 | ----------------- 197 | - Minor structure adjustment. 198 | - Local algorithm refinement. 199 | 200 | AV1 201 | ----------------- 202 | - P and B frame support. 203 | - General video coding tools support. 204 | - SIMD optimization. 205 | 206 | VVC 207 | ----------------- 208 | - Screen content coding tools support. 209 | - SIMD optimization. 210 | - More VVC coding tools support. 211 | - Memory usage reduction. 212 | - Affine motion estimation. 213 | 214 | About Xin26x 215 | ----------------- 216 | The main purpose of Xin26x is unification. Xin26x is designed to unify different video standards and different implementations for same video standard. 217 | 218 | In past 30 years, there are a lot of video standards released by different groups. Fortunately, these standards are all block-based motion compensation and transform hybrid scheme. Actually, it never changed since h.261 had been released. Based on that, Xin26x is designed to unify mainstream video standards into ONE encoder. Xin26x is a flexible video encoder framework to accommodate all the video standard so far on this planet. Currently, Xin26x have implemented h.265 and h.266. For AV1, Xin26x supports static picture encoding. Later, Xin26x is planning to accommodate EVC. 219 | 220 | For same video standard, there are different implememations target to different application scenario. In my opinion, there are mainly 3 categories of encoder according to application latency. 221 | | Latency | Scenario | 222 | | -----------------------------------| ---------------------------------- | 223 | | 200ms or blow (real time) | real time video communication | 224 | | 1s-3s (low latency) | live video boardcast | 225 | | 10s or above (offline) | offline video application | 226 | 227 | Different encoding tools are adopted for different encoder implementions. For example, B frame is normally not adopted for RTC(Real-Time Communication) encoder. Frame parallelism is not used for RTC encoder. Rate control for RTC encoder is very strict. Besides, lookahead and mb-tree are normally not applied on first 2 encoders. Screen content coding tools are normally considered for a RTC encoder. In current industry, Openh264 is for real time video communication application. X264 is mainly for offline and low latency. Xin26x begins at a RTC video encoder. To accommodate offline video coding tools and video standard evolution, the encoder architecture has been greatly refactored. Also to make encoder work under different application scenarios, multiple different rate control modes are designed in Xin26x. 228 | 229 | I wish video coding standardization would take a revolution, break though current hybrid scheme, stop piling up computation for better compression rate in the future, then Xin26x reaches its end-of-life. Otherwise, Xin26x will keep catching up with the latest video coding standard, till I reach my end-of-life. 230 | 231 | Basicly, Xin26x is purely a result of coding happiness pursuit. It is named after my 8 year old beautiful child. I would like her know how great her father is. After she grows up, I wish she would know how father loved her. 232 | 233 | Any question, please contact pig.peppa@qq.com 234 | 235 | -------------------------------------------------------------------------------- /app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(encoder) -------------------------------------------------------------------------------- /app/common/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Add include directories here 3 | # 4 | include_directories ( 5 | if(WIN32) 6 | "${PROJECT_SOURCE_DIR}/third_party/getopt" 7 | endif() 8 | "${PROJECT_SOURCE_DIR}/video_api/video_common/include" 9 | "${PROJECT_SOURCE_DIR}/video_api/h265_encoder/include" 10 | "${PROJECT_SOURCE_DIR}/app/common/include") 11 | 12 | FILE(GLOB cmake_includes include/*.h) 13 | FILE(GLOB cmake_sources source/*.c) 14 | 15 | add_library(${APP_COMMON_LIB} ${cmake_sources} ${cmake_includes}) 16 | 17 | -------------------------------------------------------------------------------- /app/common/include/xin_config_file.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************//** 2 | * 3 | * @file xin_config_file.h 4 | * @authors shennung 5 | * @copyright (c) 2020, shennung All rights reserved 6 | * 7 | *******************************************************************************/ 8 | #ifndef _xin_config_file_h_ 9 | #define _xin_config_file_h_ 10 | 11 | #include 12 | #include 13 | #include "xin26x_params.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | typedef struct config_file_struct 19 | { 20 | FILE* fileHandle; 21 | char* key; 22 | char* value; 23 | }config_file_struct; 24 | 25 | 26 | config_file_struct* CreateConfigFile(const char* configFileName); 27 | void DeleteConfigFile(const config_file_struct* configFile); 28 | bool ReadOneLine(const config_file_struct* configFile); 29 | bool EndOfFile(const config_file_struct* configFile); 30 | 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | 36 | #endif // _config_file_h_ 37 | -------------------------------------------------------------------------------- /app/common/include/xin_encoder_option.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************//** 2 | * 3 | * @file encoder_option.h 4 | * @authors shennung 5 | * @copyright (c) 2020, shennung All rights reserved 6 | * 7 | *******************************************************************************/ 8 | #ifndef _xin_encoder_option_h_ 9 | #define _xin_encoder_option_h_ 10 | 11 | #include 12 | #include "xin26x_params.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | #define MAX_FILE_NAME_LEN 256 19 | #define MAX_FRAME_WIDTH 1920 20 | #define MAX_FRAME_HEIGHT 1088 21 | 22 | typedef struct encoder_option_struct 23 | { 24 | //xin encoder configure 25 | xin26x_params xinConfig; 26 | 27 | //app option 28 | char inputFileName[MAX_FILE_NAME_LEN]; 29 | char outputFileName[MAX_FILE_NAME_LEN]; 30 | char reconFileName[MAX_FILE_NAME_LEN]; 31 | FILE* inputFileHandle; 32 | FILE* outputFileHandle; 33 | FILE* reconFileHandle; 34 | 35 | }encoder_option_struct; 36 | 37 | 38 | encoder_option_struct* CreateEncoderOption(int argc, char**argv); 39 | void DeleteEncoderOption(encoder_option_struct* encoder_option); 40 | void PrintEncoderOption(encoder_option_struct* encoder_option); 41 | void ShowHelp(); 42 | void ShowVersion(); 43 | 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif // _encoder_option_h_ 50 | -------------------------------------------------------------------------------- /app/common/source/xin_config_file.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************//** 2 | * 3 | * @file xin_config_file.c 4 | * @authors shennung 5 | * @brief xin26x encoder configuration parse related subroutines. 6 | * @copyright (c) 2020, shennung All rights reserved 7 | * 8 | *******************************************************************************/ 9 | #include 10 | #include 11 | #include "xin_typedef.h" 12 | #include "xin_config_file.h" 13 | 14 | static const int MAX_OPTION_LEN = 256; 15 | 16 | config_file_struct* CreateConfigFile(const char* configFileName) 17 | { 18 | config_file_struct* configFile = 0; 19 | if (configFileName == 0) 20 | { 21 | printf("Config file name is null\n"); 22 | return configFile; 23 | } 24 | 25 | 26 | configFile = (config_file_struct*)malloc(sizeof(config_file_struct)); 27 | if (configFile) 28 | { 29 | memset((void*)configFile, 0, sizeof(config_file_struct)); 30 | configFile->fileHandle = fopen(configFileName, "r"); 31 | if (configFile->fileHandle == 0) 32 | { 33 | free(configFile); 34 | configFile = 0; 35 | } 36 | else 37 | { 38 | configFile->key = (char*)malloc(MAX_OPTION_LEN); 39 | configFile->value = (char*)malloc(MAX_OPTION_LEN); 40 | } 41 | } 42 | 43 | return configFile; 44 | } 45 | 46 | void DeleteConfigFile(const config_file_struct* configFile) 47 | { 48 | if (configFile) 49 | { 50 | fclose(configFile->fileHandle); 51 | free(configFile->key); 52 | free(configFile->value); 53 | free((void*)configFile); 54 | } 55 | } 56 | 57 | bool ReadOneLine(const config_file_struct* configFile) 58 | { 59 | bool ret = false; 60 | bool commentFlag = false; 61 | int strLen = 0; 62 | char* str; 63 | 64 | if (configFile == 0) 65 | { 66 | return ret; 67 | } 68 | 69 | memset((void*)configFile->key, 0, MAX_OPTION_LEN); 70 | memset((void*)configFile->value, 0, MAX_OPTION_LEN); 71 | 72 | str = configFile->key; 73 | 74 | for (;;) 75 | { 76 | const char c = (char)fgetc(configFile->fileHandle); 77 | if (c == '\n' || feof(configFile->fileHandle)) 78 | { 79 | break; 80 | } 81 | 82 | if (c == '#') 83 | { 84 | commentFlag = true; 85 | } 86 | 87 | if (!commentFlag) 88 | { 89 | if (c == '\t' || c == ' ') 90 | { 91 | if (*(configFile->key) != 0) 92 | { 93 | str = configFile->value; 94 | strLen = 0; 95 | } 96 | if (*(configFile->value) != 0) 97 | { 98 | str = 0; 99 | strLen = 0; 100 | } 101 | } 102 | else 103 | { 104 | if (str != 0) 105 | { 106 | *str = c; 107 | str++; 108 | strLen++; 109 | } 110 | } 111 | } 112 | } 113 | 114 | if (*(configFile->value) != 0) 115 | { 116 | ret = true; 117 | } 118 | 119 | return ret; 120 | } 121 | 122 | bool EndOfFile(const config_file_struct* configFile) 123 | { 124 | if(configFile) 125 | { 126 | if (feof(configFile->fileHandle)) 127 | { 128 | return true; 129 | } 130 | else 131 | { 132 | return false; 133 | } 134 | } 135 | else 136 | { 137 | return true; 138 | } 139 | } 140 | 141 | -------------------------------------------------------------------------------- /app/common/source/xin_encoder_option.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************//** 2 | * 3 | * @file xin_encoder_option.c 4 | * @authors shennung 5 | * @brief xin26x encoder configuration parse related subroutines. 6 | * @copyright (c) 2020, shennung All rights reserved 7 | * 8 | *******************************************************************************/ 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "xin_typedef.h" 14 | #include "xin_encoder_option.h" 15 | #include "xin_config_file.h" 16 | #include "xin26x_encoder_api.h" 17 | 18 | static const char encoder_short_options[] = "c:i:o:n:R:B:I:w:h:f:d:y:b:a:t:u:e:E:m:s:r:q:O:p:D:P:L:T:W:F:HV"; 19 | static const struct option encoder_long_options[] = 20 | { 21 | { "config", required_argument, 0, 'c' }, 22 | { "input", required_argument, 0, 'i' }, 23 | { "output", required_argument, 0, 'o' }, 24 | { "algmode", required_argument, 0, 'a' }, 25 | { "framenumber", required_argument, 0, 'n' }, 26 | { "recon", required_argument, 0, 'R' }, 27 | { "width", required_argument, 0, 'w' }, 28 | { "height", required_argument, 0, 'h' }, 29 | { "framerate", required_argument, 0, 'f' }, 30 | { "bitrate", required_argument, 0, 'b' }, 31 | { "temporallayer", required_argument, 0, 't' }, 32 | { "screencontent", required_argument, 0, 's' }, 33 | { "transformSkip", required_argument, 0, 'A' }, 34 | { "preset", required_argument, 0, 'p' }, 35 | { "cclm", required_argument, 0, 'C' }, 36 | { "dmvr", required_argument, 0, 'y' }, 37 | { "mctf", required_argument, 0, 'K' }, 38 | { "wpp", required_argument, 0, 'W' }, 39 | { "fpp", required_argument, 0, 'F' }, 40 | { "bframes", required_argument, 0, 'B' }, 41 | { "intraperiod", required_argument, 0, 'I' }, 42 | { "intranxn", required_argument, 0, 'N' }, 43 | { "internxn", required_argument, 0, 'X' }, 44 | { "thread", required_argument, 0, 'T' }, 45 | { "sbh", required_argument, 0, 'S' }, 46 | { "sao", required_argument, 0, 'O' }, 47 | { "alf", required_argument, 0, 'l' }, 48 | { "deblock", required_argument, 0, 'D' }, 49 | { "unitTree", required_argument, 0, 'u' }, 50 | { "treeStrength", required_argument, 0, 'e' }, 51 | { "refreshtype", required_argument, 0, 'U' }, 52 | { "refframes", required_argument, 0, 'M' }, 53 | { "frameSkip", required_argument, 0, '1' }, 54 | { "ctuSize", required_argument, 0, '2' }, 55 | { "minQtSize", required_argument, 0, '3' }, 56 | { "maxBtSize", required_argument, 0, '4' }, 57 | { "maxTtsize", required_argument, 0, '5' }, 58 | { "maxMttDepth", required_argument, 0, '6' }, 59 | { "minCuSize", required_argument, 0, '7' }, 60 | { "lookAhead", required_argument, 0, '8' }, 61 | { "trSize64", required_argument, 0, '9' }, 62 | { "maxTrSkipSize", required_argument, 0, 'G' }, 63 | { "adaBFrame", required_argument, 0, 'g' }, 64 | { "rectparttype", required_argument, 0, 'Q' }, 65 | { "sbSize", required_argument, 0, 'z' }, 66 | { "rateControl", required_argument, 0, 'r' }, 67 | { "initqp", required_argument, 0, 'q' }, 68 | { "rdoq", required_argument, 0, 'd' }, 69 | { "logLevel", required_argument, 0, 'E' }, 70 | { "psnr", required_argument, 0, 'P' }, 71 | { "help", no_argument, 0, 'H' }, 72 | { "version", no_argument, 0, 'V' }, 73 | { "sbTmvp", required_argument, 0, 128 }, 74 | { "affine", required_argument, 0, 129 }, 75 | { "mts", required_argument, 0, 130 }, 76 | { "gpb", required_argument, 0, 131 }, 77 | { "depQuant", required_argument, 0, 132 }, 78 | { "scenecut", required_argument, 0, 133 }, 79 | { "zerolatency", required_argument, 0, 134 }, 80 | { "amvr", required_argument, 0, 135 }, 81 | { "vbvBufSize", required_argument, 0, 136 }, 82 | { "vbvMaxRate", required_argument, 0, 137 }, 83 | { "crf", required_argument, 0, 138 }, 84 | { "minQp", required_argument, 0, 139 }, 85 | { "maxQp", required_argument, 0, 140 }, 86 | { "bcw", required_argument, 0, 141 }, 87 | { "hidden", required_argument, 0, 255 }, 88 | { 0, 0, 0, 0 } 89 | }; 90 | 91 | static void SetPreset ( 92 | encoder_option_struct *encoderOption) 93 | { 94 | switch (encoderOption->xinConfig.encoderMode) 95 | { 96 | case 0: 97 | encoderOption->xinConfig.refFrameNum = 1; 98 | encoderOption->xinConfig.motionSearchMode = 1; 99 | encoderOption->xinConfig.enableRdoq = 0; 100 | encoderOption->xinConfig.enableMctf = 0; 101 | 102 | // VVC 103 | encoderOption->xinConfig.ctuSize = 64; 104 | encoderOption->xinConfig.maxMttDepth = 0; 105 | encoderOption->xinConfig.lumaTrSize64 = 0; 106 | encoderOption->xinConfig.enableCclm = 0; 107 | encoderOption->xinConfig.enableDmvr = 0; 108 | encoderOption->xinConfig.enableAlf = 0; 109 | encoderOption->xinConfig.enableAmvr = FALSE; 110 | encoderOption->xinConfig.enableBcw = FALSE; 111 | 112 | // HEVC 113 | encoderOption->xinConfig.enableSmp = 0; 114 | 115 | break; 116 | 117 | case 1: 118 | encoderOption->xinConfig.refFrameNum = 1; 119 | encoderOption->xinConfig.motionSearchMode = 1; 120 | encoderOption->xinConfig.enableRdoq = 0; 121 | encoderOption->xinConfig.enableMctf = 0; 122 | 123 | // VVC 124 | encoderOption->xinConfig.ctuSize = 64; 125 | encoderOption->xinConfig.maxMttDepth = 1; 126 | encoderOption->xinConfig.maxBtSize = 64; 127 | encoderOption->xinConfig.maxTtSize = 8; 128 | encoderOption->xinConfig.lumaTrSize64 = 0; 129 | encoderOption->xinConfig.enableCclm = 0; 130 | encoderOption->xinConfig.enableDmvr = 0; 131 | encoderOption->xinConfig.enableAlf = 0; 132 | encoderOption->xinConfig.enableAmvr = FALSE; 133 | encoderOption->xinConfig.enableBcw = FALSE; 134 | 135 | // HEVC 136 | encoderOption->xinConfig.enableSmp = 0; 137 | 138 | break; 139 | 140 | case 2: 141 | encoderOption->xinConfig.refFrameNum = 2; 142 | encoderOption->xinConfig.enableRdoq = 0; 143 | encoderOption->xinConfig.motionSearchMode = 1; 144 | encoderOption->xinConfig.enableMctf = 1; 145 | 146 | // VVC 147 | encoderOption->xinConfig.ctuSize = 64; 148 | encoderOption->xinConfig.maxMttDepth = 1; 149 | encoderOption->xinConfig.maxBtSize = 64; 150 | encoderOption->xinConfig.maxTtSize = 8; 151 | encoderOption->xinConfig.lumaTrSize64 = 1; 152 | encoderOption->xinConfig.enableCclm = 0; 153 | encoderOption->xinConfig.enableDmvr = 1; 154 | encoderOption->xinConfig.enableAlf = 1; 155 | encoderOption->xinConfig.enableAmvr = FALSE; 156 | encoderOption->xinConfig.enableBcw = FALSE; 157 | 158 | // HEVC 159 | encoderOption->xinConfig.enableSmp = 0; 160 | 161 | break; 162 | 163 | case 3: 164 | encoderOption->xinConfig.refFrameNum = 3; 165 | encoderOption->xinConfig.motionSearchMode = 1; 166 | encoderOption->xinConfig.enableRdoq = 0; 167 | encoderOption->xinConfig.enableMctf = 1; 168 | 169 | // VVC 170 | encoderOption->xinConfig.ctuSize = 64; 171 | encoderOption->xinConfig.maxMttDepth = 1; 172 | encoderOption->xinConfig.maxBtSize = 64; 173 | encoderOption->xinConfig.maxTtSize = 64; 174 | encoderOption->xinConfig.lumaTrSize64 = 1; 175 | encoderOption->xinConfig.enableCclm = 0; 176 | encoderOption->xinConfig.enableDmvr = 1; 177 | encoderOption->xinConfig.enableAlf = 1; 178 | encoderOption->xinConfig.enableAmvr = FALSE; 179 | encoderOption->xinConfig.enableBcw = FALSE; 180 | 181 | // HEVC 182 | encoderOption->xinConfig.enableSmp = 0; 183 | 184 | break; 185 | 186 | case 4: 187 | encoderOption->xinConfig.refFrameNum = 2; 188 | encoderOption->xinConfig.enableRdoq = 1; 189 | encoderOption->xinConfig.motionSearchMode = 2; 190 | encoderOption->xinConfig.enableMctf = 1; 191 | 192 | // VVC 193 | encoderOption->xinConfig.ctuSize = 64; 194 | encoderOption->xinConfig.maxMttDepth = 1; 195 | encoderOption->xinConfig.maxBtSize = 64; 196 | encoderOption->xinConfig.maxTtSize = 64; 197 | encoderOption->xinConfig.lumaTrSize64 = 1; 198 | encoderOption->xinConfig.enableCclm = 0; 199 | encoderOption->xinConfig.enableDmvr = 1; 200 | encoderOption->xinConfig.enableAlf = 1; 201 | encoderOption->xinConfig.enableSbTmvp = FALSE; 202 | encoderOption->xinConfig.enableAffine = FALSE; 203 | encoderOption->xinConfig.enableMts = TRUE; 204 | encoderOption->xinConfig.enableDepQuant = TRUE; 205 | encoderOption->xinConfig.enableAmvr = FALSE; 206 | encoderOption->xinConfig.enableBcw = FALSE; 207 | 208 | // HEVC 209 | encoderOption->xinConfig.enableSmp = 1; 210 | 211 | break; 212 | 213 | case 5: 214 | encoderOption->xinConfig.refFrameNum = 3; 215 | encoderOption->xinConfig.enableRdoq = 1; 216 | encoderOption->xinConfig.motionSearchMode = 2; 217 | encoderOption->xinConfig.enableMctf = 1; 218 | 219 | // VVC 220 | encoderOption->xinConfig.ctuSize = 128; 221 | encoderOption->xinConfig.maxMttDepth = 1; 222 | encoderOption->xinConfig.maxBtSize = 64; 223 | encoderOption->xinConfig.maxTtSize = 64; 224 | encoderOption->xinConfig.lumaTrSize64 = 1; 225 | encoderOption->xinConfig.enableCclm = 0; 226 | encoderOption->xinConfig.enableDmvr = 1; 227 | encoderOption->xinConfig.enableAlf = TRUE; 228 | encoderOption->xinConfig.enableSbTmvp = TRUE; 229 | encoderOption->xinConfig.enableAffine = TRUE; 230 | encoderOption->xinConfig.enableMts = TRUE; 231 | encoderOption->xinConfig.enableDepQuant = TRUE; 232 | encoderOption->xinConfig.enableAmvr = FALSE; 233 | encoderOption->xinConfig.enableBcw = FALSE; 234 | 235 | // HEVC 236 | encoderOption->xinConfig.enableSmp = 1; 237 | 238 | break; 239 | 240 | case 6: 241 | encoderOption->xinConfig.refFrameNum = 4; 242 | encoderOption->xinConfig.enableRdoq = 1; 243 | encoderOption->xinConfig.motionSearchMode = 2; 244 | encoderOption->xinConfig.enableMctf = 1; 245 | 246 | // VVC 247 | encoderOption->xinConfig.ctuSize = 128; 248 | encoderOption->xinConfig.maxMttDepth = 1; 249 | encoderOption->xinConfig.maxBtSize = 64; 250 | encoderOption->xinConfig.maxTtSize = 64; 251 | encoderOption->xinConfig.lumaTrSize64 = 1; 252 | encoderOption->xinConfig.enableCclm = 1; 253 | encoderOption->xinConfig.enableDmvr = 1; 254 | encoderOption->xinConfig.enableAlf = TRUE; 255 | encoderOption->xinConfig.enableSbTmvp = TRUE; 256 | encoderOption->xinConfig.enableAffine = TRUE; 257 | encoderOption->xinConfig.enableMts = TRUE; 258 | encoderOption->xinConfig.enableDepQuant = TRUE; 259 | encoderOption->xinConfig.enableAmvr = TRUE; 260 | encoderOption->xinConfig.enableBcw = TRUE; 261 | 262 | // HEVC 263 | encoderOption->xinConfig.enableSmp = 1; 264 | 265 | break; 266 | 267 | default: 268 | encoderOption->xinConfig.refFrameNum = 4; 269 | encoderOption->xinConfig.enableRdoq = 1; 270 | encoderOption->xinConfig.motionSearchMode = 2; 271 | encoderOption->xinConfig.enableMctf = 1; 272 | 273 | // VVC 274 | encoderOption->xinConfig.ctuSize = 128; 275 | encoderOption->xinConfig.maxMttDepth = 1; 276 | encoderOption->xinConfig.maxBtSize = 64; 277 | encoderOption->xinConfig.maxTtSize = 64; 278 | encoderOption->xinConfig.lumaTrSize64 = 1; 279 | encoderOption->xinConfig.enableCclm = 1; 280 | encoderOption->xinConfig.enableDmvr = 1; 281 | encoderOption->xinConfig.enableAlf = TRUE; 282 | encoderOption->xinConfig.enableSbTmvp = TRUE; 283 | encoderOption->xinConfig.enableAffine = TRUE; 284 | encoderOption->xinConfig.enableMts = TRUE; 285 | encoderOption->xinConfig.enableDepQuant = TRUE; 286 | encoderOption->xinConfig.enableAmvr = TRUE; 287 | encoderOption->xinConfig.enableBcw = TRUE; 288 | 289 | // HEVC 290 | encoderOption->xinConfig.enableSmp = 1; 291 | break; 292 | 293 | } 294 | 295 | } 296 | 297 | static void SetScreenContentMode ( 298 | xin26x_params *xinConfig) 299 | { 300 | if (xinConfig->screenContentMode) 301 | { 302 | // h266 & h265 303 | xinConfig->transformSkipFlag = TRUE; 304 | xinConfig->motionSearchMode = 2; 305 | xinConfig->enableMctf = FALSE; 306 | 307 | // h265 308 | xinConfig->enableIntraNxN = TRUE; 309 | xinConfig->enableInterNxN = TRUE; 310 | 311 | // h266 312 | xinConfig->maxTrSkipSize = xinConfig->maxTrSkipSize > 8 ? xinConfig->maxTrSkipSize : 8; 313 | xinConfig->minCuSize = 4; 314 | xinConfig->minQtSize = 4; 315 | xinConfig->enableCclm = TRUE; 316 | } 317 | 318 | } 319 | 320 | static void SetZeroLatencyMode ( 321 | xin26x_params *xinConfig) 322 | { 323 | if (xinConfig->zeroLatency) 324 | { 325 | xinConfig->bFrameNum = 0; 326 | xinConfig->lookAhead = 0; 327 | xinConfig->enableSceneCut = FALSE; 328 | xinConfig->enableMctf = FALSE; 329 | xinConfig->unitTree = FALSE; 330 | xinConfig->rcMode = xinConfig->rcMode > 3 ? 3 : xinConfig->rcMode; 331 | } 332 | 333 | } 334 | 335 | static bool parseConfigFile(encoder_option_struct* encoderOption, const char *configFileName) 336 | { 337 | bool ret = false; 338 | if (encoderOption && configFileName) 339 | { 340 | const config_file_struct* configFile = CreateConfigFile(configFileName); 341 | if (configFile) 342 | { 343 | while (!EndOfFile(configFile)) 344 | { 345 | if (ReadOneLine(configFile)) 346 | { 347 | //add all config options here 348 | if (strcmp(configFile->key, "InputWidth") == 0) 349 | { 350 | encoderOption->xinConfig.inputWidth = atoi(configFile->value); 351 | } 352 | else if (strcmp(configFile->key, "InputHeight") == 0) 353 | { 354 | encoderOption->xinConfig.inputHeight = atoi(configFile->value); 355 | } 356 | else if (strcmp(configFile->key, "MinCbSize") == 0) 357 | { 358 | encoderOption->xinConfig.minCbSize = atoi(configFile->value); 359 | } 360 | else if (strcmp(configFile->key, "MaxCbSize") == 0) 361 | { 362 | encoderOption->xinConfig.maxCbSize = atoi(configFile->value); 363 | } 364 | else if (strcmp(configFile->key, "MinTbSize") == 0) 365 | { 366 | encoderOption->xinConfig.minTbSize = atoi(configFile->value); 367 | } 368 | else if (strcmp(configFile->key, "MaxTbSize") == 0) 369 | { 370 | encoderOption->xinConfig.maxTbSize = atoi(configFile->value); 371 | } 372 | else if (strcmp(configFile->key, "SbSize") == 0) 373 | { 374 | encoderOption->xinConfig.sbSize = atoi(configFile->value); 375 | } 376 | else if (strcmp(configFile->key, "RectPartType") == 0) 377 | { 378 | encoderOption->xinConfig.enableRectPartType = atoi(configFile->value); 379 | } 380 | else if (strcmp(configFile->key, "InputImageFile") == 0) 381 | { 382 | int fileNameLen 383 | = (MAX_FILE_NAME_LEN < ((int)strlen(configFile->value) + 1))? 384 | MAX_FILE_NAME_LEN : ((int)strlen(configFile->value) + 1); 385 | memcpy(encoderOption->inputFileName, configFile->value, 386 | fileNameLen); 387 | } 388 | else if (strcmp(configFile->key, "OutputStreamFile") == 0) 389 | { 390 | int fileNameLen 391 | = (MAX_FILE_NAME_LEN < ((int)strlen(configFile->value) + 1)) ? 392 | MAX_FILE_NAME_LEN : ((int)strlen(configFile->value) + 1); 393 | memcpy(encoderOption->outputFileName, configFile->value, fileNameLen); 394 | } 395 | else if (strcmp(configFile->key, "ReconImageFile") == 0) 396 | { 397 | int fileNameLen 398 | = (MAX_FILE_NAME_LEN < ((int)strlen(configFile->value) + 1)) ? 399 | MAX_FILE_NAME_LEN : ((int)strlen(configFile->value) + 1); 400 | memcpy(encoderOption->reconFileName, configFile->value, fileNameLen); 401 | } 402 | else if (strcmp(configFile->key, "TemporalLayers") == 0) 403 | { 404 | encoderOption->xinConfig.temporalLayerNum = atoi(configFile->value); 405 | } 406 | else if (strcmp(configFile->key, "InitialQP") == 0) 407 | { 408 | encoderOption->xinConfig.qp = atoi(configFile->value); 409 | } 410 | else if (strcmp(configFile->key, "FrameToBeEncoded") == 0) 411 | { 412 | encoderOption->xinConfig.frameToBeEncoded = atoi(configFile->value); 413 | } 414 | else if (strcmp(configFile->key, "IntraNxN") == 0) 415 | { 416 | encoderOption->xinConfig.enableIntraNxN = atoi(configFile->value); 417 | } 418 | else if (strcmp(configFile->key, "InterNxN") == 0) 419 | { 420 | encoderOption->xinConfig.enableInterNxN = atoi(configFile->value); 421 | } 422 | else if (strcmp(configFile->key, "SearchRange") == 0) 423 | { 424 | encoderOption->xinConfig.searchRange = atoi(configFile->value); 425 | } 426 | else if (strcmp(configFile->key, "UseDeltaQp") == 0) 427 | { 428 | encoderOption->xinConfig.enableCuQpDelta = atoi(configFile->value); 429 | } 430 | else if (strcmp(configFile->key, "TransformSkip") == 0) 431 | { 432 | encoderOption->xinConfig.transformSkipFlag = atoi(configFile->value); 433 | } 434 | else if (strcmp(configFile->key, "MaxTrSkipSize") == 0) 435 | { 436 | encoderOption->xinConfig.maxTrSkipSize = atoi(configFile->value); 437 | } 438 | else if (strcmp(configFile->key, "LoopFilter") == 0) 439 | { 440 | encoderOption->xinConfig.enableDeblock = atoi(configFile->value); 441 | } 442 | else if (strcmp(configFile->key, "SAO") == 0) 443 | { 444 | encoderOption->xinConfig.enableSao = atoi(configFile->value); 445 | } 446 | else if (strcmp(configFile->key, "ALF") == 0) 447 | { 448 | encoderOption->xinConfig.enableAlf = atoi(configFile->value); 449 | } 450 | else if (strcmp(configFile->key, "RateControl") == 0) 451 | { 452 | encoderOption->xinConfig.rcMode = atoi(configFile->value); 453 | } 454 | else if (strcmp(configFile->key, "TargetBitrate") == 0) 455 | { 456 | encoderOption->xinConfig.bitRate = atoi(configFile->value); 457 | } 458 | else if (strcmp(configFile->key, "FrameRate") == 0) 459 | { 460 | encoderOption->xinConfig.frameRate = (float)atof(configFile->value); 461 | } 462 | else if (strcmp(configFile->key, "LookAhead") == 0) 463 | { 464 | encoderOption->xinConfig.lookAhead = (UINT32)atof(configFile->value); 465 | } 466 | else if (strcmp(configFile->key, "UnitTree") == 0) 467 | { 468 | encoderOption->xinConfig.unitTree = (UINT32)atof(configFile->value); 469 | } 470 | else if (strcmp(configFile->key, "TreeStrength") == 0) 471 | { 472 | encoderOption->xinConfig.unitTreeStrength = (double)atof(configFile->value); 473 | } 474 | else if (strcmp(configFile->key, "IntraPeriod") == 0) 475 | { 476 | encoderOption->xinConfig.intraPeriod = atoi(configFile->value); 477 | } 478 | else if (strcmp(configFile->key, "ScreenContent") == 0) 479 | { 480 | encoderOption->xinConfig.screenContentMode = atoi(configFile->value); 481 | 482 | SetScreenContentMode ( 483 | &encoderOption->xinConfig); 484 | } 485 | else if (strcmp(configFile->key, "TMVPMode") == 0) 486 | { 487 | encoderOption->xinConfig.enableTMvp = atoi(configFile->value); 488 | } 489 | else if (strcmp(configFile->key, "NumTileColumns") == 0) 490 | { 491 | encoderOption->xinConfig.numTileCols = atoi(configFile->value); 492 | } 493 | else if (strcmp(configFile->key, "NumTileRows") == 0) 494 | { 495 | encoderOption->xinConfig.numTileRows = atoi(configFile->value); 496 | } 497 | else if (strcmp(configFile->key, "WPP") == 0) 498 | { 499 | encoderOption->xinConfig.enableWpp = atoi(configFile->value); 500 | } 501 | else if (strcmp(configFile->key, "EncoderMode") == 0) 502 | { 503 | encoderOption->xinConfig.encoderMode = atoi(configFile->value); 504 | 505 | SetPreset (encoderOption); 506 | } 507 | else if (strcmp(configFile->key, "CtuSize") == 0) 508 | { 509 | encoderOption->xinConfig.ctuSize = atoi(configFile->value); 510 | } 511 | else if (strcmp(configFile->key, "MinQtSize") == 0) 512 | { 513 | encoderOption->xinConfig.minQtSize = atoi(configFile->value); 514 | } 515 | else if (strcmp(configFile->key, "MaxBtSize") == 0) 516 | { 517 | encoderOption->xinConfig.maxBtSize = atoi(configFile->value); 518 | } 519 | else if (strcmp(configFile->key, "MaxTtSize") == 0) 520 | { 521 | encoderOption->xinConfig.maxTtSize = atoi(configFile->value); 522 | } 523 | else if (strcmp(configFile->key, "MaxMttDepth") == 0) 524 | { 525 | encoderOption->xinConfig.maxMttDepth = atoi(configFile->value); 526 | } 527 | else if (strcmp(configFile->key, "MinCuSize") == 0) 528 | { 529 | encoderOption->xinConfig.minCuSize = atoi(configFile->value); 530 | } 531 | else if (strcmp(configFile->key, "TrSize64") == 0) 532 | { 533 | encoderOption->xinConfig.lumaTrSize64 = atoi(configFile->value); 534 | } 535 | else if (strcmp(configFile->key, "Cclm") == 0) 536 | { 537 | encoderOption->xinConfig.enableCclm = atoi(configFile->value); 538 | } 539 | else if (strcmp(configFile->key, "MCTF") == 0) 540 | { 541 | encoderOption->xinConfig.enableMctf = atoi(configFile->value); 542 | } 543 | else if (strcmp(configFile->key, "Dmvr") == 0) 544 | { 545 | encoderOption->xinConfig.enableDmvr = atoi(configFile->value); 546 | } 547 | else if (strcmp(configFile->key, "AlgorithmMode") == 0) 548 | { 549 | encoderOption->xinConfig.algorithmMode = atoi(configFile->value); 550 | } 551 | else if (strcmp(configFile->key, "RefFrames") == 0) 552 | { 553 | encoderOption->xinConfig.refFrameNum = atoi(configFile->value); 554 | } 555 | else if (strcmp(configFile->key, "AdaptiveBFrame") == 0) 556 | { 557 | encoderOption->xinConfig.adaptiveBFrame = atoi(configFile->value); 558 | } 559 | else if (strcmp(configFile->key, "SignBitHidden") == 0) 560 | { 561 | encoderOption->xinConfig.enableSignDataHiding = atoi(configFile->value); 562 | } 563 | else if (strcmp(configFile->key, "RDOQ") == 0) 564 | { 565 | encoderOption->xinConfig.enableRdoq = atoi(configFile->value); 566 | } 567 | else if (strcmp(configFile->key, "BFrames") == 0) 568 | { 569 | encoderOption->xinConfig.bFrameNum = atoi(configFile->value); 570 | } 571 | else if (strcmp(configFile->key, "CalcPsnr") == 0) 572 | { 573 | encoderOption->xinConfig.calcPsnr = atoi(configFile->value); 574 | } 575 | else if (strcmp(configFile->key, "FrameSkip") == 0) 576 | { 577 | encoderOption->xinConfig.frameSkip = atoi(configFile->value); 578 | } 579 | else if (strcmp(configFile->key, "ThreadNum") == 0) 580 | { 581 | encoderOption->xinConfig.threadNum = atoi(configFile->value); 582 | } 583 | else if (strcmp(configFile->key, "FPP") == 0) 584 | { 585 | encoderOption->xinConfig.enableFpp = atoi(configFile->value); 586 | } 587 | else if (strcmp(configFile->key, "RefreshType") == 0) 588 | { 589 | encoderOption->xinConfig.refreshType = atoi(configFile->value); 590 | } 591 | else if (strcmp(configFile->key, "logLevel") == 0) 592 | { 593 | encoderOption->xinConfig.logLevel = atoi(configFile->value); 594 | } 595 | 596 | } 597 | 598 | } 599 | 600 | ret = true; 601 | } 602 | else 603 | { 604 | printf("CreateConfigFile %s failed\n", configFileName); 605 | } 606 | 607 | DeleteConfigFile(configFile); 608 | 609 | } 610 | 611 | return ret; 612 | } 613 | 614 | static bool verifyEncoderOption( 615 | encoder_option_struct *encoderOption, 616 | bool bConsulting) 617 | { 618 | bool ret = true; 619 | 620 | if (strlen(encoderOption->inputFileName) > 0) 621 | { 622 | encoderOption->inputFileHandle = fopen(encoderOption->inputFileName, "rb"); 623 | if (encoderOption->inputFileHandle == 0) 624 | { 625 | printf("Open %s failed\n", encoderOption->inputFileName); 626 | ret = false; 627 | } 628 | } 629 | else 630 | { 631 | if (!bConsulting) 632 | { 633 | printf("No input file\n"); 634 | } 635 | ret = false; 636 | } 637 | 638 | if (strlen(encoderOption->outputFileName) > 0) 639 | { 640 | encoderOption->outputFileHandle = fopen(encoderOption->outputFileName, "wb"); 641 | if (encoderOption->outputFileHandle == 0) 642 | { 643 | printf("Open %s failed\n", encoderOption->outputFileName); 644 | ret = false; 645 | } 646 | } 647 | 648 | if (strlen(encoderOption->reconFileName) > 0) 649 | { 650 | encoderOption->reconFileHandle = fopen(encoderOption->reconFileName, "wb"); 651 | if (encoderOption->reconFileHandle == 0) 652 | { 653 | printf("Open %s failed\n", encoderOption->reconFileName); 654 | ret = false; 655 | } 656 | } 657 | 658 | if (encoderOption->reconFileHandle) 659 | { 660 | encoderOption->xinConfig.needRecon = true; 661 | } 662 | else 663 | { 664 | encoderOption->xinConfig.needRecon = false; 665 | } 666 | 667 | return ret; 668 | 669 | } 670 | 671 | encoder_option_struct* CreateEncoderOption(int argc, char**argv) 672 | { 673 | const char *configFileName; 674 | encoder_option_struct *encoderOption; 675 | bool bConsulting; 676 | 677 | configFileName = NULL; 678 | encoderOption = NULL; 679 | bConsulting = false; 680 | 681 | if (argc <= 1) 682 | { 683 | printf("Argument is invalid. Run xin26x_test --help for a list of options.\n"); 684 | 685 | return NULL; 686 | } 687 | 688 | //get config file 689 | for (optind = 0; ; ) 690 | { 691 | int opt = getopt_long(argc, argv, encoder_short_options, encoder_long_options, (int *)0); 692 | switch (opt) 693 | { 694 | case 'c': 695 | configFileName = optarg; 696 | break; 697 | 698 | default: 699 | break; 700 | } 701 | if (opt == -1) 702 | { 703 | break; 704 | } 705 | } 706 | 707 | encoderOption = (encoder_option_struct*)malloc(sizeof(encoder_option_struct)); 708 | 709 | memset(encoderOption, 0, sizeof(encoder_option_struct)); 710 | 711 | Xin26xSetDefaultParam ( 712 | &encoderOption->xinConfig); 713 | 714 | if (configFileName) 715 | { 716 | //configEncoder with config file 717 | if (!parseConfigFile(encoderOption, configFileName)) 718 | { 719 | printf("Config file is invalid\n"); 720 | 721 | return NULL; 722 | } 723 | } 724 | 725 | // replace config file setting if there is custom setting 726 | for (optind = 0; ; ) 727 | { 728 | int fileNameLen = 0; 729 | int opt = getopt_long(argc, argv, encoder_short_options, encoder_long_options, (int *)0); 730 | 731 | switch (opt) 732 | { 733 | case 'i': 734 | fileNameLen 735 | = (MAX_FILE_NAME_LEN < ((int)strlen(optarg) + 1)) ? 736 | MAX_FILE_NAME_LEN : ((int)strlen(optarg) + 1); 737 | memcpy(encoderOption->inputFileName, optarg, 738 | fileNameLen); 739 | break; 740 | 741 | case 'o': 742 | fileNameLen 743 | = (MAX_FILE_NAME_LEN < ((int)strlen(optarg) + 1)) ? 744 | MAX_FILE_NAME_LEN : ((int)strlen(optarg) + 1); 745 | memcpy(encoderOption->outputFileName, optarg, 746 | fileNameLen); 747 | break; 748 | 749 | case 'a': 750 | encoderOption->xinConfig.algorithmMode = atoi(optarg); 751 | break; 752 | 753 | case 'n': 754 | encoderOption->xinConfig.frameToBeEncoded = atoi(optarg); 755 | break; 756 | 757 | case 'R': 758 | fileNameLen 759 | = (MAX_FILE_NAME_LEN < ((int)strlen(optarg) + 1)) ? 760 | MAX_FILE_NAME_LEN : ((int)strlen(optarg) + 1); 761 | memcpy(encoderOption->reconFileName, optarg, 762 | fileNameLen); 763 | break; 764 | 765 | case 'w': 766 | encoderOption->xinConfig.inputWidth = atoi(optarg); 767 | break; 768 | 769 | case 'h': 770 | encoderOption->xinConfig.inputHeight = atoi(optarg); 771 | break; 772 | 773 | case 'f': 774 | encoderOption->xinConfig.frameRate = (float)atof(optarg); 775 | break; 776 | 777 | case 'b': 778 | encoderOption->xinConfig.bitRate = atoi(optarg); 779 | break; 780 | 781 | case 't': 782 | encoderOption->xinConfig.temporalLayerNum = atoi(optarg); 783 | break; 784 | 785 | case 's': 786 | encoderOption->xinConfig.screenContentMode = atoi(optarg); 787 | 788 | SetScreenContentMode ( 789 | &encoderOption->xinConfig); 790 | 791 | break; 792 | 793 | case 'r': 794 | encoderOption->xinConfig.rcMode = atoi(optarg); 795 | break; 796 | 797 | case 'u': 798 | encoderOption->xinConfig.unitTree = atoi(optarg); 799 | break; 800 | 801 | case 'e': 802 | encoderOption->xinConfig.unitTreeStrength = (double)atoi(optarg); 803 | break; 804 | 805 | case 'O': 806 | encoderOption->xinConfig.enableSao = atoi(optarg); 807 | break; 808 | 809 | case 'l': 810 | encoderOption->xinConfig.enableAlf = atoi(optarg); 811 | break; 812 | 813 | case 'D': 814 | encoderOption->xinConfig.enableDeblock = atoi(optarg); 815 | break; 816 | 817 | case 'P': 818 | encoderOption->xinConfig.calcPsnr = atoi(optarg); 819 | break; 820 | 821 | case 'B': 822 | encoderOption->xinConfig.bFrameNum = atoi(optarg); 823 | break; 824 | 825 | case 'W': 826 | encoderOption->xinConfig.enableWpp = atoi(optarg); 827 | break; 828 | 829 | case 'F': 830 | encoderOption->xinConfig.enableFpp = atoi(optarg); 831 | break; 832 | 833 | case 'T': 834 | encoderOption->xinConfig.threadNum = atoi(optarg); 835 | break; 836 | 837 | case 'N': 838 | encoderOption->xinConfig.enableIntraNxN = atoi(optarg); 839 | break; 840 | 841 | case 'X': 842 | encoderOption->xinConfig.enableInterNxN = atoi(optarg); 843 | break; 844 | 845 | case 'p': 846 | encoderOption->xinConfig.encoderMode = atoi(optarg); 847 | 848 | SetPreset (encoderOption); 849 | 850 | break; 851 | 852 | case 'S': 853 | encoderOption->xinConfig.enableSignDataHiding = atoi(optarg); 854 | break; 855 | 856 | case 'U': 857 | encoderOption->xinConfig.refreshType = atoi(optarg); 858 | break; 859 | 860 | case 'M': 861 | encoderOption->xinConfig.refFrameNum = atoi(optarg); 862 | break; 863 | 864 | case 'g': 865 | encoderOption->xinConfig.adaptiveBFrame = atoi(optarg); 866 | break; 867 | 868 | case 'A': 869 | encoderOption->xinConfig.transformSkipFlag = atoi(optarg); 870 | break; 871 | 872 | case '1': 873 | encoderOption->xinConfig.frameSkip = atoi(optarg); 874 | break; 875 | 876 | case '2': 877 | encoderOption->xinConfig.ctuSize = atoi(optarg); 878 | break; 879 | 880 | case '3': 881 | encoderOption->xinConfig.minQtSize = atoi(optarg); 882 | break; 883 | 884 | case '4': 885 | encoderOption->xinConfig.maxBtSize = atoi(optarg); 886 | break; 887 | 888 | case '5': 889 | encoderOption->xinConfig.maxTtSize = atoi(optarg); 890 | break; 891 | 892 | case '6': 893 | encoderOption->xinConfig.maxMttDepth = atoi(optarg); 894 | break; 895 | 896 | case '7': 897 | encoderOption->xinConfig.minCuSize = atoi(optarg); 898 | break; 899 | 900 | case '8': 901 | encoderOption->xinConfig.lookAhead = atoi(optarg); 902 | break; 903 | 904 | case '9': 905 | encoderOption->xinConfig.lumaTrSize64 = atoi(optarg); 906 | break; 907 | 908 | case 'I': 909 | encoderOption->xinConfig.intraPeriod = atoi(optarg); 910 | break; 911 | 912 | case 'q': 913 | encoderOption->xinConfig.qp = atoi(optarg); 914 | break; 915 | 916 | case 'd': 917 | encoderOption->xinConfig.enableRdoq = atoi(optarg); 918 | break; 919 | 920 | case 'C': 921 | encoderOption->xinConfig.enableCclm = atoi(optarg); 922 | break; 923 | 924 | case 'K': 925 | encoderOption->xinConfig.enableMctf = atoi(optarg); 926 | break; 927 | 928 | case 'y': 929 | encoderOption->xinConfig.enableDmvr = atoi(optarg); 930 | break; 931 | 932 | case 'G': 933 | encoderOption->xinConfig.maxTrSkipSize = atoi(optarg); 934 | break; 935 | 936 | case 'Q': 937 | encoderOption->xinConfig.enableRectPartType = atoi(optarg); 938 | break; 939 | 940 | case 'z': 941 | encoderOption->xinConfig.sbSize = atoi(optarg); 942 | break; 943 | 944 | case 'E': 945 | encoderOption->xinConfig.logLevel = atoi(optarg); 946 | break; 947 | 948 | case 128: 949 | encoderOption->xinConfig.enableSbTmvp = atoi(optarg); 950 | break; 951 | 952 | case 129: 953 | encoderOption->xinConfig.enableAffine = atoi(optarg); 954 | break; 955 | 956 | case 130: 957 | encoderOption->xinConfig.enableMts = atoi(optarg); 958 | break; 959 | 960 | case 131: 961 | encoderOption->xinConfig.enableGpb = atoi(optarg); 962 | break; 963 | 964 | case 132: 965 | encoderOption->xinConfig.enableDepQuant = atoi(optarg); 966 | break; 967 | 968 | case 133: 969 | encoderOption->xinConfig.enableSceneCut = atoi(optarg); 970 | break; 971 | 972 | case 134: 973 | encoderOption->xinConfig.zeroLatency = atoi(optarg); 974 | 975 | SetZeroLatencyMode ( 976 | &encoderOption->xinConfig); 977 | 978 | break; 979 | 980 | case 135: 981 | encoderOption->xinConfig.enableAmvr = atoi(optarg); 982 | break; 983 | 984 | case 136: 985 | encoderOption->xinConfig.vbvBufSize = atoi(optarg); 986 | break; 987 | 988 | case 137: 989 | encoderOption->xinConfig.vbvMaxRate = atoi(optarg); 990 | break; 991 | 992 | case 138: 993 | encoderOption->xinConfig.crf = atoi(optarg); 994 | break; 995 | 996 | case 139: 997 | encoderOption->xinConfig.minQp = atoi(optarg); 998 | break; 999 | 1000 | case 140: 1001 | encoderOption->xinConfig.maxQp = atoi(optarg); 1002 | break; 1003 | 1004 | case 141: 1005 | encoderOption->xinConfig.enableBcw = atoi(optarg); 1006 | break; 1007 | 1008 | case 255: 1009 | encoderOption->xinConfig.hiddenOption = atoi(optarg); 1010 | break; 1011 | 1012 | case 'H': 1013 | ShowHelp(); 1014 | bConsulting = true; 1015 | break; 1016 | 1017 | case 'V': 1018 | ShowVersion(); 1019 | bConsulting = true; 1020 | break; 1021 | 1022 | default: 1023 | break; 1024 | 1025 | } 1026 | 1027 | if (opt == -1) 1028 | { 1029 | break; 1030 | } 1031 | 1032 | } 1033 | 1034 | if (verifyEncoderOption(encoderOption, bConsulting) == false) 1035 | { 1036 | if (!bConsulting) 1037 | { 1038 | printf("Option is wrong!\n"); 1039 | 1040 | ShowHelp(); 1041 | } 1042 | 1043 | free (encoderOption); 1044 | 1045 | encoderOption = NULL; 1046 | 1047 | } 1048 | 1049 | return encoderOption; 1050 | 1051 | } 1052 | 1053 | void DeleteEncoderOption(encoder_option_struct* encoderOption) 1054 | { 1055 | if (encoderOption->inputFileHandle) 1056 | { 1057 | fclose(encoderOption->inputFileHandle); 1058 | encoderOption->inputFileHandle = 0; 1059 | } 1060 | 1061 | if (encoderOption->outputFileHandle) 1062 | { 1063 | fclose(encoderOption->outputFileHandle); 1064 | encoderOption->outputFileHandle = 0; 1065 | } 1066 | 1067 | if (encoderOption->reconFileHandle) 1068 | { 1069 | fclose(encoderOption->reconFileHandle); 1070 | encoderOption->reconFileHandle = 0; 1071 | } 1072 | 1073 | } 1074 | 1075 | void PrintEncoderOption(encoder_option_struct *encoderOption) 1076 | { 1077 | (void)encoderOption; 1078 | } 1079 | 1080 | void ShowHelp() 1081 | { 1082 | printf ("\nSyntax: xin26x_test [options]\n"); 1083 | 1084 | printf ("\nEncoder config file option: if there is no config file, app will use custom options\n"); 1085 | printf ("-c/--config Config file\n"); 1086 | printf ("\nEncoder custom options: if there are some custom options, it will replace the value in config file\n"); 1087 | 1088 | printf ("Input and Ouput Options:\n"); 1089 | printf ("-i/--input Input YUV420 file\n"); 1090 | printf ("-o/--output Output raw bitstream file\n"); 1091 | printf ("-n/--framenumber Frames to be encoded\n"); 1092 | printf ("-w/--width Width of input YUV420 file\n"); 1093 | printf ("-h/--height Height of input YUV420 file\n"); 1094 | printf ("\n"); 1095 | 1096 | printf ("Algorithm Mode:\n"); 1097 | printf ("-a/--algmode Which algorithm mode is used. 0: H.265, 1: AV1 2: H.266.\n"); 1098 | printf ("\n"); 1099 | 1100 | printf ("H.265 Coding Tools:\n"); 1101 | printf ("--intranxn Enable intra 4x4, 0: disable, 1: enable\n"); 1102 | printf ("--internxn Enable inter 4x4, 0: disable, 1: enable\n"); 1103 | printf ("\n"); 1104 | 1105 | printf ("AV1 Coding Toools:\n"); 1106 | printf ("--sbsize Super Block size 64 or 128.\n"); 1107 | printf ("--rectparttype Enable rectangle partition type.\n"); 1108 | printf ("\n"); 1109 | 1110 | printf ("H266 Coding Tools:\n"); 1111 | printf ("--minQtSize Minimum allowed quaternary tree leaf node size.\n"); 1112 | printf ("--maxBtSize Maximum allowed binary tree root node size.\n"); 1113 | printf ("--maxTtSize Maximum allowed ternary tree root node size.\n"); 1114 | printf ("--maxMttDepth Maximum allowed hierarchy depth of multi-type tree splitting from a quadtree leaf.\n"); 1115 | printf ("--minCuSize Minimum coding unit size.\n"); 1116 | printf ("--trSize64 Enable max transform size 64 for luma, 0: disable, 1: enable.\n"); 1117 | printf ("--maxTrSkipSize Max transform skip size.\n"); 1118 | printf ("--sbTmvp Enbale SbTMVP.\n"); 1119 | printf ("\n"); 1120 | 1121 | printf ("H265 and H266 Coding Tools:\n"); 1122 | printf ("--sbh Enable sign bit hidden, 0: disable, 1: enable\n"); 1123 | printf ("--transformSkip Enable transform skip. 0: disable, 1: enable\n"); 1124 | printf ("--sao Enable sample adaptive offset. 0: disable, 1: enable\n"); 1125 | printf ("\n"); 1126 | 1127 | printf ("General Coding Tools:\n"); 1128 | printf ("-p/--preset Encoder preset. 0: superfast, 1: veryfast, 2: fast, 3: medium, 4 slow, 5 veryslow.\n"); 1129 | printf ("-s/--screencontent Enable screen content, 0: disable, 1: enable\n"); 1130 | printf ("--lookAhead How many frames are lookahead.\n"); 1131 | printf ("-d/--rdoq Enable rate distortion optimization. 0: disable, 1: Enable.\n"); 1132 | printf ("-L/--lathread How many thread used for lookahead.\n"); 1133 | printf ("-u/--unitTree Enable unit tree, 0: disable, 1: enable.\n"); 1134 | printf ("-e/--treeStrength Unit tree strength.\n"); 1135 | printf ("\n"); 1136 | 1137 | printf ("Coding Structure:\n"); 1138 | printf ("-t/--temporallayer Temporal layer\n"); 1139 | printf ("-I/--intraperiod Intra Period Length\n"); 1140 | printf ("--refreshtype Refresh Type, Only works under b frame cases. 0:CRA, 1:IDR\n"); 1141 | printf ("--refframes Reference frame number, Only works under none b frame cases.\n"); 1142 | printf ("-B/--bframes B frame number in a prediciton gop.\n"); 1143 | printf ("--adabframe Enable adapitve B frame number in a gop. 0: disable, 1: enable.\n"); 1144 | printf ("\n"); 1145 | 1146 | printf ("Multiple Thread:\n"); 1147 | printf ("-W/--wpp Enable WaveFront Parallel Processing. 0: disable, 1: Enable.\n"); 1148 | printf ("-F/--fpp Enable Frame Parallel Processing. 0: disable, 1: Enable.\n"); 1149 | printf ("-T/--thread Specify thread number in thread pool. It is decided by local system if thread number is 0.\n"); 1150 | printf ("\n"); 1151 | 1152 | printf ("Rate Control:\n"); 1153 | printf ("-r/--ratecontrol Enable rate control, 0: disable, 1: cbr people 2: cbr content 3: vbr.\n"); 1154 | printf ("-q/--qp Encode QP, work when rate control is disabled\n"); 1155 | printf ("-f/--framerate Encode frame rate\n"); 1156 | printf ("-b/--bitrate Encode bit rate\n"); 1157 | printf ("--frameSkip Enable frame skip when bit rate is insufficient. 0: disable, 1: enable\n"); 1158 | printf ("\n"); 1159 | 1160 | printf ("Other Options:\n"); 1161 | printf ("-H/--help Show this help text\n"); 1162 | printf ("-V/--version Show version info\n"); 1163 | printf ("-E/--statlevel Statistics level. 0: no stat, 1: stat in sequence level, 2: stat in picture level.\n"); 1164 | 1165 | } 1166 | 1167 | void ShowVersion() 1168 | { 1169 | printf ("xin26x v1.0\n"); 1170 | } 1171 | 1172 | -------------------------------------------------------------------------------- /app/encoder/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories ( 2 | if(WIN32) 3 | "${PROJECT_SOURCE_DIR}/third_party/getopt" 4 | endif() 5 | "${PROJECT_SOURCE_DIR}/video_api/video_common/include" 6 | "${PROJECT_SOURCE_DIR}/video_api/video_encoder/include" 7 | "${PROJECT_SOURCE_DIR}/app/common/include" 8 | "${PROJECT_SOURCE_DIR}/app/encoder/include") 9 | 10 | link_directories( 11 | "${PROJECT_SOURCE_DIR}/lib") 12 | 13 | 14 | FILE(GLOB cmake_includes *.h) 15 | FILE(GLOB cmake_sources source/*.c) 16 | 17 | FILE(GLOB cmake_common_sources ${PROJECT_SOURCE_DIR}/app/common/source/*.c) 18 | SET(cmake_sources ${cmake_sources} ${cmake_common_sources}) 19 | 20 | if(WIN32) 21 | 22 | FILE(GLOB cmake_3party_sources ${PROJECT_SOURCE_DIR}/third_party/getopt/*.c) 23 | SET(cmake_sources ${cmake_sources} ${cmake_3party_sources}) 24 | 25 | set_source_files_properties(${PROJECT_SOURCE_DIR}/third_party/getopt/getopt.c PROPERTIES COMPILE_FLAGS "-DHAVE_STRING_H=1") 26 | 27 | if(MSVC) 28 | set_source_files_properties(${PROJECT_SOURCE_DIR}/third_party/getopt/getopt.c PROPERTIES COMPILE_FLAGS "/wd4100 /wd4131 -DHAVE_STRING_H=1") 29 | endif(MSVC) 30 | 31 | endif() 32 | 33 | if(XCODE) 34 | 35 | add_executable(xin26x_test ${cmake_sources} ${cmake_target_obj}) 36 | 37 | else(XCODE) 38 | 39 | add_executable(xin26x_test ${cmake_sources}) 40 | target_link_libraries(xin26x_test ${XIN26X_LIB}) 41 | 42 | endif() 43 | 44 | if (UNIX AND (NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")) 45 | target_link_libraries(xin26x_test dl m) 46 | endif() -------------------------------------------------------------------------------- /app/encoder/source/xin_app_enc.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************//** 2 | * 3 | * @file xin_app_enc.c 4 | * @authors shennung 5 | * @brief xin26x encoder test client. 6 | * @copyright (c) 2020, shennung All rights reserved 7 | * 8 | *******************************************************************************/ 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "xin_typedef.h" 16 | #include "xin26x_params.h" 17 | #include "xin_encoder_option.h" 18 | #include "xin26x_encoder_api.h" 19 | #if _WIN32 20 | #include 21 | #include 22 | #include 23 | #include 24 | #else 25 | #include 26 | #endif 27 | 28 | #if defined(_MSC_VER) 29 | #define fseeko _fseeki64 30 | #define ftello _ftelli64 31 | #endif 32 | 33 | static void WriteFrame ( 34 | FILE *reconFile, 35 | xin_frame_desc *reconFrame) 36 | { 37 | UINT32 rowIdx; 38 | PIXEL *yBuf; 39 | PIXEL *uBuf; 40 | PIXEL *vBuf; 41 | 42 | yBuf = reconFrame->yuvBuf[0]; 43 | uBuf = reconFrame->yuvBuf[1]; 44 | vBuf = reconFrame->yuvBuf[2]; 45 | 46 | for (rowIdx = 0; rowIdx < reconFrame->lumaHeight; rowIdx++) 47 | { 48 | fwrite ( 49 | yBuf, 50 | sizeof(PIXEL), 51 | reconFrame->lumaWidth, 52 | reconFile); 53 | 54 | yBuf += reconFrame->lumaStride; 55 | } 56 | 57 | for (rowIdx = 0; rowIdx < reconFrame->lumaHeight/2; rowIdx++) 58 | { 59 | fwrite ( 60 | uBuf, 61 | sizeof(PIXEL), 62 | reconFrame->lumaWidth/2, 63 | reconFile); 64 | 65 | uBuf += reconFrame->chromaStride; 66 | } 67 | 68 | for (rowIdx = 0; rowIdx < reconFrame->lumaHeight/2; rowIdx++) 69 | { 70 | fwrite ( 71 | vBuf, 72 | sizeof(PIXEL), 73 | reconFrame->lumaWidth/2, 74 | reconFile); 75 | 76 | vBuf += reconFrame->chromaStride; 77 | } 78 | 79 | } 80 | 81 | static int ReadFrame ( 82 | FILE *inputFile, 83 | xin_frame_desc *inputFrame) 84 | { 85 | size_t readCount; 86 | 87 | readCount = fread ( 88 | inputFrame->yuvBuf[0], 89 | 1, 90 | inputFrame->lumaHeight*inputFrame->lumaWidth, 91 | inputFile); 92 | 93 | if (readCount != inputFrame->lumaHeight*inputFrame->lumaWidth) 94 | { 95 | return XIN_FAIL; 96 | } 97 | 98 | readCount = fread ( 99 | inputFrame->yuvBuf[1], 100 | 1, 101 | inputFrame->lumaHeight*inputFrame->lumaWidth/4, 102 | inputFile); 103 | 104 | if (readCount != inputFrame->lumaHeight*inputFrame->lumaWidth/4) 105 | { 106 | return XIN_FAIL; 107 | } 108 | 109 | readCount = fread ( 110 | inputFrame->yuvBuf[2], 111 | 1, 112 | inputFrame->lumaHeight*inputFrame->lumaWidth/4, 113 | inputFile); 114 | 115 | if (readCount != inputFrame->lumaHeight*inputFrame->lumaWidth/4) 116 | { 117 | return XIN_FAIL; 118 | } 119 | 120 | return XIN_SUCCESS; 121 | 122 | } 123 | 124 | static void GetFrameCount ( 125 | FILE *inputFile, 126 | UINT32 width, 127 | UINT32 height, 128 | UINT32 *frameCount) 129 | { 130 | UINT64 fileSize; 131 | UINT32 frameSize; 132 | 133 | frameSize = 3*width*height/2; 134 | 135 | fseeko ( 136 | inputFile, 137 | 0, 138 | SEEK_END); 139 | 140 | fileSize = ftello (inputFile); 141 | 142 | fseeko ( 143 | inputFile, 144 | 0, 145 | SEEK_SET); 146 | 147 | *frameCount = (UINT32)(fileSize/frameSize); 148 | 149 | } 150 | 151 | int64_t Xin26xGetTime ( ) 152 | { 153 | #if _WIN32 154 | struct timeb time; 155 | ftime(&time); 156 | return ((int64_t)time.time * 1000 + (int64_t)time.millitm) * 1000; 157 | #else 158 | struct timeval time; 159 | gettimeofday(&time, NULL); 160 | return (int64_t)time.tv_sec * 1000000 + (int64_t)time.tv_usec; 161 | #endif 162 | } 163 | 164 | int main(int argc, char **argv) 165 | { 166 | encoder_option_struct *encoderOption; 167 | XIN_HANDLE encoderHandle; 168 | XIN_HANDLE fileReadHandle; 169 | UINT32 inputFrameIdx; 170 | UINT32 trailingFrame; 171 | UINT32 encodedFrame; 172 | xin26x_params *config; 173 | xin_frame_desc inputFrame; 174 | xin_frame_desc reconFrame[4]; 175 | UINT32 reconFrameNum; 176 | UINT32 reconFrameIdx; 177 | xin_out_buf_desc outputBuffer; 178 | SINT64 startTime; 179 | SINT64 endTime; 180 | double encoderTime; 181 | UINT64 totalBitSize; 182 | UINT32 frameToBeEncoded; 183 | SINT32 passIdx; 184 | 185 | totalBitSize = 0; 186 | encoderOption = CreateEncoderOption(argc, argv); 187 | 188 | if (encoderOption) 189 | { 190 | PrintEncoderOption (encoderOption); 191 | 192 | config = &encoderOption->xinConfig; 193 | 194 | GetFrameCount ( 195 | encoderOption->inputFileHandle, 196 | config->inputWidth, 197 | config->inputHeight, 198 | &frameToBeEncoded); 199 | 200 | if ((frameToBeEncoded < config->frameToBeEncoded) || (config->frameToBeEncoded == 0)) 201 | { 202 | config->frameToBeEncoded = frameToBeEncoded; 203 | } 204 | 205 | if (Xin26xEncoderCreate (&encoderHandle, config)) 206 | { 207 | printf("Fail to create encoder\n"); 208 | 209 | return -1; 210 | } 211 | 212 | if (Xin26xReadFrameCreate (&fileReadHandle, ReadFrame, config, encoderOption->inputFileHandle)) 213 | { 214 | printf("Fail to create file reader\n"); 215 | 216 | return -1; 217 | } 218 | 219 | printf("Start coding...\n"); 220 | 221 | encodedFrame = 0; 222 | trailingFrame = 0; 223 | startTime = Xin26xGetTime (); 224 | 225 | for (passIdx = 0; passIdx <= config->twoPassEncoder; passIdx++) 226 | { 227 | for (inputFrameIdx = 0; inputFrameIdx < config->frameToBeEncoded; inputFrameIdx++) 228 | { 229 | if (passIdx == 0) 230 | { 231 | Xin26xReadFrame ( 232 | fileReadHandle, 233 | &inputFrame); 234 | } 235 | 236 | Xin26xEncodeFrame ( 237 | encoderHandle, 238 | (passIdx == 0) ? &inputFrame : NULL, 239 | &outputBuffer); 240 | 241 | totalBitSize += outputBuffer.bytesGenerate*8; 242 | 243 | if ((encoderOption->reconFileHandle) && (outputBuffer.bytesGenerate > 0) && (passIdx == config->twoPassEncoder)) 244 | { 245 | Xin26xGetReconFrame ( 246 | encoderHandle, 247 | reconFrame, 248 | &reconFrameNum); 249 | 250 | for (reconFrameIdx = 0; reconFrameIdx < reconFrameNum; reconFrameIdx++) 251 | { 252 | WriteFrame ( 253 | encoderOption->reconFileHandle, 254 | reconFrame + reconFrameIdx); 255 | } 256 | } 257 | 258 | if ((outputBuffer.bytesGenerate > 0) && (passIdx == config->twoPassEncoder)) 259 | { 260 | encodedFrame++; 261 | 262 | if (config->logLevel >= XIN26X_LOG_PIC) 263 | { 264 | printf ("frame %d, encoded %d bytes.\n", encodedFrame, outputBuffer.bytesGenerate); 265 | } 266 | else if (config->logLevel == XIN26X_LOG_SEQ) 267 | { 268 | printf ("%d/%d frames are encoded.\r", encodedFrame, config->frameToBeEncoded); 269 | } 270 | 271 | fwrite ( 272 | outputBuffer.bitsBuf, 273 | 1, 274 | outputBuffer.bytesGenerate, 275 | encoderOption->outputFileHandle); 276 | } 277 | 278 | } 279 | 280 | // Last pass 281 | if (config->twoPassEncoder == passIdx) 282 | { 283 | // Flush traling frames 284 | do 285 | { 286 | Xin26xEncodeFrame ( 287 | encoderHandle, 288 | NULL, 289 | &outputBuffer); 290 | 291 | totalBitSize += (outputBuffer.bytesGenerate > 0) ? outputBuffer.bytesGenerate*8 : 0; 292 | 293 | if ((encoderOption->reconFileHandle) && (outputBuffer.bytesGenerate > 0) && (passIdx == config->twoPassEncoder)) 294 | { 295 | Xin26xGetReconFrame ( 296 | encoderHandle, 297 | reconFrame, 298 | &reconFrameNum); 299 | 300 | for (reconFrameIdx = 0; reconFrameIdx < reconFrameNum; reconFrameIdx++) 301 | { 302 | WriteFrame ( 303 | encoderOption->reconFileHandle, 304 | reconFrame + reconFrameIdx); 305 | } 306 | 307 | } 308 | 309 | if ((outputBuffer.bytesGenerate > 0) && (passIdx == config->twoPassEncoder)) 310 | { 311 | encodedFrame++; 312 | 313 | if (config->logLevel >= XIN26X_LOG_PIC) 314 | { 315 | printf ("frame %d, encoded %d bytes.\n", encodedFrame, outputBuffer.bytesGenerate); 316 | } 317 | else if (config->logLevel == XIN26X_LOG_SEQ) 318 | { 319 | printf ("%d/%d frames are encoded.\r", encodedFrame, config->frameToBeEncoded); 320 | } 321 | 322 | fwrite ( 323 | outputBuffer.bitsBuf, 324 | 1, 325 | outputBuffer.bytesGenerate, 326 | encoderOption->outputFileHandle); 327 | } 328 | 329 | trailingFrame++; 330 | 331 | } 332 | while (outputBuffer.bytesGenerate >= 0); 333 | 334 | } 335 | 336 | } 337 | 338 | endTime = Xin26xGetTime (); 339 | encoderTime = (double)(endTime - startTime) / 1000000; 340 | 341 | if (config->logLevel >= XIN26X_LOG_SEQ) 342 | { 343 | printf ("%d frames encoded, coding speed fps:%3.4f bitrate: %4.2f kbps.\n", config->frameToBeEncoded, (double)(config->frameToBeEncoded) / encoderTime, ((double)totalBitSize)/((double)config->frameToBeEncoded/(double)config->frameRate)/1000.0); 344 | } 345 | 346 | fflush (encoderOption->outputFileHandle); 347 | 348 | printf("Complete coding.\n"); 349 | 350 | Xin26xReadFrameDelete ( 351 | fileReadHandle); 352 | 353 | Xin26xEncoderDelete ( 354 | encoderHandle); 355 | 356 | DeleteEncoderOption ( 357 | encoderOption); 358 | 359 | free (encoderOption); 360 | 361 | } 362 | 363 | return 0; 364 | 365 | } 366 | 367 | -------------------------------------------------------------------------------- /build/make-solutions.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: 3 | :: run this batch file to create a Visual Studio solution file for this project. 4 | :: See the cmake documentation for other generator targets 5 | :: 6 | cmake -G "Visual Studio 12 Win64" ..\ 7 | -------------------------------------------------------------------------------- /lib/xin26x.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pigpeppa/xin26x/d5244662ed2035eae70714e96b39c7f440e3cc0d/lib/xin26x.exp -------------------------------------------------------------------------------- /lib/xin26x.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pigpeppa/xin26x/d5244662ed2035eae70714e96b39c7f440e3cc0d/lib/xin26x.lib -------------------------------------------------------------------------------- /testbin/VvcDecoderApp.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pigpeppa/xin26x/d5244662ed2035eae70714e96b39c7f440e3cc0d/testbin/VvcDecoderApp.exe -------------------------------------------------------------------------------- /testbin/xin26x.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pigpeppa/xin26x/d5244662ed2035eae70714e96b39c7f440e3cc0d/testbin/xin26x.dll -------------------------------------------------------------------------------- /testbin/xin26x_test.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pigpeppa/xin26x/d5244662ed2035eae70714e96b39c7f440e3cc0d/testbin/xin26x_test.exe -------------------------------------------------------------------------------- /third_party/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Add include directories here 3 | # 4 | 5 | FILE(GLOB cmake_includes getopt/*.h) 6 | FILE(GLOB cmake_sources getopt/*.c) 7 | 8 | set_source_files_properties(getopt/getopt.c PROPERTIES COMPILE_FLAGS "-DHAVE_STRING_H=1") 9 | if(MSVC) 10 | set_source_files_properties(getopt/getopt.c PROPERTIES COMPILE_FLAGS "/wd4100 /wd4131 -DHAVE_STRING_H=1") 11 | endif(MSVC) 12 | 13 | add_library(${THIRD_PARTY_LIB} ${cmake_sources} ${cmake_includes}) 14 | 15 | -------------------------------------------------------------------------------- /third_party/getopt/LICENSE: -------------------------------------------------------------------------------- 1 | #### AUTHORS: 2 | 3 | * Todd C. Miller 4 | * The NetBSD Foundation, Inc. 5 | * Alexei Kasatkin is the author of trivial CMakeLists.txt, build script itself is Public Domain 6 | 7 | #### LICENSE 8 | 9 | Copyright (c) 2002 Todd C. Miller 10 | 11 | Permission to use, copy, modify, and distribute this software for any 12 | purpose with or without fee is hereby granted, provided that the above 13 | copyright notice and this permission notice appear in all copies. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 16 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 18 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 21 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 | 23 | Sponsored in part by the Defense Advanced Research Projects 24 | Agency (DARPA) and Air Force Research Laboratory, Air Force 25 | Materiel Command, USAF, under agreement number F39502-99-1-0512. 26 | 27 | *** 28 | 29 | Copyright (c) 2000 The NetBSD Foundation, Inc. 30 | All rights reserved. 31 | 32 | This code is derived from software contributed to The NetBSD Foundation 33 | by Dieter Baron and Thomas Klausner. 34 | 35 | Redistribution and use in source and binary forms, with or without 36 | modification, are permitted provided that the following conditions 37 | are met: 38 | 1. Redistributions of source code must retain the above copyright 39 | notice, this list of conditions and the following disclaimer. 40 | 2. Redistributions in binary form must reproduce the above copyright 41 | notice, this list of conditions and the following disclaimer in the 42 | documentation and/or other materials provided with the distribution. 43 | 44 | THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 45 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 46 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 47 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 48 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 49 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 50 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 51 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 52 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 53 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 54 | POSSIBILITY OF SUCH DAMAGE. 55 | -------------------------------------------------------------------------------- /third_party/getopt/getopt.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl Exp $ */ 2 | /* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ 3 | 4 | /* 5 | * Copyright (c) 2002 Todd C. Miller 6 | * 7 | * Permission to use, copy, modify, and distribute this software for any 8 | * purpose with or without fee is hereby granted, provided that the above 9 | * copyright notice and this permission notice appear in all copies. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 | * 19 | * Sponsored in part by the Defense Advanced Research Projects 20 | * Agency (DARPA) and Air Force Research Laboratory, Air Force 21 | * Materiel Command, USAF, under agreement number F39502-99-1-0512. 22 | */ 23 | /*- 24 | * Copyright (c) 2000 The NetBSD Foundation, Inc. 25 | * All rights reserved. 26 | * 27 | * This code is derived from software contributed to The NetBSD Foundation 28 | * by Dieter Baron and Thomas Klausner. 29 | * 30 | * Redistribution and use in source and binary forms, with or without 31 | * modification, are permitted provided that the following conditions 32 | * are met: 33 | * 1. Redistributions of source code must retain the above copyright 34 | * notice, this list of conditions and the following disclaimer. 35 | * 2. Redistributions in binary form must reproduce the above copyright 36 | * notice, this list of conditions and the following disclaimer in the 37 | * documentation and/or other materials provided with the distribution. 38 | * 39 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 40 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 41 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 43 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 44 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 45 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 46 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 47 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 49 | * POSSIBILITY OF SUCH DAMAGE. 50 | */ 51 | 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | 60 | #define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ 61 | 62 | #ifdef REPLACE_GETOPT 63 | int opterr = 1; /* if error message should be printed */ 64 | int optind = 1; /* index into parent argv vector */ 65 | int optopt = '?'; /* character checked for validity */ 66 | #undef optreset /* see getopt.h */ 67 | #define optreset __mingw_optreset 68 | int optreset; /* reset getopt */ 69 | char *optarg; /* argument associated with option */ 70 | #endif 71 | 72 | #define PRINT_ERROR ((opterr) && (*options != ':')) 73 | 74 | #define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ 75 | #define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ 76 | #define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ 77 | 78 | /* return values */ 79 | #define BADCH (int)'?' 80 | #define BADARG ((*options == ':') ? (int)':' : (int)'?') 81 | #define INORDER (int)1 82 | 83 | #ifndef __CYGWIN__ 84 | #define __progname __argv[0] 85 | #else 86 | extern char __declspec(dllimport) *__progname; 87 | #endif 88 | 89 | #ifdef __CYGWIN__ 90 | static char EMSG[] = ""; 91 | #else 92 | #define EMSG "" 93 | #endif 94 | 95 | static int getopt_internal(int, char * const *, const char *, 96 | const struct option *, int *, int); 97 | static int parse_long_options(char * const *, const char *, 98 | const struct option *, int *, int); 99 | static int gcd(int, int); 100 | static void permute_args(int, int, int, char * const *); 101 | 102 | static char *place = EMSG; /* option letter processing */ 103 | 104 | /* XXX: set optreset to 1 rather than these two */ 105 | static int nonopt_start = -1; /* first non option argument (for permute) */ 106 | static int nonopt_end = -1; /* first option after non options (for permute) */ 107 | 108 | /* Error messages */ 109 | static const char recargchar[] = "option requires an argument -- %c"; 110 | static const char recargstring[] = "option requires an argument -- %s"; 111 | static const char ambig[] = "ambiguous option -- %.*s"; 112 | static const char noarg[] = "option doesn't take an argument -- %.*s"; 113 | static const char illoptchar[] = "unknown option -- %c"; 114 | static const char illoptstring[] = "unknown option -- %s"; 115 | 116 | static void 117 | _vwarnx(const char *fmt,va_list ap) 118 | { 119 | (void)fprintf(stderr,"%s: ",__progname); 120 | if (fmt != NULL) 121 | (void)vfprintf(stderr,fmt,ap); 122 | (void)fprintf(stderr,"\n"); 123 | } 124 | 125 | static void 126 | warnx(const char *fmt,...) 127 | { 128 | va_list ap; 129 | va_start(ap,fmt); 130 | _vwarnx(fmt,ap); 131 | va_end(ap); 132 | } 133 | 134 | /* 135 | * Compute the greatest common divisor of a and b. 136 | */ 137 | static int 138 | gcd(int a, int b) 139 | { 140 | int c; 141 | 142 | c = a % b; 143 | while (c != 0) { 144 | a = b; 145 | b = c; 146 | c = a % b; 147 | } 148 | 149 | return (b); 150 | } 151 | 152 | /* 153 | * Exchange the block from nonopt_start to nonopt_end with the block 154 | * from nonopt_end to opt_end (keeping the same order of arguments 155 | * in each block). 156 | */ 157 | static void 158 | permute_args(int panonopt_start, int panonopt_end, int opt_end, 159 | char * const *nargv) 160 | { 161 | int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; 162 | char *swap; 163 | 164 | /* 165 | * compute lengths of blocks and number and size of cycles 166 | */ 167 | nnonopts = panonopt_end - panonopt_start; 168 | nopts = opt_end - panonopt_end; 169 | ncycle = gcd(nnonopts, nopts); 170 | cyclelen = (opt_end - panonopt_start) / ncycle; 171 | 172 | for (i = 0; i < ncycle; i++) { 173 | cstart = panonopt_end+i; 174 | pos = cstart; 175 | for (j = 0; j < cyclelen; j++) { 176 | if (pos >= panonopt_end) 177 | pos -= nnonopts; 178 | else 179 | pos += nopts; 180 | swap = nargv[pos]; 181 | /* LINTED const cast */ 182 | ((char **) nargv)[pos] = nargv[cstart]; 183 | /* LINTED const cast */ 184 | ((char **)nargv)[cstart] = swap; 185 | } 186 | } 187 | } 188 | 189 | /* 190 | * parse_long_options -- 191 | * Parse long options in argc/argv argument vector. 192 | * Returns -1 if short_too is set and the option does not match long_options. 193 | */ 194 | static int 195 | parse_long_options(char * const *nargv, const char *options, 196 | const struct option *long_options, int *idx, int short_too) 197 | { 198 | char *current_argv, *has_equal; 199 | size_t current_argv_len; 200 | int i, ambiguous, match; 201 | 202 | #define IDENTICAL_INTERPRETATION(_x, _y) \ 203 | (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \ 204 | long_options[(_x)].flag == long_options[(_y)].flag && \ 205 | long_options[(_x)].val == long_options[(_y)].val) 206 | 207 | current_argv = place; 208 | match = -1; 209 | ambiguous = 0; 210 | 211 | optind++; 212 | 213 | if ((has_equal = strchr(current_argv, '=')) != NULL) { 214 | /* argument found (--option=arg) */ 215 | current_argv_len = has_equal - current_argv; 216 | has_equal++; 217 | } else 218 | current_argv_len = strlen(current_argv); 219 | 220 | for (i = 0; long_options[i].name; i++) { 221 | /* find matching long option */ 222 | if (strncmp(current_argv, long_options[i].name, 223 | current_argv_len)) 224 | continue; 225 | 226 | if (strlen(long_options[i].name) == current_argv_len) { 227 | /* exact match */ 228 | match = i; 229 | ambiguous = 0; 230 | break; 231 | } 232 | /* 233 | * If this is a known short option, don't allow 234 | * a partial match of a single character. 235 | */ 236 | if (short_too && current_argv_len == 1) 237 | continue; 238 | 239 | if (match == -1) /* partial match */ 240 | match = i; 241 | else if (!IDENTICAL_INTERPRETATION(i, match)) 242 | ambiguous = 1; 243 | } 244 | if (ambiguous) { 245 | /* ambiguous abbreviation */ 246 | if (PRINT_ERROR) 247 | warnx(ambig, (int)current_argv_len, 248 | current_argv); 249 | optopt = 0; 250 | return (BADCH); 251 | } 252 | if (match != -1) { /* option found */ 253 | if (long_options[match].has_arg == no_argument 254 | && has_equal) { 255 | if (PRINT_ERROR) 256 | warnx(noarg, (int)current_argv_len, 257 | current_argv); 258 | /* 259 | * XXX: GNU sets optopt to val regardless of flag 260 | */ 261 | if (long_options[match].flag == NULL) 262 | optopt = long_options[match].val; 263 | else 264 | optopt = 0; 265 | return (BADARG); 266 | } 267 | if (long_options[match].has_arg == required_argument || 268 | long_options[match].has_arg == optional_argument) { 269 | if (has_equal) 270 | optarg = has_equal; 271 | else if (long_options[match].has_arg == 272 | required_argument) { 273 | /* 274 | * optional argument doesn't use next nargv 275 | */ 276 | optarg = nargv[optind++]; 277 | } 278 | } 279 | if ((long_options[match].has_arg == required_argument) 280 | && (optarg == NULL)) { 281 | /* 282 | * Missing argument; leading ':' indicates no error 283 | * should be generated. 284 | */ 285 | if (PRINT_ERROR) 286 | warnx(recargstring, 287 | current_argv); 288 | /* 289 | * XXX: GNU sets optopt to val regardless of flag 290 | */ 291 | if (long_options[match].flag == NULL) 292 | optopt = long_options[match].val; 293 | else 294 | optopt = 0; 295 | --optind; 296 | return (BADARG); 297 | } 298 | } else { /* unknown option */ 299 | if (short_too) { 300 | --optind; 301 | return (-1); 302 | } 303 | if (PRINT_ERROR) 304 | warnx(illoptstring, current_argv); 305 | optopt = 0; 306 | return (BADCH); 307 | } 308 | if (idx) 309 | *idx = match; 310 | if (long_options[match].flag) { 311 | *long_options[match].flag = long_options[match].val; 312 | return (0); 313 | } else 314 | return (long_options[match].val); 315 | #undef IDENTICAL_INTERPRETATION 316 | } 317 | 318 | /* 319 | * getopt_internal -- 320 | * Parse argc/argv argument vector. Called by user level routines. 321 | */ 322 | static int 323 | getopt_internal(int nargc, char * const *nargv, const char *options, 324 | const struct option *long_options, int *idx, int flags) 325 | { 326 | const char *oli; /* option letter list index */ 327 | int optchar, short_too; 328 | static int posixly_correct = -1; 329 | 330 | if (options == NULL) 331 | return (-1); 332 | 333 | /* 334 | * XXX Some GNU programs (like cvs) set optind to 0 instead of 335 | * XXX using optreset. Work around this braindamage. 336 | */ 337 | if (optind == 0) 338 | optind = optreset = 1; 339 | 340 | /* 341 | * Disable GNU extensions if POSIXLY_CORRECT is set or options 342 | * string begins with a '+'. 343 | * 344 | * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or 345 | * optreset != 0 for GNU compatibility. 346 | */ 347 | if (posixly_correct == -1 || optreset != 0) 348 | posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); 349 | if (*options == '-') 350 | flags |= FLAG_ALLARGS; 351 | else if (posixly_correct || *options == '+') 352 | flags &= ~FLAG_PERMUTE; 353 | if (*options == '+' || *options == '-') 354 | options++; 355 | 356 | optarg = NULL; 357 | if (optreset) 358 | nonopt_start = nonopt_end = -1; 359 | start: 360 | if (optreset || !*place) { /* update scanning pointer */ 361 | optreset = 0; 362 | if (optind >= nargc) { /* end of argument vector */ 363 | place = EMSG; 364 | if (nonopt_end != -1) { 365 | /* do permutation, if we have to */ 366 | permute_args(nonopt_start, nonopt_end, 367 | optind, nargv); 368 | optind -= nonopt_end - nonopt_start; 369 | } 370 | else if (nonopt_start != -1) { 371 | /* 372 | * If we skipped non-options, set optind 373 | * to the first of them. 374 | */ 375 | optind = nonopt_start; 376 | } 377 | nonopt_start = nonopt_end = -1; 378 | return (-1); 379 | } 380 | if (*(place = nargv[optind]) != '-' || 381 | (place[1] == '\0' && strchr(options, '-') == NULL)) { 382 | place = EMSG; /* found non-option */ 383 | if (flags & FLAG_ALLARGS) { 384 | /* 385 | * GNU extension: 386 | * return non-option as argument to option 1 387 | */ 388 | optarg = nargv[optind++]; 389 | return (INORDER); 390 | } 391 | if (!(flags & FLAG_PERMUTE)) { 392 | /* 393 | * If no permutation wanted, stop parsing 394 | * at first non-option. 395 | */ 396 | return (-1); 397 | } 398 | /* do permutation */ 399 | if (nonopt_start == -1) 400 | nonopt_start = optind; 401 | else if (nonopt_end != -1) { 402 | permute_args(nonopt_start, nonopt_end, 403 | optind, nargv); 404 | nonopt_start = optind - 405 | (nonopt_end - nonopt_start); 406 | nonopt_end = -1; 407 | } 408 | optind++; 409 | /* process next argument */ 410 | goto start; 411 | } 412 | if (nonopt_start != -1 && nonopt_end == -1) 413 | nonopt_end = optind; 414 | 415 | /* 416 | * If we have "-" do nothing, if "--" we are done. 417 | */ 418 | if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { 419 | optind++; 420 | place = EMSG; 421 | /* 422 | * We found an option (--), so if we skipped 423 | * non-options, we have to permute. 424 | */ 425 | if (nonopt_end != -1) { 426 | permute_args(nonopt_start, nonopt_end, 427 | optind, nargv); 428 | optind -= nonopt_end - nonopt_start; 429 | } 430 | nonopt_start = nonopt_end = -1; 431 | return (-1); 432 | } 433 | } 434 | 435 | /* 436 | * Check long options if: 437 | * 1) we were passed some 438 | * 2) the arg is not just "-" 439 | * 3) either the arg starts with -- we are getopt_long_only() 440 | */ 441 | if (long_options != NULL && place != nargv[optind] && 442 | (*place == '-' || (flags & FLAG_LONGONLY))) { 443 | short_too = 0; 444 | if (*place == '-') 445 | place++; /* --foo long option */ 446 | else if (*place != ':' && strchr(options, *place) != NULL) 447 | short_too = 1; /* could be short option too */ 448 | 449 | optchar = parse_long_options(nargv, options, long_options, 450 | idx, short_too); 451 | if (optchar != -1) { 452 | place = EMSG; 453 | return (optchar); 454 | } 455 | } 456 | 457 | if ((optchar = (int)*place++) == (int)':' || 458 | (optchar == (int)'-' && *place != '\0') || 459 | (oli = strchr(options, optchar)) == NULL) { 460 | /* 461 | * If the user specified "-" and '-' isn't listed in 462 | * options, return -1 (non-option) as per POSIX. 463 | * Otherwise, it is an unknown option character (or ':'). 464 | */ 465 | if (optchar == (int)'-' && *place == '\0') 466 | return (-1); 467 | if (!*place) 468 | ++optind; 469 | if (PRINT_ERROR) 470 | warnx(illoptchar, optchar); 471 | optopt = optchar; 472 | return (BADCH); 473 | } 474 | if (long_options != NULL && optchar == 'W' && oli[1] == ';') { 475 | /* -W long-option */ 476 | if (*place) /* no space */ 477 | /* NOTHING */; 478 | else if (++optind >= nargc) { /* no arg */ 479 | place = EMSG; 480 | if (PRINT_ERROR) 481 | warnx(recargchar, optchar); 482 | optopt = optchar; 483 | return (BADARG); 484 | } else /* white space */ 485 | place = nargv[optind]; 486 | optchar = parse_long_options(nargv, options, long_options, 487 | idx, 0); 488 | place = EMSG; 489 | return (optchar); 490 | } 491 | if (*++oli != ':') { /* doesn't take argument */ 492 | if (!*place) 493 | ++optind; 494 | } else { /* takes (optional) argument */ 495 | optarg = NULL; 496 | if (*place) /* no white space */ 497 | optarg = place; 498 | else if (oli[1] != ':') { /* arg not optional */ 499 | if (++optind >= nargc) { /* no arg */ 500 | place = EMSG; 501 | if (PRINT_ERROR) 502 | warnx(recargchar, optchar); 503 | optopt = optchar; 504 | return (BADARG); 505 | } else 506 | optarg = nargv[optind]; 507 | } 508 | place = EMSG; 509 | ++optind; 510 | } 511 | /* dump back option letter */ 512 | return (optchar); 513 | } 514 | 515 | #ifdef REPLACE_GETOPT 516 | /* 517 | * getopt -- 518 | * Parse argc/argv argument vector. 519 | * 520 | * [eventually this will replace the BSD getopt] 521 | */ 522 | int 523 | getopt(int nargc, char * const *nargv, const char *options) 524 | { 525 | 526 | /* 527 | * We don't pass FLAG_PERMUTE to getopt_internal() since 528 | * the BSD getopt(3) (unlike GNU) has never done this. 529 | * 530 | * Furthermore, since many privileged programs call getopt() 531 | * before dropping privileges it makes sense to keep things 532 | * as simple (and bug-free) as possible. 533 | */ 534 | return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); 535 | } 536 | #endif /* REPLACE_GETOPT */ 537 | 538 | /* 539 | * getopt_long -- 540 | * Parse argc/argv argument vector. 541 | */ 542 | int 543 | getopt_long(int nargc, char * const *nargv, const char *options, 544 | const struct option *long_options, int *idx) 545 | { 546 | 547 | return (getopt_internal(nargc, nargv, options, long_options, idx, 548 | FLAG_PERMUTE)); 549 | } 550 | 551 | /* 552 | * getopt_long_only -- 553 | * Parse argc/argv argument vector. 554 | */ 555 | int 556 | getopt_long_only(int nargc, char * const *nargv, const char *options, 557 | const struct option *long_options, int *idx) 558 | { 559 | 560 | return (getopt_internal(nargc, nargv, options, long_options, idx, 561 | FLAG_PERMUTE|FLAG_LONGONLY)); 562 | } 563 | -------------------------------------------------------------------------------- /third_party/getopt/getopt.h: -------------------------------------------------------------------------------- 1 | #ifndef __GETOPT_H__ 2 | /** 3 | * DISCLAIMER 4 | * This file has no copyright assigned and is placed in the Public Domain. 5 | * This file is a part of the w64 mingw-runtime package. 6 | * 7 | * The w64 mingw-runtime package and its code is distributed in the hope that it 8 | * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR 9 | * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to 10 | * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #define __GETOPT_H__ 14 | 15 | #if defined( WINGETOPT_SHARED_LIB ) 16 | # if defined( BUILDING_WINGETOPT_DLL ) 17 | # define WINGETOPT_API __declspec(dllexport) 18 | # else 19 | # define WINGETOPT_API __declspec(dllimport) 20 | # endif 21 | #else 22 | # define WINGETOPT_API 23 | #endif 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | WINGETOPT_API extern int optind; /* index of first non-option in argv */ 30 | WINGETOPT_API extern int optopt; /* single option character, as parsed */ 31 | WINGETOPT_API extern int opterr; /* flag to enable built-in diagnostics... */ 32 | /* (user may set to zero, to suppress) */ 33 | 34 | WINGETOPT_API extern char *optarg; /* pointer to argument of current option */ 35 | 36 | extern int getopt(int nargc, char * const *nargv, const char *options); 37 | 38 | #ifdef _BSD_SOURCE 39 | /* 40 | * BSD adds the non-standard `optreset' feature, for reinitialisation 41 | * of `getopt' parsing. We support this feature, for applications which 42 | * proclaim their BSD heritage, before including this header; however, 43 | * to maintain portability, developers are advised to avoid it. 44 | */ 45 | # define optreset __mingw_optreset 46 | extern int optreset; 47 | #endif 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | /* 52 | * POSIX requires the `getopt' API to be specified in `unistd.h'; 53 | * thus, `unistd.h' includes this header. However, we do not want 54 | * to expose the `getopt_long' or `getopt_long_only' APIs, when 55 | * included in this manner. Thus, close the standard __GETOPT_H__ 56 | * declarations block, and open an additional __GETOPT_LONG_H__ 57 | * specific block, only when *not* __UNISTD_H_SOURCED__, in which 58 | * to declare the extended API. 59 | */ 60 | #endif /* !defined(__GETOPT_H__) */ 61 | 62 | #if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) 63 | #define __GETOPT_LONG_H__ 64 | 65 | #ifdef __cplusplus 66 | extern "C" { 67 | #endif 68 | 69 | struct option /* specification for a long form option... */ 70 | { 71 | const char *name; /* option name, without leading hyphens */ 72 | int has_arg; /* does it take an argument? */ 73 | int *flag; /* where to save its status, or NULL */ 74 | int val; /* its associated status value */ 75 | }; 76 | 77 | enum /* permitted values for its `has_arg' field... */ 78 | { 79 | no_argument = 0, /* option never takes an argument */ 80 | required_argument, /* option always requires an argument */ 81 | optional_argument /* option may take an argument */ 82 | }; 83 | 84 | extern int getopt_long(int nargc, char * const *nargv, const char *options, 85 | const struct option *long_options, int *idx); 86 | extern int getopt_long_only(int nargc, char * const *nargv, const char *options, 87 | const struct option *long_options, int *idx); 88 | /* 89 | * Previous MinGW implementation had... 90 | */ 91 | #ifndef HAVE_DECL_GETOPT 92 | /* 93 | * ...for the long form API only; keep this for compatibility. 94 | */ 95 | # define HAVE_DECL_GETOPT 1 96 | #endif 97 | 98 | #ifdef __cplusplus 99 | } 100 | #endif 101 | 102 | #endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */ 103 | -------------------------------------------------------------------------------- /video_api/video_common/include/xin_typedef.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************//** 2 | * 3 | * @file xin_typedef.h 4 | * @brief data type definition 5 | * @authors Pig Peppa 6 | * @copyright (c) 2020, Pig Peppa All rights reserved 7 | * 8 | *******************************************************************************/ 9 | #ifndef _xin_typedef_h_ 10 | #define _xin_typedef_h_ 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | #include 17 | 18 | #if defined(_MSC_VER) 19 | #define inline __inline 20 | #elif defined(__linux__) || defined(__APPLE__) 21 | #define inline __inline__ 22 | #endif 23 | 24 | #ifndef NULL 25 | #define NULL ((void*)0) 26 | #endif 27 | 28 | #ifndef FALSE 29 | #define FALSE (1 == 0) 30 | #endif 31 | 32 | #ifndef TRUE 33 | #define TRUE (1 == 1) 34 | #endif 35 | 36 | #define XIN_SUCCESS 0 37 | #define XIN_FAIL -1 38 | 39 | typedef void * XIN_HANDLE; 40 | 41 | #ifdef _MSC_VER 42 | 43 | typedef unsigned __int8 UINT8; 44 | typedef unsigned __int16 UINT16; 45 | typedef unsigned __int32 UINT32; 46 | typedef unsigned __int64 UINT64; 47 | typedef signed __int8 SINT8; 48 | typedef signed __int16 SINT16; 49 | typedef signed __int32 SINT32; 50 | typedef signed __int64 SINT64; 51 | typedef signed __int32 BOOL; 52 | 53 | #else 54 | 55 | typedef uint8_t UINT8; 56 | typedef uint16_t UINT16; 57 | typedef uint32_t UINT32; 58 | typedef uint64_t UINT64; 59 | typedef int8_t SINT8; 60 | typedef int16_t SINT16; 61 | typedef int32_t SINT32; 62 | typedef int64_t SINT64; 63 | typedef int32_t BOOL; 64 | 65 | #endif 66 | 67 | typedef float FLOAT32; 68 | typedef double FLOAT64; 69 | 70 | 71 | // Define pixel and coefficient data type 72 | #ifdef ENABLE_10BIT_ENCODER 73 | #define PIXEL UINT16 74 | #define PIXEL4 UINT64 75 | #define PIXEL2 UINT32 76 | #define COEFF SINT32 77 | #define LEVEL UINT32 78 | #define MIN_PIXEL_VALUE (0) 79 | #define MAX_PIXEL_VALUE (1023) 80 | #define MAX_COEFF_VALUE (32767) 81 | #define MIN_COEFF_VALUE (-32768) 82 | #define XIN_DEFAULT_PIXEL (128*4) 83 | #else 84 | #define PIXEL UINT8 85 | #define PIXEL4 UINT32 86 | #define PIXEL2 UINT16 87 | #define COEFF SINT16 88 | #define LEVEL UINT16 89 | #define MIN_PIXEL_VALUE (0) 90 | #define MAX_PIXEL_VALUE (255) 91 | #define MAX_COEFF_VALUE (32767) 92 | #define MIN_COEFF_VALUE (-32768) 93 | #define XIN_DEFAULT_PIXEL (128) 94 | #endif 95 | 96 | #ifdef __cplusplus 97 | } 98 | #endif 99 | #endif -------------------------------------------------------------------------------- /video_api/video_encoder/include/xin26x_encoder_api.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************//** 2 | * 3 | * @file xin26x_encoder_api.h 4 | * @brief h26x encoder Application Programming Interface. 5 | * @authors Pig Peppa 6 | * @copyright (c) 2020, Pig Peppa All rights reserved 7 | * 8 | *******************************************************************************/ 9 | #ifndef _xin26x_encoder_api_h_ 10 | #define _xin26x_encoder_api_h_ 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | SINT32 Xin26xEncoderCreate ( 17 | XIN_HANDLE *encoderHandle, 18 | xin26x_params *config); 19 | 20 | void Xin26xEncoderDelete ( 21 | XIN_HANDLE encoderHandle); 22 | 23 | void Xin26xEncodeFrame ( 24 | XIN_HANDLE encoderHandle, 25 | xin_frame_desc *inputBuf, 26 | xin_out_buf_desc *outputBuf); 27 | 28 | void Xin26xGetReconFrame ( 29 | XIN_HANDLE encoderHandle, 30 | xin_frame_desc *reconBuf, 31 | UINT32 *reconBufNum); 32 | 33 | void Xin26xEncoderReconfig ( 34 | XIN_HANDLE encoderHandle); 35 | 36 | void Xin26xSetDefaultParam ( 37 | xin26x_params * param); 38 | 39 | void Xin26xControlOption ( 40 | XIN_HANDLE encoderHandle, 41 | xin26x_dynamic_params *dynParam); 42 | 43 | SINT32 Xin26xReadFrameCreate ( 44 | XIN_HANDLE *fileReadHandle, 45 | SINT32 frameRead(FILE *inputFile, xin_frame_desc *inputFrame), 46 | xin26x_params *config, 47 | FILE *fileHandle); 48 | 49 | void Xin26xReadFrameDelete ( 50 | XIN_HANDLE *fileReadHandle); 51 | 52 | void Xin26xReadFrame ( 53 | XIN_HANDLE fileReadHandle, 54 | xin_frame_desc *outFrame); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | #endif -------------------------------------------------------------------------------- /video_api/video_encoder/include/xin26x_logger.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************//** 2 | * 3 | * @file xin26x_logger.h 4 | * @brief This files contains h26x logger definition. 5 | * @authors Pig Peppa 6 | * @copyright (c) 2020, Pig Peppa All rights reserved 7 | * 8 | *******************************************************************************/ 9 | #ifndef _xin26x_logger_h_ 10 | #define _xin26x_logger_h_ 11 | #include "xin_typedef.h" 12 | 13 | typedef void (*XinLogEntry) ( 14 | UINT32 level, 15 | char* pMsg, 16 | ...); 17 | 18 | void Xin26xLogEntry ( 19 | UINT32 level, 20 | char* pMsg, 21 | ...); 22 | 23 | extern void (*pfXin26xLogEntry) ( 24 | UINT32 level, 25 | char* pMsg, 26 | ...); 27 | 28 | #define XIN_LOGGER_NONE (-1) 29 | #define XIN_LOGGER_ERROR 0 30 | #define XIN_LOGGER_WARNING 1 31 | #define XIN_LOGGER_STATUS 2 32 | #define XIN_LOGGER_DEBUG 3 33 | 34 | #endif -------------------------------------------------------------------------------- /video_api/video_encoder/include/xin26x_params.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************//** 2 | * 3 | * @file xin26x_params.h 4 | * @brief This files contains h26x encoder configuration api. 5 | * @authors Pig Peppa 6 | * @copyright (c) 2020, Pig Peppa All rights reserved 7 | * 8 | *******************************************************************************/ 9 | #ifndef _xin26x_params_h_ 10 | #define _xin26x_params_h_ 11 | 12 | #include "xin26x_logger.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | #define XIN26X_OPTION_SET_IDR 0 19 | #define XIN26X_OPTION_SET_FPS 1 20 | #define XIN26X_OPTION_SET_BITRATE 2 21 | #define XIN26X_OPTION_SET_TEMPLAYER 3 22 | #define XIN26X_OPTION_SET_RCMODE 4 23 | #define XIN26X_OPTION_GET_PSNR 5 24 | #define XIN26X_DYN_COMMAND_INVALID (255) 25 | 26 | #define XIN26X_LOG_NONE 0 27 | #define XIN26X_LOG_SEQ 1 28 | #define XIN26X_LOG_PIC 2 29 | 30 | typedef struct xin_frame_desc 31 | { 32 | void *yuvBuf[3]; 33 | 34 | UINT32 lumaWidth; 35 | UINT32 lumaHeight; 36 | 37 | intptr_t lumaStride; 38 | intptr_t chromaStride; 39 | 40 | UINT32 bitDepth; 41 | 42 | } xin_frame_desc; 43 | 44 | typedef struct xin_out_buf_desc 45 | { 46 | UINT8 *bitsBuf; 47 | SINT32 bytesGenerate; 48 | UINT32 temporalLayer; 49 | 50 | } xin_out_buf_desc; 51 | 52 | typedef struct xin26x_params 53 | { 54 | UINT32 inputWidth; 55 | UINT32 inputHeight; 56 | 57 | float frameRate; 58 | UINT32 bitRate; 59 | UINT32 crf; 60 | UINT32 vbvBufSize; 61 | UINT32 vbvMaxRate; 62 | UINT32 minQp; 63 | UINT32 maxQp; 64 | UINT32 rcMode; 65 | BOOL frameSkip; 66 | UINT32 encoderMode; 67 | UINT32 algorithmMode; 68 | 69 | UINT32 frameToBeEncoded; 70 | 71 | UINT32 bFrameNum; 72 | UINT32 refFrameNum; 73 | UINT32 temporalLayerNum; 74 | BOOL twoPassEncoder; 75 | UINT32 enableMctf; 76 | BOOL enableSceneCut; 77 | 78 | UINT32 intraPeriod; 79 | UINT32 refreshType; 80 | 81 | UINT32 screenContentMode; 82 | BOOL zeroLatency; 83 | 84 | UINT32 bitDepth; 85 | 86 | UINT32 minCbSize; 87 | UINT32 maxCbSize; 88 | 89 | UINT32 minTbSize; 90 | UINT32 maxTbSize; 91 | 92 | UINT32 interTbDepth; 93 | UINT32 intraTbDepth; 94 | 95 | UINT32 qp; 96 | 97 | BOOL calcPsnr; 98 | 99 | BOOL enableSao; 100 | 101 | BOOL enableGpb; 102 | 103 | BOOL enableStrongIntraSmoothing; 104 | BOOL enableTMvp; 105 | 106 | BOOL enableSignDataHiding; 107 | 108 | UINT32 enableRdoq; 109 | 110 | BOOL enableIntraNxN; 111 | BOOL enableInterNxN; 112 | 113 | BOOL constrainedIntraPredFlag; 114 | 115 | BOOL transformSkipFlag; 116 | UINT32 adaptiveBFrame; 117 | 118 | BOOL enableCuQpDelta; 119 | UINT32 diffCuQpDeltaDepth; 120 | 121 | UINT32 motionSearchMode; 122 | UINT32 searchRange; 123 | 124 | UINT32 enableSmp; 125 | UINT32 enableAmp; 126 | SINT32 chromaQpOffset; 127 | 128 | // h266 settings 129 | UINT32 ctuSize; 130 | UINT32 minQtSize; 131 | UINT32 maxBtSize; 132 | UINT32 maxTtSize; 133 | UINT32 maxMttDepth; 134 | UINT32 minCuSize; 135 | UINT32 maxTrSkipSize; 136 | BOOL enableMts; 137 | BOOL enableCclm; 138 | BOOL enableDmvr; 139 | BOOL lumaTrSize64; 140 | BOOL enableAlf; 141 | BOOL enableLmcs; 142 | BOOL enableSbTmvp; 143 | BOOL enableAffine; 144 | BOOL enableDepQuant; 145 | BOOL enableAmvr; 146 | BOOL enableBcw; 147 | 148 | // av1 settings 149 | UINT32 sbSize; 150 | BOOL enableRectPartType; 151 | UINT32 outputFormat; 152 | 153 | UINT32 threadNum; 154 | BOOL enableWpp; 155 | UINT32 enableFpp; 156 | UINT32 numTileCols; 157 | UINT32 numTileRows; 158 | BOOL unitTree; 159 | UINT32 lookAhead; 160 | double unitTreeStrength; 161 | 162 | BOOL enableDeblock; 163 | BOOL needRecon; 164 | XinLogEntry pfXinLogEntry; 165 | UINT32 logLevel; 166 | UINT32 clientId; 167 | UINT32 hiddenOption; 168 | 169 | } xin26x_params; 170 | 171 | typedef struct xin26x_dynamic_params 172 | { 173 | UINT32 optionId; 174 | float frameRate; 175 | UINT32 bitRate; 176 | UINT32 temporalLayerNum; 177 | UINT32 rcMode; 178 | double psnrYuv[3]; 179 | 180 | } xin26x_dynamic_params; 181 | 182 | #ifdef __cplusplus 183 | } 184 | #endif 185 | #endif 186 | -------------------------------------------------------------------------------- /video_api/video_encoder/xin26x_encoder.def: -------------------------------------------------------------------------------- 1 | LIBRARY 2 | EXPORTS 3 | 4 | Xin26xEncoderCreate 5 | Xin26xEncoderDelete 6 | Xin26xEncodeFrame 7 | Xin26xGetReconFrame 8 | Xin26xSetDefaultParam 9 | Xin26xControlOption 10 | Xin26xReadFrameCreate 11 | Xin26xReadFrameDelete 12 | Xin26xReadFrame --------------------------------------------------------------------------------