├── cmake └── xvc.pc.in ├── appveyor.yml ├── .travis.yml ├── src ├── xvc_common_lib │ ├── common.cc │ ├── utils_md5.h │ ├── simd │ │ ├── resampler_simd.h │ │ └── inter_prediction_simd.h │ ├── simd_cpu.h │ ├── simd_functions.h │ ├── simd_functions.cc │ ├── picture_types.h │ ├── checksum.h │ ├── deblocking_filter.h │ ├── transform_data.h │ ├── context_model.h │ ├── utils.h │ ├── reference_picture_lists.h │ ├── quantize.h │ ├── utils.cc │ ├── yuv_pic.h │ ├── intra_prediction.h │ ├── segment_header.h │ ├── common.h │ ├── reference_picture_lists.cc │ ├── checksum.cc │ ├── quantize.cc │ └── resample.h ├── xvc_enc_lib │ ├── encoder_simd_functions.h │ ├── encoder_simd_functions.cc │ ├── segment_header_writer.h │ ├── simd │ │ └── sample_metric_simd.h │ ├── bit_writer.h │ ├── bit_writer.cc │ ├── entropy_encoder.h │ ├── cu_writer.h │ ├── inter_tz_search.h │ ├── thread_encoder.h │ ├── intra_search.h │ ├── cu_cache.h │ ├── encoder_settings.h │ ├── syntax_writer.h │ ├── transform_encoder.h │ └── cu_encoder.h └── xvc_dec_lib │ ├── bit_reader.h │ ├── entropy_decoder.h │ ├── segment_header_reader.h │ ├── cu_decoder.h │ ├── bit_reader.cc │ ├── cu_reader.h │ ├── thread_decoder.h │ ├── entropy_decoder.cc │ └── picture_decoder.h ├── app ├── xvc_enc_app │ ├── main_enc.cc │ ├── y4m_reader.h │ └── encoder_app.h ├── xvc_dec_app │ ├── main_dec.cc │ ├── y4m_writer.h │ ├── y4m_writer.cc │ └── decoder_app.h └── CMakeLists.txt ├── test ├── googletest │ ├── CONTRIBUTORS │ ├── LICENSE │ └── src │ │ └── gtest_main.cc ├── CMakeLists.txt └── xvc_test │ ├── yuv_helper.h │ ├── resolution_test.cc │ ├── decoder_scalability_test.cc │ ├── decoder_helper.h │ └── hls_test.cc ├── .gitignore ├── CMakeLists.txt └── README.md /cmake/xvc.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${exec_prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: @CMAKE_PROJECT_NAME@ 7 | Description: xvc video codec library. 8 | Version: 1.0 9 | Libs: -L${libdir} -lxvcenc -lxvcdec 10 | Libs.private: @PKG_CONFIG_LINK_LIBS@ @CMAKE_THREAD_LIBS_INIT@ 11 | Cflags: -I${includedir} 12 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | image: Visual Studio 2019 2 | configuration: Release 3 | 4 | environment: 5 | matrix: 6 | - target: x64 7 | xvc_target: "x86_64" 8 | 9 | before_build: 10 | - SET XVC_TARGET_ARCH=%xvc_target% 11 | - cmake . -A %target% 12 | 13 | build: 14 | project: xvc.sln 15 | 16 | artifacts: 17 | - path: app\Release\*.* 18 | name: $(APPVEYOR_PROJECT_NAME)-$(target) 19 | 20 | deploy: 21 | - provider: GitHub 22 | artifact: $(APPVEYOR_PROJECT_NAME)-$(target) 23 | auth_token: 24 | secure: 'crYJW1VEBGF+La21YHoo9EO28nF55K0FyvVMeWwMBjf0JSyhGSuY1VUowmYyikGt' 25 | prerelease: true 26 | on: 27 | appveyor_repo_tag: true 28 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | cache: ccache 3 | dist: bionic 4 | osx_image: xcode11 5 | compiler: 6 | - gcc 7 | - clang 8 | os: 9 | - linux 10 | - osx 11 | 12 | addons: 13 | homebrew: 14 | packages: ccache 15 | 16 | env: 17 | matrix: 18 | - build_type=Release 19 | - build_type=Debug 20 | - build_type=Release build_shared=ON 21 | 22 | install: 23 | - if [ $TRAVIS_OS_NAME = osx ]; then brew install ccache; fi 24 | - export PATH="/usr/local/opt/ccache/libexec:$PATH" 25 | 26 | script: 27 | - mkdir build && cd build 28 | - cmake .. -DCMAKE_{C,CXX}_COMPILER_LAUNCHER=ccache -DCMAKE_BUILD_TYPE=${build_type:-Release} -DBUILD_SHARED_LIBS=${build_shared:-OFF} 29 | - make -j 8 30 | - make test 31 | - sudo make install 32 | 33 | matrix: 34 | exclude: 35 | - os: osx 36 | compiler: gcc 37 | -------------------------------------------------------------------------------- /src/xvc_common_lib/common.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "xvc_common_lib/common.h" 23 | 24 | namespace xvc { 25 | 26 | } // namespace xvc 27 | -------------------------------------------------------------------------------- /app/xvc_enc_app/main_enc.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "xvc_enc_app/encoder_app.h" 23 | 24 | int main(int argc, const char* argv[]) { 25 | xvc_app::EncoderApp main_app; 26 | 27 | main_app.ReadArguments(argc, argv); 28 | main_app.CheckParameters(); 29 | main_app.PrintEncoderSettings(); 30 | main_app.MainEncoderLoop(); 31 | main_app.PrintStatistics(); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /test/googletest/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This file contains a list of people who've made non-trivial 2 | # contribution to the Google C++ Testing Framework project. People 3 | # who commit code to the project are encouraged to add their names 4 | # here. Please keep the list sorted by first names. 5 | 6 | Ajay Joshi 7 | Balázs Dán 8 | Bharat Mediratta 9 | Chandler Carruth 10 | Chris Prince 11 | Chris Taylor 12 | Dan Egnor 13 | Eric Roman 14 | Hady Zalek 15 | Jeffrey Yasskin 16 | Jói Sigurðsson 17 | Keir Mierle 18 | Keith Ray 19 | Kenton Varda 20 | Manuel Klimek 21 | Markus Heule 22 | Mika Raento 23 | Miklós Fazekas 24 | Pasi Valminen 25 | Patrick Hanna 26 | Patrick Riley 27 | Peter Kaminski 28 | Preston Jackson 29 | Rainer Klaffenboeck 30 | Russ Cox 31 | Russ Rufer 32 | Sean Mcafee 33 | Sigurður Ásgeirsson 34 | Tracy Bialik 35 | Vadim Berman 36 | Vlad Losev 37 | Zhanyong Wan 38 | -------------------------------------------------------------------------------- /app/xvc_dec_app/main_dec.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "xvc_dec_app/decoder_app.h" 23 | 24 | int main(int argc, const char *argv[]) { 25 | xvc_app::DecoderApp main_app; 26 | 27 | main_app.ReadArguments(argc, argv); 28 | main_app.CheckParameters(); 29 | main_app.CreateAndConfigureApi(); 30 | main_app.PrintDecoderSettings(); 31 | main_app.MainDecoderLoop(); 32 | main_app.CloseStream(); 33 | main_app.PrintStatistics(); 34 | 35 | return main_app.CheckConformance(); 36 | } 37 | -------------------------------------------------------------------------------- /test/googletest/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2008, Google Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /src/xvc_common_lib/utils_md5.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_UTILS_MD5_H_ 23 | #define XVC_COMMON_LIB_UTILS_MD5_H_ 24 | 25 | #include 26 | 27 | namespace xvc { 28 | namespace util { 29 | 30 | class MD5 { 31 | public: 32 | MD5(); 33 | void Reset(); 34 | void Update(const uint8_t *buf, uint32_t len); 35 | void Final(uint8_t digest[16]); 36 | 37 | private: 38 | uint32_t buf_[4]; 39 | uint32_t bits_[2]; 40 | uint32_t state_[16]; 41 | }; 42 | 43 | } // namespace util 44 | } // namespace xvc 45 | 46 | #endif // XVC_COMMON_LIB_UTILS_MD5_H_ 47 | -------------------------------------------------------------------------------- /app/xvc_dec_app/y4m_writer.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_DEC_APP_Y4M_WRITER_H_ 23 | #define XVC_DEC_APP_Y4M_WRITER_H_ 24 | 25 | #include 26 | 27 | #include "xvc_dec_lib/xvcdec.h" 28 | 29 | namespace xvc_app { 30 | 31 | class Y4mWriter { 32 | public: 33 | void WriteHeader(const xvc_dec_pic_stats &stats, std::ostream *output); 34 | 35 | private: 36 | void WriteGlobalHeader(const xvc_dec_pic_stats &stats, std::ostream *output); 37 | 38 | bool global_header_written_ = false; 39 | }; 40 | 41 | } // namespace xvc_app 42 | 43 | #endif // XVC_DEC_APP_Y4M_WRITER_H_ 44 | -------------------------------------------------------------------------------- /src/xvc_common_lib/simd/resampler_simd.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_SIMD_RESAMPLER_SIMD_H_ 23 | #define XVC_COMMON_LIB_SIMD_RESAMPLER_SIMD_H_ 24 | 25 | #include 26 | 27 | #include "xvc_common_lib/common.h" 28 | #include "xvc_common_lib/simd_cpu.h" 29 | 30 | namespace xvc { 31 | 32 | struct SimdFunctions; 33 | 34 | namespace simd { 35 | 36 | struct ResamplerSimd { 37 | static void Register(const std::set &caps, 38 | xvc::SimdFunctions *simd); 39 | }; 40 | 41 | } // namespace simd 42 | } // namespace xvc 43 | 44 | #endif // XVC_COMMON_LIB_SIMD_RESAMPLER_SIMD_H_ 45 | -------------------------------------------------------------------------------- /src/xvc_common_lib/simd_cpu.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_SIMD_CPU_H_ 23 | #define XVC_COMMON_LIB_SIMD_CPU_H_ 24 | 25 | #include 26 | #include 27 | 28 | namespace xvc { 29 | 30 | enum class CpuCapability { 31 | kNeon = 1, 32 | kMmx, 33 | kSse, 34 | kSse2, 35 | kSse3, 36 | kSsse3, 37 | kSse4_1, 38 | kSse4_2, 39 | kAvx, 40 | kAvx2, 41 | 42 | kTotalNumber 43 | }; 44 | 45 | struct SimdCpu { 46 | static std::set GetMaskedCaps(uint32_t mask); 47 | static std::set GetRuntimeCapabilities(); 48 | }; 49 | 50 | } // namespace xvc 51 | 52 | #endif // XVC_COMMON_LIB_SIMD_CPU_H_ 53 | -------------------------------------------------------------------------------- /src/xvc_common_lib/simd/inter_prediction_simd.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_SIMD_INTER_PREDICTION_SIMD_H_ 23 | #define XVC_COMMON_LIB_SIMD_INTER_PREDICTION_SIMD_H_ 24 | 25 | #include 26 | 27 | #include "xvc_common_lib/common.h" 28 | #include "xvc_common_lib/simd_cpu.h" 29 | 30 | namespace xvc { 31 | 32 | struct SimdFunctions; 33 | 34 | namespace simd { 35 | 36 | struct InterPredictionSimd { 37 | static void Register(const std::set &caps, 38 | xvc::SimdFunctions *simd); 39 | }; 40 | 41 | } // namespace simd 42 | } // namespace xvc 43 | 44 | #endif // XVC_COMMON_LIB_SIMD_INTER_PREDICTION_SIMD_H_ 45 | -------------------------------------------------------------------------------- /src/xvc_common_lib/simd_functions.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_SIMD_FUNCTIONS_H_ 23 | #define XVC_COMMON_LIB_SIMD_FUNCTIONS_H_ 24 | 25 | #include 26 | 27 | #include "xvc_common_lib/common.h" 28 | #include "xvc_common_lib/simd_cpu.h" 29 | #include "xvc_common_lib/inter_prediction.h" 30 | #include "xvc_common_lib/resample.h" 31 | 32 | namespace xvc { 33 | 34 | struct SimdFunctions { 35 | explicit SimdFunctions(const std::set &capabilities); 36 | 37 | InterPrediction::SimdFunc inter_prediction; 38 | Resampler::SimdFunc resampler; 39 | }; 40 | 41 | } // namespace xvc 42 | 43 | #endif // XVC_COMMON_LIB_SIMD_FUNCTIONS_H_ 44 | -------------------------------------------------------------------------------- /src/xvc_common_lib/simd_functions.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "xvc_common_lib/simd_functions.h" 23 | 24 | #if defined(XVC_ARCH_ARM) || defined(XVC_ARCH_X86) || defined(XVC_ARCH_MIPS) 25 | #include "xvc_common_lib/simd/inter_prediction_simd.h" 26 | #include "xvc_common_lib/simd/resampler_simd.h" 27 | #endif 28 | 29 | namespace xvc { 30 | 31 | SimdFunctions::SimdFunctions(const std::set &capabilities) 32 | : inter_prediction() { 33 | #if defined(XVC_ARCH_ARM) || defined(XVC_ARCH_X86) || defined(XVC_ARCH_MIPS) 34 | simd::InterPredictionSimd::Register(capabilities, this); 35 | simd::ResamplerSimd::Register(capabilities, this); 36 | #endif 37 | } 38 | 39 | } // namespace xvc 40 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/encoder_simd_functions.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_ENCODER_SIMD_FUNCTIONS_H_ 23 | #define XVC_ENC_LIB_ENCODER_SIMD_FUNCTIONS_H_ 24 | 25 | #include 26 | 27 | #include "xvc_common_lib/simd_cpu.h" 28 | #include "xvc_enc_lib/sample_metric.h" 29 | #include "xvc_common_lib/simd_functions.h" 30 | 31 | namespace xvc { 32 | 33 | struct EncoderSimdFunctions : public SimdFunctions { 34 | explicit EncoderSimdFunctions(const std::set &capabilities, 35 | int internal_bitdepth); 36 | 37 | SampleMetric::SimdFunc sample_metric; 38 | }; 39 | 40 | } // namespace xvc 41 | 42 | #endif // XVC_ENC_LIB_ENCODER_SIMD_FUNCTIONS_H_ 43 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/encoder_simd_functions.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "xvc_enc_lib/encoder_simd_functions.h" 23 | 24 | #if defined(XVC_ARCH_ARM) || defined(XVC_ARCH_X86) || defined(XVC_ARCH_MIPS) 25 | #include "xvc_enc_lib/simd/sample_metric_simd.h" 26 | #endif 27 | 28 | namespace xvc { 29 | 30 | EncoderSimdFunctions::EncoderSimdFunctions(const std::set &caps, 31 | int internal_bitdepth) 32 | : SimdFunctions(caps), 33 | sample_metric() { 34 | #if defined(XVC_ARCH_ARM) || defined(XVC_ARCH_X86) || defined(XVC_ARCH_MIPS) 35 | simd::SampleMetricSimd::Register(caps, internal_bitdepth, this); 36 | #endif 37 | } 38 | 39 | } // namespace xvc 40 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/segment_header_writer.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_SEGMENT_HEADER_WRITER_H_ 23 | #define XVC_ENC_LIB_SEGMENT_HEADER_WRITER_H_ 24 | 25 | #include "xvc_common_lib/segment_header.h" 26 | 27 | #include "xvc_enc_lib/bit_writer.h" 28 | 29 | namespace xvc { 30 | 31 | class SegmentHeaderWriter { 32 | public: 33 | static void Write(const SegmentHeader &segment_header, BitWriter *bit_writer, 34 | double framerate); 35 | 36 | private: 37 | static void WriteRestrictions(const Restrictions &restrictions, 38 | BitWriter *bit_writer); 39 | }; 40 | 41 | } // namespace xvc 42 | 43 | #endif // XVC_ENC_LIB_SEGMENT_HEADER_WRITER_H_ 44 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/simd/sample_metric_simd.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_SIMD_SAMPLE_METRIC_SIMD_H_ 23 | #define XVC_ENC_LIB_SIMD_SAMPLE_METRIC_SIMD_H_ 24 | 25 | #include 26 | 27 | #include "xvc_common_lib/common.h" 28 | #include "xvc_common_lib/simd_cpu.h" 29 | 30 | namespace xvc { 31 | 32 | struct EncoderSimdFunctions; 33 | 34 | namespace simd { 35 | 36 | struct SampleMetricSimd { 37 | static void Register(const std::set &caps, 38 | int internal_bitdepth, 39 | xvc::EncoderSimdFunctions *simd); 40 | }; 41 | 42 | } // namespace simd 43 | } // namespace xvc 44 | 45 | #endif // XVC_ENC_LIB_SIMD_SAMPLE_METRIC_SIMD_H_ 46 | -------------------------------------------------------------------------------- /app/xvc_enc_app/y4m_reader.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_APP_Y4M_READER_H_ 23 | #define XVC_ENC_APP_Y4M_READER_H_ 24 | 25 | #include 26 | 27 | #include "xvc_enc_lib/xvcenc.h" 28 | 29 | namespace xvc_app { 30 | 31 | struct PictureFormat { 32 | int width = 0; 33 | int height = 0; 34 | double framerate = 0; 35 | int input_bitdepth = 8; 36 | xvc_enc_chroma_format chroma_format = XVC_ENC_CHROMA_FORMAT_420; 37 | }; 38 | 39 | class Y4mReader { 40 | public: 41 | explicit Y4mReader(std::istream *ifs) : ifs_(ifs) {} 42 | bool Read(PictureFormat *pic_format, std::streamoff *start_skip, 43 | std::streamoff *picture_skip); 44 | private: 45 | std::istream *ifs_; 46 | }; 47 | 48 | } // namespace xvc_app 49 | 50 | #endif // XVC_ENC_APP_Y4M_READER_H_ 51 | -------------------------------------------------------------------------------- /test/googletest/src/gtest_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #include 31 | 32 | #include "gtest/gtest.h" 33 | 34 | GTEST_API_ int main(int argc, char **argv) { 35 | printf("Running main() from gtest_main.cc\n"); 36 | testing::InitGoogleTest(&argc, argv); 37 | return RUN_ALL_TESTS(); 38 | } 39 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/bit_writer.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_BIT_WRITER_H_ 23 | #define XVC_ENC_LIB_BIT_WRITER_H_ 24 | 25 | #include 26 | #include 27 | 28 | #include "xvc_common_lib/common.h" 29 | 30 | namespace xvc { 31 | 32 | class BitWriter { 33 | public: 34 | BitWriter() : shift_(0) { 35 | } 36 | 37 | std::vector* GetBytes() { return &buffer_; } 38 | void Clear() { 39 | buffer_.clear(); 40 | assert(!shift_); 41 | } 42 | void WriteBit(uint32_t bitval); 43 | void WriteBits(uint32_t bits, int num_bits); 44 | void PadZeroBits(); 45 | void WriteByte(uint8_t byte); 46 | void WriteBytes(const uint8_t *byte, size_t num_bytes); 47 | 48 | private: 49 | int shift_; 50 | std::vector buffer_; 51 | }; 52 | 53 | } // namespace xvc 54 | 55 | #endif // XVC_ENC_LIB_BIT_WRITER_H_ 56 | -------------------------------------------------------------------------------- /src/xvc_dec_lib/bit_reader.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_DEC_LIB_BIT_READER_H_ 23 | #define XVC_DEC_LIB_BIT_READER_H_ 24 | 25 | #include 26 | #include 27 | 28 | #include "xvc_common_lib/common.h" 29 | 30 | namespace xvc { 31 | 32 | class BitReader { 33 | public: 34 | BitReader(const uint8_t *buffer, size_t length) 35 | : buffer_(buffer), length_(length) { 36 | } 37 | 38 | size_t GetPosition() const; 39 | int ReadBit(); 40 | uint32_t ReadBits(int num_bits); 41 | void SkipBits(); 42 | uint8_t ReadByte(); 43 | void ReadBytes(uint8_t *bytes, size_t len); 44 | void Rewind(int num_bits); 45 | 46 | private: 47 | void Refill(); 48 | 49 | int bit_mask_ = 0x80; 50 | size_t consumed_ = 0; 51 | const uint8_t *buffer_ = nullptr; 52 | size_t length_ = 0; 53 | }; 54 | 55 | } // namespace xvc 56 | 57 | #endif // XVC_DEC_LIB_BIT_READER_H_ 58 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/bit_writer.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "xvc_enc_lib/bit_writer.h" 23 | 24 | #include 25 | 26 | namespace xvc { 27 | 28 | void BitWriter::WriteBit(uint32_t bit_val) { 29 | if (!shift_) { 30 | buffer_.push_back(0); 31 | shift_ = 8; 32 | } 33 | buffer_.back() |= (bit_val << --shift_); 34 | } 35 | 36 | void BitWriter::WriteBits(uint32_t bits, int num_bits) { 37 | uint32_t mask = 1 << (num_bits - 1); 38 | while (mask) { 39 | WriteBit((bits & (mask)) ? 1 : 0); 40 | mask >>= 1; 41 | } 42 | } 43 | 44 | void BitWriter::PadZeroBits() { 45 | if (shift_) { 46 | shift_ = 0; 47 | } 48 | } 49 | 50 | void BitWriter::WriteByte(uint8_t byte) { 51 | assert(!shift_); 52 | buffer_.push_back(byte); 53 | } 54 | 55 | void BitWriter::WriteBytes(const uint8_t *byte, size_t num_bytes) { 56 | buffer_.insert(buffer_.end(), byte, byte + num_bytes); 57 | } 58 | 59 | } // namespace xvc 60 | -------------------------------------------------------------------------------- /src/xvc_dec_lib/entropy_decoder.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_DEC_LIB_ENTROPY_DECODER_H_ 23 | #define XVC_DEC_LIB_ENTROPY_DECODER_H_ 24 | 25 | #include "xvc_common_lib/context_model.h" 26 | #include "xvc_dec_lib/bit_reader.h" 27 | 28 | namespace xvc { 29 | 30 | template 31 | class EntropyDecoder { 32 | public: 33 | explicit EntropyDecoder(BitReader *bit_reader); 34 | 35 | uint32_t DecodeBin(ContextModel *ctx); 36 | uint32_t DecodeBypass(); 37 | uint32_t DecodeBypassBins(int num_bins); 38 | uint32_t DecodeBinTrm(); 39 | 40 | void Start(); 41 | void Finish(); 42 | 43 | private: 44 | uint32_t range_; 45 | uint32_t value_; 46 | int bits_needed_; 47 | BitReader *bit_reader_; 48 | }; 49 | 50 | extern template class EntropyDecoder; 51 | extern template class EntropyDecoder; 52 | 53 | } // namespace xvc 54 | 55 | #endif // XVC_DEC_LIB_ENTROPY_DECODER_H_ 56 | -------------------------------------------------------------------------------- /app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_CXX_STANDARD 11) 2 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 3 | set(CMAKE_CXX_EXTENSIONS OFF) 4 | 5 | SET(XVC_DEC_APP_SOURCES 6 | "xvc_dec_app/decoder_app.cc" 7 | "xvc_dec_app/decoder_app.h" 8 | "xvc_dec_app/main_dec.cc" 9 | "xvc_dec_app/y4m_writer.cc" 10 | "xvc_dec_app/y4m_writer.h") 11 | 12 | set(XVC_ENC_APP_SOURCES 13 | "xvc_enc_app/encoder_app.cc" 14 | "xvc_enc_app/encoder_app.h" 15 | "xvc_enc_app/main_enc.cc" 16 | "xvc_enc_app/y4m_reader.cc" 17 | "xvc_enc_app/y4m_reader.h") 18 | 19 | if(ENABLE_ASSERTIONS) 20 | add_definitions(-UNDEBUG) 21 | string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " " CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") 22 | endif() 23 | 24 | if(BUILD_SHARED_LIBS) 25 | add_definitions(-DXVC_SHARED_LIB) 26 | endif() 27 | 28 | if(MSVC) 29 | set(cxx_flags /GS /W3 /WX /Za /EHsc) 30 | elseif(CMAKE_COMPILER_IS_GNUCXX) 31 | set(cxx_flags -Wall -Wshadow -Werror -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -fexceptions) 32 | if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) 33 | set(cxx_flags ${cxx_flags} -Wno-error=missing-braces) 34 | endif() 35 | elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") 36 | set(cxx_flags -Wshadow -Werror -fexceptions) 37 | endif() 38 | 39 | # xvc_enc_app 40 | add_executable(xvc_enc_app ${XVC_ENC_APP_SOURCES}) 41 | set_target_properties(xvc_enc_app PROPERTIES OUTPUT_NAME "xvcenc") 42 | target_compile_options(xvc_enc_app PRIVATE ${cxx_flags}) 43 | target_include_directories(xvc_enc_app PUBLIC . ../src) 44 | target_link_libraries(xvc_enc_app LINK_PUBLIC xvc_enc_lib) 45 | 46 | # xvc_dec_app 47 | add_executable(xvc_dec_app ${XVC_DEC_APP_SOURCES}) 48 | set_target_properties(xvc_dec_app PROPERTIES OUTPUT_NAME "xvcdec") 49 | target_compile_options(xvc_dec_app PRIVATE ${cxx_flags}) 50 | target_include_directories(xvc_dec_app PUBLIC . ../src) 51 | target_link_libraries(xvc_dec_app LINK_PUBLIC xvc_dec_lib) 52 | 53 | install(TARGETS xvc_enc_app xvc_dec_app DESTINATION "${CMAKE_INSTALL_BINDIR}") 54 | -------------------------------------------------------------------------------- /src/xvc_dec_lib/segment_header_reader.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_DEC_LIB_SEGMENT_HEADER_READER_H_ 23 | #define XVC_DEC_LIB_SEGMENT_HEADER_READER_H_ 24 | 25 | #include "xvc_common_lib/segment_header.h" 26 | 27 | #include "xvc_dec_lib/decoder.h" 28 | #include "xvc_dec_lib/bit_reader.h" 29 | 30 | namespace xvc { 31 | 32 | class SegmentHeaderReader { 33 | public: 34 | static Decoder::State Read(SegmentHeader* segment_header, 35 | BitReader *bit_reader, 36 | SegmentNum segment_counter, 37 | bool* accept_xvc_bit_zero); 38 | static bool SupportedBitstreamVersion(uint32_t major_version, 39 | uint32_t minor_version); 40 | 41 | private: 42 | static Restrictions ReadRestrictions(const SegmentHeader &segment_header, 43 | BitReader *bit_reader); 44 | }; 45 | 46 | } // namespace xvc 47 | 48 | #endif // XVC_DEC_LIB_SEGMENT_HEADER_READER_H_ 49 | -------------------------------------------------------------------------------- /src/xvc_common_lib/picture_types.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_PICTURE_TYPES_H_ 23 | #define XVC_COMMON_LIB_PICTURE_TYPES_H_ 24 | 25 | namespace xvc { 26 | 27 | enum class NalUnitType { 28 | kIntraPicture = 0, 29 | kIntraAccessPicture = 1, 30 | kPredictedPicture = 2, 31 | kPredictedAccessPicture = 3, 32 | kBipredictedPicture = 4, 33 | kBipredictedAccessPicture = 5, 34 | kReservedPictureType6 = 6, 35 | kReservedPictureType7 = 7, 36 | kReservedPictureType8 = 8, 37 | kReservedPictureType9 = 9, 38 | kReservedPictureType10 = 10, 39 | kSegmentHeader = 16, 40 | kSei = 17, 41 | kAccessUnitDelimiter = 18, 42 | kEndOfSegment = 19, 43 | }; 44 | 45 | enum class OutputStatus { 46 | kReady, 47 | kProcessing, 48 | kPostProcessing, 49 | kFinishedProcessing, 50 | kHasNotBeenOutput, 51 | kHasBeenOutput, 52 | }; 53 | 54 | enum class PicturePredictionType { 55 | kIntra = 2, 56 | kUni = 1, 57 | kBi = 0, 58 | kInvalid = 99, 59 | }; 60 | 61 | } // namespace xvc 62 | 63 | #endif // XVC_COMMON_LIB_PICTURE_TYPES_H_ 64 | -------------------------------------------------------------------------------- /src/xvc_common_lib/checksum.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_CHECKSUM_H_ 23 | #define XVC_COMMON_LIB_CHECKSUM_H_ 24 | 25 | #include 26 | 27 | #include "xvc_common_lib/common.h" 28 | #include "xvc_common_lib/yuv_pic.h" 29 | #include "xvc_common_lib/restrictions.h" 30 | 31 | namespace xvc { 32 | 33 | class Checksum { 34 | public: 35 | enum class Method { 36 | kNone = 0, 37 | kCrc = 1, 38 | kMd5 = 2, 39 | }; 40 | enum class Mode { 41 | kMinOverhead = 0, 42 | kMaxRobust = 1, 43 | kTotalNumber = 2, 44 | kInvalid = 99, 45 | }; 46 | static const Method kDefaultMethod = Method::kMd5; 47 | static const Method kFallbackMethod = Method::kCrc; 48 | 49 | Checksum(Method method, Mode mode) : method_(method), mode_(mode) {} 50 | void HashPicture(const YuvPicture &pic); 51 | std::vector GetHash() const { return hash_; } 52 | 53 | private: 54 | void CalculateCrc(const YuvPicture &pic, Mode mode); 55 | void CalculateMd5(const YuvPicture &pic, Mode mode); 56 | 57 | const Method method_; 58 | const Mode mode_; 59 | std::vector hash_; 60 | }; 61 | 62 | } // namespace xvc 63 | 64 | #endif // XVC_COMMON_LIB_CHECKSUM_H_ 65 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_CXX_STANDARD 11) 2 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 3 | set(CMAKE_CXX_EXTENSIONS OFF) 4 | 5 | set(gtest_force_shared_crt ON CACHE BOOL "Use shared (DLL) run-time lib") 6 | add_subdirectory(googletest EXCLUDE_FROM_ALL) 7 | 8 | set(XVC_TEST_SOURCES 9 | "xvc_test/all_intra_test.cc" 10 | "xvc_test/checksum_enc_dec_test.cc" 11 | "xvc_test/decoder_api_test.cc" 12 | "xvc_test/decoder_helper.h" 13 | "xvc_test/decoder_resample_test.cc" 14 | "xvc_test/decoder_scalability_test.cc" 15 | "xvc_test/encode_decode_test.cc" 16 | "xvc_test/encoder_api_test.cc" 17 | "xvc_test/encoder_helper.h" 18 | "xvc_test/hls_test.cc" 19 | "xvc_test/resampler_test.cc" 20 | "xvc_test/residual_coding_test.cc" 21 | "xvc_test/resolution_test.cc" 22 | "xvc_test/restrictions_test.cc" 23 | "xvc_test/simd_test.cc" 24 | "xvc_test/transform_test.cc" 25 | "xvc_test/yuv_helper.cc" 26 | "xvc_test/yuv_helper.h") 27 | 28 | if(ENABLE_ASSERTIONS) 29 | add_definitions(-UNDEBUG) 30 | string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " " CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") 31 | endif() 32 | 33 | if(BUILD_SHARED_LIBS) 34 | add_definitions(-DXVC_SHARED_LIB) 35 | endif() 36 | 37 | if(MSVC) 38 | set(cxx_flags /GS /W3 /WX /Za /EHsc) 39 | elseif(CMAKE_COMPILER_IS_GNUCXX) 40 | set(cxx_flags -Wall -Wshadow -Werror -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -fexceptions) 41 | if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) 42 | set(cxx_flags ${cxx_flags} -Wno-error=missing-braces) 43 | endif() 44 | elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") 45 | set(cxx_flags -Wshadow -Werror -fexceptions) 46 | endif() 47 | 48 | if(BUILD_TESTS_LIBS) 49 | # xvc_test_lib 50 | add_library(xvc_test_lib STATIC ${XVC_TEST_SOURCES}) 51 | target_compile_options(xvc_test_lib PRIVATE ${cxx_flags}) 52 | target_include_directories(xvc_test_lib PUBLIC . ../src) 53 | target_link_libraries(xvc_test_lib PRIVATE xvc_enc_lib xvc_dec_lib PUBLIC gtest) 54 | endif() 55 | 56 | # xvc_test 57 | add_executable(xvc_test ${XVC_TEST_SOURCES}) 58 | target_compile_options(xvc_test PRIVATE ${cxx_flags}) 59 | target_include_directories(xvc_test PUBLIC . ../src) 60 | target_link_libraries(xvc_test LINK_PUBLIC xvc_enc_lib xvc_dec_lib gtest_main) 61 | add_test(xvc_test xvc_test) 62 | 63 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/entropy_encoder.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_ENTROPY_ENCODER_H_ 23 | #define XVC_ENC_LIB_ENTROPY_ENCODER_H_ 24 | 25 | #include "xvc_common_lib/context_model.h" 26 | #include "xvc_enc_lib/bit_writer.h" 27 | 28 | namespace xvc { 29 | 30 | class EntropyEncoder { 31 | public: 32 | explicit EntropyEncoder(BitWriter *bit_writer); 33 | EntropyEncoder(BitWriter *bit_writer, uint32_t written_bits, 34 | uint32_t fractional_bits); 35 | 36 | void EncodeBin(uint32_t binval, ContextModel *ctx); 37 | void EncodeBypass(uint32_t binval); 38 | void EncodeBypassBins(uint32_t binvals, int num_bins); 39 | void EncodeBinTrm(uint32_t binval); 40 | 41 | void ResetBitCounting() { frac_bits_ &= 32767; } 42 | void Start(); 43 | void Finish(); 44 | Bits GetNumWrittenBits() const { 45 | return static_cast(frac_bits_ >> 15); 46 | } 47 | Bits GetFractionalBits() const { 48 | return static_cast(frac_bits_ & 32767); 49 | } 50 | 51 | private: 52 | void WriteOut(); 53 | void WriteIfPossible(); 54 | 55 | uint32_t low_; 56 | uint32_t range_; 57 | uint32_t buffered_byte_; 58 | int num_buffered_bytes_; 59 | int bits_left_; 60 | uint64_t frac_bits_ = 0; 61 | BitWriter *bit_writer_; 62 | }; 63 | 64 | } // namespace xvc 65 | 66 | #endif // XVC_ENC_LIB_ENTROPY_ENCODER_H_ 67 | -------------------------------------------------------------------------------- /src/xvc_dec_lib/cu_decoder.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_DEC_LIB_CU_DECODER_H_ 23 | #define XVC_DEC_LIB_CU_DECODER_H_ 24 | 25 | #include 26 | 27 | #include "xvc_common_lib/sample_buffer.h" 28 | #include "xvc_common_lib/inter_prediction.h" 29 | #include "xvc_common_lib/intra_prediction.h" 30 | #include "xvc_common_lib/picture_data.h" 31 | #include "xvc_common_lib/quantize.h" 32 | #include "xvc_common_lib/simd_functions.h" 33 | #include "xvc_common_lib/transform.h" 34 | #include "xvc_common_lib/yuv_pic.h" 35 | #include "xvc_dec_lib/cu_reader.h" 36 | #include "xvc_dec_lib/syntax_reader.h" 37 | 38 | namespace xvc { 39 | 40 | class CuDecoder { 41 | public: 42 | CuDecoder(const SimdFunctions &simd, YuvPicture *decoded_pic, 43 | PictureData *picture_data); 44 | void DecodeCtu(int rsaddr, SyntaxReader *reader); 45 | 46 | private: 47 | static const ptrdiff_t kBufferStride_ = constants::kMaxBlockSize; 48 | void ReadCtu(int rsaddr, SyntaxReader *reader); 49 | void DecompressCu(CodingUnit *cu); 50 | void DecompressComponent(CodingUnit *cu, YuvComponent comp, const Qp &qp); 51 | void PredictIntra(const CodingUnit &cu, YuvComponent comp, 52 | SampleBuffer *pred_buffer); 53 | 54 | const Sample min_pel_; 55 | const Sample max_pel_; 56 | YuvPicture &decoded_pic_; 57 | PictureData &pic_data_; 58 | InterPrediction inter_pred_; 59 | IntraPrediction intra_pred_; 60 | InverseTransform inv_transform_; 61 | Quantize quantize_; 62 | CuReader cu_reader_; 63 | SampleBufferStorage temp_pred_; 64 | ResidualBufferStorage temp_resi_; 65 | CoeffBufferStorage temp_coeff_; 66 | }; 67 | 68 | } // namespace xvc 69 | 70 | #endif // XVC_DEC_LIB_CU_DECODER_H_ 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | ## Ignore Visual Studio temporary files, build results, and 35 | ## files generated by popular Visual Studio add-ons. 36 | 37 | # User-specific files 38 | *.suo 39 | *.user 40 | *.userosscache 41 | *.sln.docstates 42 | 43 | # User-specific files (MonoDevelop/Xamarin Studio) 44 | *.userprefs 45 | 46 | # Build results 47 | [Dd]ebug/ 48 | [Dd]ebugPublic/ 49 | [Rr]elease/ 50 | [Rr]eleases/ 51 | x64/ 52 | x86/ 53 | bld/ 54 | [Bb]in/ 55 | [Oo]bj/ 56 | [Ll]og/ 57 | 58 | # Visual Studio 2015 cache/options directory 59 | .vs/ 60 | 61 | # MSTest test Results 62 | [Tt]est[Rr]esult*/ 63 | [Bb]uild[Ll]og.* 64 | 65 | # NUNIT 66 | *.VisualState.xml 67 | TestResult.xml 68 | 69 | # Build Results of an ATL Project 70 | [Dd]ebugPS/ 71 | [Rr]eleasePS/ 72 | dlldata.c 73 | 74 | # DNX 75 | project.lock.json 76 | project.fragment.lock.json 77 | artifacts/ 78 | 79 | *_i.c 80 | *_p.c 81 | *_i.h 82 | *.ilk 83 | *.meta 84 | *.obj 85 | *.pch 86 | *.pdb 87 | *.pgc 88 | *.pgd 89 | *.rsp 90 | *.sbr 91 | *.tlb 92 | *.tli 93 | *.tlh 94 | *.tmp 95 | *.tmp_proj 96 | *.log 97 | *.vspscc 98 | *.vssscc 99 | .builds 100 | *.pidb 101 | *.svclog 102 | *.scc 103 | 104 | # Chutzpah Test files 105 | _Chutzpah* 106 | 107 | # Visual C++ cache files 108 | ipch/ 109 | *.aps 110 | *.ncb 111 | *.opendb 112 | *.opensdf 113 | *.sdf 114 | *.cachefile 115 | *.VC.db 116 | *.VC.VC.opendb 117 | 118 | # Visual Studio profiler 119 | *.psess 120 | *.vsp 121 | *.vspx 122 | *.sap 123 | 124 | # Visual Studio code coverage results 125 | *.coverage 126 | *.coveragexml 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Visual Studio cache files 139 | # files ending in .cache can be ignored 140 | *.[Cc]ache 141 | # but keep track of directories ending in .cache 142 | !*.[Cc]ache/ 143 | 144 | # Others 145 | ClientBin/ 146 | ~$* 147 | *~ 148 | *.dbmdl 149 | *.dbproj.schemaview 150 | *.jfm 151 | *.pfx 152 | *.publishsettings 153 | 154 | # Backup & report files from converting an old project file 155 | # to a newer Visual Studio version. Backup files are not needed, 156 | # because we have git ;-) 157 | _UpgradeReport_Files/ 158 | Backup*/ 159 | UpgradeLog*.XML 160 | UpgradeLog*.htm 161 | 162 | -------------------------------------------------------------------------------- /app/xvc_dec_app/y4m_writer.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "xvc_dec_app/y4m_writer.h" 23 | 24 | #include 25 | #include 26 | 27 | namespace xvc_app { 28 | 29 | void Y4mWriter::WriteHeader(const xvc_dec_pic_stats &stats, 30 | std::ostream *output) { 31 | if (!global_header_written_) { 32 | WriteGlobalHeader(stats, output); 33 | global_header_written_ = true; 34 | } 35 | (*output) << "FRAME\n"; 36 | } 37 | 38 | void Y4mWriter::WriteGlobalHeader(const xvc_dec_pic_stats &stats, 39 | std::ostream * output) { 40 | int fps_num, fps_denom; 41 | if (static_cast(stats.framerate) == stats.framerate) { 42 | fps_num = static_cast(stats.framerate); 43 | fps_denom = 1; 44 | } else { 45 | fps_num = static_cast(1000 * stats.framerate); 46 | fps_denom = 1000; 47 | } 48 | const char *chroma_format = nullptr; 49 | if (stats.chroma_format == XVC_DEC_CHROMA_FORMAT_420) { 50 | chroma_format = "420"; 51 | } else if (stats.chroma_format == XVC_DEC_CHROMA_FORMAT_444) { 52 | chroma_format = "444"; 53 | } else if (stats.chroma_format == XVC_DEC_CHROMA_FORMAT_422) { 54 | chroma_format = "422"; 55 | } else if (stats.chroma_format == XVC_DEC_CHROMA_FORMAT_MONOCHROME) { 56 | chroma_format = "mono"; 57 | } else { 58 | assert(0); 59 | } 60 | (*output) 61 | << "YUV4MPEG2 " 62 | << "W" << stats.width << " H" << stats.height << " " 63 | << "F" << fps_num << ":" << fps_denom << " " 64 | << "Ip"; 65 | if (chroma_format) { 66 | (*output) << " C" << chroma_format; 67 | if (stats.bitdepth > 8) { 68 | (*output) << "p" << stats.bitdepth; 69 | } 70 | (*output) << " "; 71 | } 72 | (*output) << "\n"; 73 | } 74 | 75 | } // namespace xvc_app 76 | -------------------------------------------------------------------------------- /src/xvc_dec_lib/bit_reader.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "xvc_dec_lib/bit_reader.h" 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | namespace xvc { 30 | 31 | size_t BitReader::GetPosition() const { 32 | assert(bit_mask_ == 0x80); 33 | return consumed_; 34 | } 35 | 36 | int BitReader::ReadBit() { 37 | int val = buffer_[consumed_] & bit_mask_; 38 | bit_mask_ >>= 1; 39 | if (!bit_mask_) { 40 | bit_mask_ = 0x80; 41 | assert(consumed_ < length_); 42 | if (consumed_ < length_) { 43 | consumed_++; 44 | } 45 | } 46 | return val ? 1 : 0; 47 | } 48 | 49 | uint32_t BitReader::ReadBits(int num_bits) { 50 | uint32_t bits = 0; 51 | while (num_bits) { 52 | bits |= ReadBit() << (num_bits - 1); 53 | num_bits--; 54 | } 55 | return bits; 56 | } 57 | 58 | void BitReader::SkipBits() { 59 | if (bit_mask_ != 0x80) { 60 | bit_mask_ = 0x80; 61 | assert(consumed_ < length_); 62 | if (consumed_ < length_) { 63 | consumed_++; 64 | } 65 | } 66 | } 67 | 68 | uint8_t BitReader::ReadByte() { 69 | assert(consumed_ < length_); 70 | if (consumed_ >= length_) { 71 | throw std::runtime_error("corrupt bitstream"); 72 | } 73 | return buffer_[consumed_++]; 74 | } 75 | 76 | void BitReader::ReadBytes(uint8_t *bytes, size_t len) { 77 | assert(consumed_ < length_); 78 | assert(consumed_ + len <= length_); 79 | size_t tocopy = std::min(len, length_ - consumed_); 80 | std::memcpy(bytes, &buffer_[consumed_], tocopy); 81 | consumed_ += tocopy; 82 | } 83 | 84 | void BitReader::Rewind(int num_bits) { 85 | while (num_bits--) { 86 | bit_mask_ <<= 1; 87 | if (bit_mask_ == 0x100) { 88 | bit_mask_ = 0x1; 89 | assert(consumed_ > 0); 90 | --consumed_; 91 | } 92 | } 93 | } 94 | 95 | } // namespace xvc 96 | -------------------------------------------------------------------------------- /src/xvc_dec_lib/cu_reader.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_DEC_LIB_CU_READER_H_ 23 | #define XVC_DEC_LIB_CU_READER_H_ 24 | 25 | #include "xvc_common_lib/coding_unit.h" 26 | #include "xvc_common_lib/picture_data.h" 27 | #include "xvc_dec_lib/syntax_reader.h" 28 | 29 | namespace xvc { 30 | 31 | class CuReader { 32 | public: 33 | CuReader(PictureData *pic_data, const IntraPrediction &intra_pred); 34 | bool ReadCtu(CodingUnit *cu, SyntaxReader *reader) { 35 | ctu_has_coeffs_ = false; 36 | ReadCu(cu, SplitRestriction::kNone, reader); 37 | return ctu_has_coeffs_; 38 | } 39 | 40 | private: 41 | void ReadCu(CodingUnit *cu, SplitRestriction split_restrict, 42 | SyntaxReader *reader); 43 | SplitType ReadSplit(CodingUnit *cu, SplitRestriction split_restriction, 44 | SyntaxReader *reader); 45 | void ReadComponent(CodingUnit *cu, YuvComponent comp, SyntaxReader *reader); 46 | void ReadIntraPrediction(CodingUnit *cu, YuvComponent comp, 47 | SyntaxReader *reader); 48 | void ReadInterPrediction(CodingUnit *cu, YuvComponent comp, 49 | SyntaxReader *reader); 50 | void ReadMergePrediction(CodingUnit *cu, YuvComponent comp, 51 | SyntaxReader *reader); 52 | void ReadResidualData(CodingUnit *cu, YuvComponent comp, 53 | SyntaxReader *reader); 54 | void ReadResidualDataInternal(CodingUnit *cu, YuvComponent comp, 55 | SyntaxReader *reader) const; 56 | bool ReadCbfInvariant(CodingUnit *cu, YuvComponent comp, 57 | SyntaxReader *reader) const; 58 | 59 | const Restrictions &restrictions_; 60 | PictureData *pic_data_; 61 | const IntraPrediction &intra_pred_; 62 | bool ctu_has_coeffs_ = false; 63 | }; 64 | 65 | } // namespace xvc 66 | 67 | #endif // XVC_DEC_LIB_CU_READER_H_ 68 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/cu_writer.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_CU_WRITER_H_ 23 | #define XVC_ENC_LIB_CU_WRITER_H_ 24 | 25 | #include "xvc_common_lib/coding_unit.h" 26 | #include "xvc_common_lib/intra_prediction.h" 27 | #include "xvc_common_lib/picture_data.h" 28 | #include "xvc_enc_lib/syntax_writer.h" 29 | 30 | namespace xvc { 31 | 32 | class CuWriter { 33 | public: 34 | CuWriter(const PictureData &pic_data, const IntraPrediction *intra_pred) 35 | : pic_data_(pic_data), 36 | intra_pred_(intra_pred) { 37 | } 38 | bool WriteCtu(CodingUnit *ctu, PictureData *cu_map, SyntaxWriter *writer); 39 | void WriteCu(CodingUnit *cu, SplitRestriction split_restriction, 40 | PictureData *cu_map, SyntaxWriter *writer); 41 | void WriteSplit(const CodingUnit &cu, SplitRestriction split_restriction, 42 | SyntaxWriter *writer); 43 | void WriteComponent(const CodingUnit &cu, YuvComponent comp, 44 | SyntaxWriter *writer); 45 | void WriteIntraPrediction(const CodingUnit &cu, YuvComponent comp, 46 | SyntaxWriter *writer); 47 | void WriteInterPrediction(const CodingUnit &cu, YuvComponent comp, 48 | SyntaxWriter *writer); 49 | void WriteMergePrediction(const CodingUnit &cu, YuvComponent comp, 50 | SyntaxWriter *writer); 51 | void WriteResidualData(const CodingUnit &cu, YuvComponent comp, 52 | SyntaxWriter *writer); 53 | // Encoder only method with simplified cbf rdo signaling 54 | void WriteResidualDataRdoCbf(const CodingUnit &cu, YuvComponent comp, 55 | SyntaxWriter *writer) const; 56 | 57 | private: 58 | void WriteResidualDataInternal(const CodingUnit &cu, YuvComponent comp, 59 | SyntaxWriter *writer) const; 60 | bool WriteCbfInvariant(const CodingUnit &cu, YuvComponent comp, 61 | SyntaxWriter *writer) const; 62 | 63 | const PictureData &pic_data_; 64 | const IntraPrediction *intra_pred_; 65 | bool ctu_has_coeffs_ = false; 66 | }; 67 | 68 | } // namespace xvc 69 | 70 | #endif // XVC_ENC_LIB_CU_WRITER_H_ 71 | -------------------------------------------------------------------------------- /app/xvc_dec_app/decoder_app.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_DEC_APP_DECODER_APP_H_ 23 | #define XVC_DEC_APP_DECODER_APP_H_ 24 | 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "xvc_dec_lib/xvcdec.h" 33 | 34 | namespace xvc_app { 35 | 36 | class DecoderApp { 37 | public: 38 | DecoderApp() : xvc_api_(nullptr), params_(nullptr), decoder_(nullptr) {} 39 | ~DecoderApp(); 40 | void ReadArguments(int argc, const char *argv[]); 41 | bool CheckParameters(); 42 | void CreateAndConfigureApi(); 43 | void PrintDecoderSettings(); 44 | void MainDecoderLoop(); 45 | void CloseStream(); 46 | void PrintStatistics(); 47 | int CheckConformance(); 48 | 49 | private: 50 | void PrintUsage(); 51 | size_t ReadNextNalSize(std::istream *input); 52 | void PrintPictureInfo(xvc_dec_pic_stats pic_stats); 53 | std::ostream& GetLog() { 54 | return !log_to_stderr_ ? std::cout : std::cerr; 55 | } 56 | 57 | std::ifstream input_stream_; 58 | std::ofstream file_output_stream_; 59 | bool output_to_stdout_ = false; 60 | bool log_to_stderr_ = false; 61 | bool output_y4m_format_ = false; 62 | 63 | int num_pictures_decoded_ = 0; 64 | int segment_info_printed_ = 0; 65 | bool all_pictures_baseline_ = true; 66 | 67 | // command line arguments 68 | struct { 69 | std::string input_filename; 70 | std::string output_filename; 71 | int output_width = -1; 72 | int output_height = -1; 73 | xvc_dec_chroma_format output_chroma_format = 74 | XVC_DEC_CHROMA_FORMAT_UNDEFINED; 75 | xvc_dec_color_matrix output_color_matrix = XVC_DEC_COLOR_MATRIX_UNDEFINED; 76 | int output_bitdepth = -1; 77 | int max_framerate = -1; 78 | int threads = -1; 79 | int simd_mask = -1; 80 | int dither = -1; 81 | int loop = -1; 82 | int verbose = 0; 83 | } cli_; 84 | 85 | const xvc_decoder_api *xvc_api_; 86 | xvc_decoder_parameters *params_; 87 | xvc_decoder *decoder_; 88 | 89 | std::chrono::time_point start_; 90 | std::chrono::time_point end_; 91 | }; 92 | 93 | } // namespace xvc_app 94 | 95 | #endif // XVC_DEC_APP_DECODER_APP_H_ 96 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/inter_tz_search.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_INTER_TZ_SEARCH_H_ 23 | #define XVC_ENC_LIB_INTER_TZ_SEARCH_H_ 24 | 25 | #include "xvc_common_lib/coding_unit.h" 26 | #include "xvc_common_lib/inter_prediction.h" 27 | #include "xvc_common_lib/yuv_pic.h" 28 | #include "xvc_common_lib/quantize.h" 29 | #include "xvc_enc_lib/sample_metric.h" 30 | #include "xvc_enc_lib/encoder_settings.h" 31 | 32 | namespace xvc { 33 | 34 | class TzSearch { 35 | public: 36 | TzSearch(const YuvPicture &orig_pic, const InterPrediction &inter_pred, 37 | const EncoderSettings &encoder_settings, int search_range) 38 | : orig_pic_(orig_pic), 39 | inter_pred_(inter_pred), 40 | encoder_settings_(encoder_settings), 41 | search_range_(search_range) { 42 | } 43 | MvFullpel Search(const CodingUnit &cu, const Qp &qp, 44 | const SampleMetric &metric, const MotionVector &mvp, 45 | const YuvPicture &ref_pic, const MvFullpel &mv_min, 46 | const MvFullpel &mv_max, const MvFullpel &prev_search); 47 | 48 | private: 49 | using const_mv = const MvFullpel; 50 | struct Left { static const int index = -1; }; 51 | struct Right { static const int index = 1; }; 52 | struct Up { static const int index = -3; }; 53 | struct Down { static const int index = 3; }; 54 | struct SearchState; 55 | template class DistortionWrapper; 56 | 57 | bool FullpelDiamondSearch(SearchState *state, const MvFullpel &mv_base, 58 | int range); 59 | void FullpelNeighborPointSearch(SearchState *state); 60 | bool CheckCostBest(SearchState *state, int mv_x, int mv_y); 61 | template 62 | bool CheckCost1(SearchState *state, int mv_x, int mv_y, int range); 63 | template 64 | bool CheckCost2(SearchState *state, int mv_x, int mv_y, int range); 65 | template 66 | bool IsInside(int mv_x, int mv_y, const_mv *mv_min, const_mv *mv_max); 67 | 68 | const YuvPicture &orig_pic_; 69 | const InterPrediction &inter_pred_; 70 | const EncoderSettings &encoder_settings_; 71 | int search_range_; 72 | }; 73 | 74 | } // namespace xvc 75 | 76 | #endif // XVC_ENC_LIB_INTER_TZ_SEARCH_H_ 77 | -------------------------------------------------------------------------------- /src/xvc_common_lib/deblocking_filter.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_DEBLOCKING_FILTER_H_ 23 | #define XVC_COMMON_LIB_DEBLOCKING_FILTER_H_ 24 | 25 | #include "xvc_common_lib/coding_unit.h" 26 | #include "xvc_common_lib/picture_data.h" 27 | #include "xvc_common_lib/yuv_pic.h" 28 | 29 | namespace xvc { 30 | 31 | enum class Direction { 32 | kVertical, 33 | kHorizontal, 34 | }; 35 | 36 | class DeblockingFilter { 37 | public: 38 | DeblockingFilter(PictureData *pic_data, YuvPicture *rec_pic, 39 | int beta_offset, int tc_offset); 40 | void DeblockPicture(); 41 | 42 | private: 43 | // Controls at what level filter decisions are made at 44 | static const int kSubblockSize = 8; 45 | static const int kSubblockSizeExt = 4; 46 | static const int kChromaFilterResolution = 8; 47 | // Number of samples to filter in parallel 48 | static const int kFilterGroupSize = 4; 49 | 50 | void DeblockCtu(int rsaddr, CuTree cu_tree, Direction dir, 51 | int subblock_size); 52 | int GetBoundaryStrength(const CodingUnit &cu_p, const CodingUnit &cu_q, 53 | int pos_x, int pos_y, Direction dir); 54 | void FilterEdgeLuma(int x, int y, Direction dir, int subblock_size, 55 | int boundary_strength, int qp); 56 | bool CheckStrongFilter(Sample *src, int beta, int tc, ptrdiff_t offset); 57 | void FilterLumaWeak(Sample *src_ptr, ptrdiff_t step_size, 58 | ptrdiff_t offset, int tc, bool filter_p1, 59 | bool filter_q1); 60 | void FilterLumaStrong(Sample *src_ptr, ptrdiff_t step_size, 61 | ptrdiff_t offset, int tc); 62 | void FilterEdgeChroma(int x, int y, int scale_x, int scale_y, Direction dir, 63 | int subblock_size, int boundary_strength, int qp); 64 | template 65 | void FilterChroma(Sample *src_ptr, ptrdiff_t step_size, 66 | ptrdiff_t offset, int tc2); 67 | 68 | const Restrictions &restrictions_; 69 | PictureData *pic_data_; 70 | YuvPicture *rec_pic_; 71 | int beta_offset_ = 0; 72 | int tc_offset_ = 0; 73 | }; 74 | 75 | } // namespace xvc 76 | 77 | #endif // XVC_COMMON_LIB_DEBLOCKING_FILTER_H_ 78 | -------------------------------------------------------------------------------- /src/xvc_common_lib/transform_data.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_TRANSFORM_DATA_H_ 23 | #define XVC_COMMON_LIB_TRANSFORM_DATA_H_ 24 | 25 | #include 26 | #include 27 | 28 | namespace xvc { 29 | 30 | class TransformData { 31 | public: 32 | // DCT-2 (6 bits precision) 33 | static const int16_t kDct2Transform4[4][4]; 34 | static const int16_t kDct2Transform8[8][8]; 35 | static const int16_t kDct2Transform16[16][16]; 36 | static const int16_t kDct2Transform32[32][32]; 37 | // DCT-2 (8 bits precision) 38 | static const int16_t kDct2Transform2High[2][2]; 39 | static const int16_t kDct2Transform4High[4][4]; 40 | static const int16_t kDct2Transform8High[8][8]; 41 | static const int16_t kDct2Transform16High[16][16]; 42 | static const int16_t kDct2Transform32High[32][32]; 43 | static const int16_t kDct2Transform64High[64][64]; 44 | // DCT-5 (8 bits precision) 45 | static const int16_t kDct5Transform4High[4 * 4]; 46 | static const int16_t kDct5Transform8High[8 * 8]; 47 | static const int16_t kDct5Transform16High[16 * 16]; 48 | static const int16_t kDct5Transform32High[32 * 32]; 49 | static const int16_t kDct5Transform64High[64 * 64]; 50 | // DCT-8 (8 bits precision) 51 | static const int16_t kDct8Transform4High[4 * 4]; 52 | static const int16_t kDct8Transform8High[8 * 8]; 53 | static const int16_t kDct8Transform16High[16 * 16]; 54 | static const int16_t kDct8Transform32High[32 * 32]; 55 | static const int16_t kDct8Transform64High[64 * 64]; 56 | // DST-1 (8 bits precision) 57 | static const int16_t kDst1Transform4High[4 * 4]; 58 | static const int16_t kDst1Transform8High[8 * 8]; 59 | static const int16_t kDst1Transform16High[16 * 16]; 60 | static const int16_t kDst1Transform32High[32 * 32]; 61 | static const int16_t kDst1Transform64High[64 * 64]; 62 | // DST-7 (8 bits precision) 63 | static const int16_t kDst7Transform4High[4 * 4]; 64 | static const int16_t kDst7Transform8High[8 * 8]; 65 | static const int16_t kDst7Transform16High[16 * 16]; 66 | static const int16_t kDst7Transform32High[32 * 32]; 67 | static const int16_t kDst7Transform64High[64 * 64]; 68 | }; 69 | 70 | } // namespace xvc 71 | 72 | #endif // XVC_COMMON_LIB_TRANSFORM_DATA_H_ 73 | -------------------------------------------------------------------------------- /src/xvc_common_lib/context_model.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_CONTEXT_MODEL_H_ 23 | #define XVC_COMMON_LIB_CONTEXT_MODEL_H_ 24 | 25 | #include 26 | 27 | #include "xvc_common_lib/common.h" 28 | 29 | namespace xvc { 30 | 31 | class ContextModel { 32 | public: 33 | static const int kFracBitsPrecision = 15; 34 | static const uint32_t kEntropyBypassBits = 1 << kFracBitsPrecision; 35 | 36 | void Init(int qp, int init_value); 37 | void UpdateLPS(); 38 | void UpdateMPS(); 39 | uint32_t GetState() const { return (state_ >> 1); } 40 | uint32_t GetMps() const { return (state_ & 1); } 41 | uint32_t GetLps(int range) const { 42 | return kRangeTable_[state_ >> 1][(range >> 6) & 3]; 43 | } 44 | uint32_t GetEntropyBits(uint32_t bin) const { 45 | return kEntropyBits_[state_ ^ bin]; 46 | } 47 | uint8_t GetRenormBitsLps(uint32_t lps) const { 48 | return kRenormTable_[lps >> 3]; 49 | } 50 | static uint32_t GetEntropyBitsTrm(uint32_t bin) { 51 | return kEntropyBits_[126 ^ bin]; 52 | } 53 | 54 | protected: 55 | static const int kNumCtxStates = 64; 56 | static const std::array kNextStateMps_; 57 | static const std::array kNextStateLps_; 58 | static const std::array kEntropyBits_; 59 | static const std::array kRenormTable_; 60 | static const std::array, kNumCtxStates> kRangeTable_; 61 | uint8_t state_ = 0; 62 | }; 63 | 64 | // TODO(PH) Following classes gives performance boost to decoder by not having 65 | // to check restriction flags for every bin but are not used by encoder due to 66 | // adding extra code complexity together with rdo 67 | 68 | class ContextModelDynamic : public ContextModel { 69 | public: 70 | // Override parent methods without virtual to avoid restriction check 71 | void UpdateLPS() { 72 | state_ = kNextStateLps_[state_]; 73 | } 74 | void UpdateMPS() { 75 | state_ = kNextStateMps_[state_]; 76 | } 77 | }; 78 | 79 | class ContextModelStatic : public ContextModel { 80 | public: 81 | // Override parent methods without virtual to avoid restriction check 82 | void UpdateLPS() {} 83 | void UpdateMPS() {} 84 | }; 85 | 86 | } // namespace xvc 87 | 88 | #endif // XVC_COMMON_LIB_CONTEXT_MODEL_H_ 89 | -------------------------------------------------------------------------------- /src/xvc_dec_lib/thread_decoder.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_DEC_LIB_THREAD_DECODER_H_ 23 | #define XVC_DEC_LIB_THREAD_DECODER_H_ 24 | 25 | // Some C++11 headers are not allowed by cpplint 26 | #include // NOLINT 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include // NOLINT 32 | #include // NOLINT 33 | #include 34 | 35 | #include "xvc_common_lib/segment_header.h" 36 | #include "xvc_dec_lib/picture_decoder.h" 37 | 38 | namespace xvc { 39 | 40 | class ThreadDecoder { 41 | public: 42 | using PicDecList = std::vector>; 43 | using PictureDecodedCallback = 44 | std::function, bool, 45 | const PicDecList &)>; 46 | 47 | explicit ThreadDecoder(int num_threads); 48 | ~ThreadDecoder(); 49 | void StopAll(); 50 | void DecodeAsync(std::shared_ptr &&segment_header, 51 | std::shared_ptr &&prev_segment_header, 52 | std::shared_ptr &&pic_dec, 53 | std::vector> &&deps, 54 | std::unique_ptr> &&nal, 55 | size_t nal_offset); 56 | void WaitForPicture(const std::shared_ptr &pic, 57 | PictureDecodedCallback callback); 58 | void WaitOne(PictureDecodedCallback callback); 59 | void WaitAll(PictureDecodedCallback callback); 60 | 61 | private: 62 | struct WorkItem { 63 | std::shared_ptr pic_dec; 64 | std::vector> inter_dependencies; 65 | std::shared_ptr segment_header; 66 | std::shared_ptr prev_segment_header; 67 | std::unique_ptr> nal; 68 | std::size_t nal_offset; 69 | bool success; 70 | }; 71 | void WorkerMain(); 72 | 73 | std::vector worker_threads_; 74 | std::mutex global_mutex_; 75 | std::condition_variable wait_work_cond_; 76 | std::condition_variable work_done_cond_; 77 | std::list pending_work_; 78 | std::deque finished_work_; 79 | int jobs_in_flight_ = 0; 80 | bool running_ = true; 81 | }; 82 | 83 | } // namespace xvc 84 | 85 | #endif // XVC_DEC_LIB_THREAD_DECODER_H_ 86 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/thread_encoder.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_THREAD_ENCODER_H_ 23 | #define XVC_ENC_LIB_THREAD_ENCODER_H_ 24 | 25 | // Some C++11 headers are not allowed by cpplint 26 | #include // NOLINT 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include // NOLINT 32 | #include // NOLINT 33 | #include 34 | 35 | #include "xvc_common_lib/segment_header.h" 36 | #include "xvc_enc_lib/encoder_settings.h" 37 | #include "xvc_enc_lib/picture_encoder.h" 38 | 39 | namespace xvc { 40 | 41 | class ThreadEncoder { 42 | public: 43 | using PicEncList = std::vector>; 44 | using PictureDecodedCallback = 45 | std::function, const PicEncList &, 46 | std::unique_ptr> pic_nal)>; 47 | 48 | ThreadEncoder(int num_threads, const EncoderSettings &encoder_settings); 49 | ~ThreadEncoder(); 50 | size_t GetNumThreads() const { return worker_threads_.size(); } 51 | void StopAll(); 52 | void EncodeAsync(std::shared_ptr segment_header, 53 | std::shared_ptr pic_enc, 54 | const std::vector> &, 55 | std::unique_ptr> &&output_nal_buffer, 56 | int segment_qp, bool buffer_flag); 57 | void WaitForPicture(const std::shared_ptr &pic, 58 | PictureDecodedCallback callback); 59 | void WaitOne(PictureDecodedCallback callback); 60 | 61 | private: 62 | struct WorkItem { 63 | std::shared_ptr pic_enc; 64 | std::vector> pic_dependencies; 65 | std::shared_ptr segment_header; 66 | std::unique_ptr> nal_buffer; 67 | int segment_qp; 68 | bool buffer_flag; 69 | const std::vector *pic_bytes; 70 | }; 71 | void WorkerMain(int thread_idx); 72 | 73 | const EncoderSettings &encoder_settings_; 74 | std::vector worker_threads_; 75 | std::mutex global_mutex_; 76 | std::condition_variable wait_work_cond_; 77 | std::condition_variable work_done_cond_; 78 | std::list pending_work_; 79 | std::deque finished_work_; 80 | bool running_ = true; 81 | }; 82 | 83 | } // namespace xvc 84 | 85 | #endif // XVC_ENC_LIB_THREAD_ENCODER_H_ 86 | -------------------------------------------------------------------------------- /test/xvc_test/yuv_helper.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_TEST_YUV_HELPER_H_ 23 | #define XVC_TEST_YUV_HELPER_H_ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "googletest/include/gtest/gtest.h" 30 | 31 | #include "xvc_common_lib/common.h" 32 | #include "xvc_common_lib/sample_buffer.h" 33 | #include "xvc_common_lib/yuv_pic.h" 34 | 35 | namespace xvc_test { 36 | 37 | class TestYuvPic { 38 | public: 39 | using Sample = ::xvc::Sample; 40 | static const int kDefaultSize = 32; 41 | static const int kInternalPicSize = 40; 42 | 43 | TestYuvPic(int width, int height, int bitdepth, int dx = 0, int dy = 0, 44 | xvc::ChromaFormat chroma_fmt = xvc::ChromaFormat::k420); 45 | const std::vector GetBytes() const { return bytes_; } 46 | const Sample* GetSamplePtr(xvc::YuvComponent comp) const; 47 | xvc::SampleBufferConst GetSampleBuffer() const { 48 | return xvc::SampleBufferConst(&samples_[0], width_); 49 | } 50 | ptrdiff_t GetStride(xvc::YuvComponent comp) const { 51 | return stride_[static_cast(comp)]; 52 | } 53 | Sample GetAverageSample(); 54 | int GetBitdepth() const { return bitdepth_; } 55 | double CalcPsnr(const char *bytes) const; 56 | double CalcPsnr(xvc::YuvComponent comp, const xvc::YuvPicture &ref_pic); 57 | void FillLargerBuffer(int out_width, int out_height, xvc::SampleBuffer *out); 58 | 59 | static ::testing::AssertionResult 60 | SameSamples(int src_width, int src_height, 61 | const xvc_test::TestYuvPic &orig_pic, int orig_upshift, 62 | const xvc::YuvPicture &ref_pic, int ref_upshift); 63 | static ::testing::AssertionResult 64 | SamePictureBytes(const uint8_t *pic1, size_t size1, 65 | const uint8_t *pic2, size_t size2); 66 | static ::testing::AssertionResult 67 | AllSampleEqualTo(int width, int height, int bitdepth, 68 | const char* pic_bytes, size_t size, 69 | xvc::Sample expected_sample); 70 | 71 | private: 72 | static const int kInternalBitdepth = 10; 73 | static const int kInternalBufferSize = 74 | 3 * kInternalPicSize * kInternalPicSize / 2; 75 | static std::array kTestSamples; 76 | 77 | int width_; 78 | int height_; 79 | int bitdepth_; 80 | xvc::ChromaFormat chroma_fmt_; 81 | std::array stride_; 82 | std::vector samples_; 83 | std::vector bytes_; 84 | }; 85 | 86 | } // namespace xvc_test 87 | 88 | #endif // XVC_TEST_YUV_HELPER_H_ 89 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/intra_search.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_INTRA_SEARCH_H_ 23 | #define XVC_ENC_LIB_INTRA_SEARCH_H_ 24 | 25 | #include 26 | 27 | #include "xvc_common_lib/intra_prediction.h" 28 | #include "xvc_common_lib/picture_data.h" 29 | #include "xvc_enc_lib/syntax_writer.h" 30 | #include "xvc_enc_lib/cu_writer.h" 31 | #include "xvc_enc_lib/encoder_settings.h" 32 | #include "xvc_enc_lib/encoder_simd_functions.h" 33 | #include "xvc_enc_lib/transform_encoder.h" 34 | 35 | namespace xvc { 36 | 37 | class IntraSearch : public IntraPrediction { 38 | public: 39 | IntraSearch(const EncoderSimdFunctions &simd, int bitdepth, 40 | const PictureData &pic_data, const YuvPicture &orig_pic, 41 | const EncoderSettings &encoder_settings); 42 | 43 | Distortion CompressIntraLuma(CodingUnit *cu, const Qp &qp, 44 | const SyntaxWriter &bitstream_writer, 45 | TransformEncoder *encoder, YuvPicture *rec_pic); 46 | Distortion CompressIntraChroma(CodingUnit *cu, const Qp &qp, 47 | const SyntaxWriter &bitstream_writer, 48 | TransformEncoder *encoder, 49 | YuvPicture *rec_pic); 50 | Distortion CompressIntraFast(CodingUnit *cu, YuvComponent comp, const Qp &qp, 51 | const SyntaxWriter &writer, 52 | TransformEncoder *encoder, YuvPicture *rec_pic); 53 | 54 | private: 55 | using IntraModeSet = 56 | std::array, kNbrIntraModesExt>; 57 | Distortion PredictAndTransform(CodingUnit *cu, YuvComponent comp, 58 | const Qp &qp, const SyntaxWriter &writer, 59 | const IntraPrediction::RefState &ref_state, 60 | TransformEncoder *encoder, 61 | YuvPicture *rec_pic); 62 | int DetermineSlowIntraModes(CodingUnit *cu, const Qp &qp, 63 | const SyntaxWriter &bitstream_writer, 64 | const IntraPrediction::RefState &ref_state, 65 | TransformEncoder *encoder, YuvPicture *rec_pic, 66 | IntraModeSet *modes_cost); 67 | 68 | const PictureData &pic_data_; 69 | const YuvPicture &orig_pic_; 70 | const EncoderSettings &encoder_settings_; 71 | const SampleMetric satd_metric_; 72 | CodingUnit::ResidualState best_cu_state_; 73 | CuWriter cu_writer_; 74 | }; 75 | 76 | } // namespace xvc 77 | 78 | #endif // XVC_ENC_LIB_INTRA_SEARCH_H_ 79 | -------------------------------------------------------------------------------- /src/xvc_common_lib/utils.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_UTILS_H_ 23 | #define XVC_COMMON_LIB_UTILS_H_ 24 | 25 | #include 26 | #include 27 | 28 | #include "xvc_common_lib/common.h" 29 | 30 | namespace xvc { 31 | 32 | namespace util { 33 | 34 | constexpr bool IsLuma(YuvComponent comp) { 35 | return comp == YuvComponent::kY; 36 | } 37 | 38 | constexpr bool IsFirstChroma(YuvComponent comp) { 39 | return comp == YuvComponent::kU; 40 | } 41 | 42 | constexpr int CompToPlane(YuvComponent comp) { 43 | return IsLuma(comp) ? 0 : 1; 44 | } 45 | 46 | template 47 | static T Clip3(U value, T min, T max) { 48 | return static_cast(std::min(std::max(value, static_cast(min)), 49 | static_cast(max))); 50 | } 51 | 52 | template 53 | static Sample ClipBD(T value, Sample max) { 54 | if (value < 0) return 0; 55 | if (value > max) return max; 56 | return static_cast(value); 57 | } 58 | 59 | int SizeToLog2(int size); 60 | int SizeLog2Bits(int size); 61 | int Log2Floor(int x); 62 | 63 | int GetChromaShiftX(ChromaFormat chroma_format); 64 | int GetChromaShiftY(ChromaFormat chroma_format); 65 | 66 | int ScaleChromaX(int size, ChromaFormat chroma_format); 67 | int ScaleChromaY(int size, ChromaFormat chroma_format); 68 | 69 | inline int ScaleSizeX(int size, ChromaFormat chroma_format, 70 | YuvComponent comp) { 71 | return IsLuma(comp) ? size : ScaleChromaX(size, chroma_format); 72 | } 73 | 74 | inline int ScaleSizeY(int size, ChromaFormat chroma_format, 75 | YuvComponent comp) { 76 | return IsLuma(comp) ? size : ScaleChromaY(size, chroma_format); 77 | } 78 | 79 | inline int GetLumaNumSamples(int width, int height) { 80 | return width * height; 81 | } 82 | 83 | inline int GetChromaNumSamples(int width, int height, ChromaFormat chroma_fmt) { 84 | return ScaleChromaX(width, chroma_fmt) * ScaleChromaY(height, chroma_fmt); 85 | } 86 | 87 | inline int GetTotalNumSamples(int width, int height, ChromaFormat chroma_fmt) { 88 | if (chroma_fmt == ChromaFormat::kArgb) { 89 | return 4 * GetLumaNumSamples(width, height); 90 | } 91 | return GetLumaNumSamples(width, height) + 92 | (GetChromaNumSamples(width, height, chroma_fmt) << 1); 93 | } 94 | 95 | inline int GetNumComponents(ChromaFormat chroma_fmt) { 96 | return chroma_fmt == ChromaFormat::kMonochrome ? 1 : 3; 97 | } 98 | 99 | } // namespace util 100 | 101 | } // namespace xvc 102 | 103 | #endif // XVC_COMMON_LIB_UTILS_H_ 104 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/cu_cache.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_CU_CACHE_H_ 23 | #define XVC_ENC_LIB_CU_CACHE_H_ 24 | 25 | #include 26 | 27 | #include "xvc_common_lib/picture_data.h" 28 | #include "xvc_common_lib/coding_unit.h" 29 | 30 | namespace xvc { 31 | 32 | // Class for caching coding unit objects with the same location and size 33 | // that are coded more than one time due to different split configurations 34 | // When using binary split depth 3 the following split configurations will 35 | // result in "identical" coding unit objects: 36 | // hor, hor, ver (inverse: ver, ver, hor) 37 | // hor, ver, hor (inverse: ver, hor, ver) 38 | // ver, hor, ver (inverse, hor, ver, ver) 39 | // quad, hor (inverse, quad, ver) 40 | // 41 | // The following combinations results in cu objects that are only coded once, 42 | // so therefore they are not cached: 43 | // hor hor hor (inverse: ver ver ver) 44 | class CuCache { 45 | public: 46 | struct Result { 47 | const CodingUnit *cu; 48 | bool cacheable; 49 | bool any_intra; 50 | bool any_inter; 51 | bool any_skip; 52 | }; 53 | explicit CuCache(PictureData *pic_data); 54 | ~CuCache(); 55 | 56 | void Invalidate(CuTree cu_tree, int depth); 57 | Result Lookup(const CodingUnit &cu); 58 | bool Store(const CodingUnit &cu); 59 | 60 | private: 61 | // number of cu objects to store per cache entry, 62 | // not needed if only using feature flags 63 | static const int kNumCuPerEntry = 0; 64 | // Number of cache partitions is related to number of binary splits 65 | // binary split depth = 0 => 0 (no cu objects are coded twice) 66 | // binary split depth = 1 => 1 (only full size, ver+hor and hor+ver) 67 | // binary split depth = 2 => 5 (full + binary split partion with depth 1) 68 | static const int kNumCachePartitions = 5; 69 | enum class CachePartition { 70 | kFull = 0, kHorizontal0, kHorizontal1, kVertical0, kVertical1, kOther 71 | }; 72 | enum CacheFeature { 73 | kFeatureValid = 0, 74 | kFeatureAnyIntra = 1, 75 | kFeatureAnyInter = 2, 76 | kFeatureAnySkip = 3, 77 | }; 78 | struct CacheEntry { 79 | std::array valid; 80 | std::array cu; 81 | uint8_t features; 82 | }; 83 | 84 | CacheEntry* Find(const CodingUnit &cu); 85 | CachePartition DetermineCuPartition(const CodingUnit &cu); 86 | 87 | PictureData* const pic_data_; 88 | std::array, 90 | constants::kQuadSplit>, 91 | constants::kMaxBlockDepth + 2>, 92 | constants::kMaxNumCuTrees> cu_cache_; 93 | }; 94 | 95 | } // namespace xvc 96 | 97 | #endif // XVC_ENC_LIB_CU_CACHE_H_ 98 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.1) 2 | if(POLICY CMP0056) # added in CMake 3.2 3 | cmake_policy(SET CMP0056 NEW) 4 | endif() 5 | 6 | project (xvc CXX C) 7 | 8 | include(GNUInstallDirs) 9 | 10 | find_package(Threads REQUIRED) 11 | 12 | # Project options 13 | option(HIGH_BITDEPTH "Store pixel samples as 16bit values." ON) 14 | option(BUILD_SHARED_LIBS "Build shared instead of static libraries." OFF) 15 | option(BUILD_APPS "Build sample console applications" ON) 16 | option(BUILD_TESTS "Build all test code" ON) 17 | option(BUILD_TESTS_LIBS "Build all test code as library" OFF) 18 | option(ENABLE_ASSEMBLY "Compile with assembly coded functions" ON) 19 | option(ENABLE_ASSERTIONS "Compile with assertions" ON) 20 | option(CODE_ANALYZE "Compile with code analyzer (MSVC)" OFF) 21 | if (CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) 22 | set(SANITIZE_BUILD "" CACHE STRING "Compile with sanitizer enabled (GCC/clang)") 23 | endif() 24 | 25 | if(NOT CMAKE_BUILD_TYPE) 26 | set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) 27 | endif() 28 | 29 | if(MSVC AND BUILD_TESTS AND BUILD_SHARED_LIBS) 30 | message(WARNING "Unit-tests disabled when building shared libraries") 31 | set(BUILD_TESTS OFF CACHE BOOL "Build all test code" FORCE) 32 | endif() 33 | 34 | # Target arch detection 35 | set(XVC_HAVE_NEON FALSE) 36 | if(NOT XVC_TARGET_ARCH) 37 | # Determine arch based on host cpu and generator used 38 | if("${CMAKE_GENERATOR}" MATCHES "^Visual Studio .+ ARM$") 39 | set(XVC_TARGET_ARCH "ARM") 40 | set(XVC_HAVE_NEON TRUE) 41 | elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64" OR 42 | "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "amd64" OR 43 | "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" OR 44 | "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i386" OR 45 | "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86") 46 | set(XVC_TARGET_ARCH "x86") 47 | elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "aarch64|armv7") 48 | set(XVC_TARGET_ARCH "ARM") 49 | set(XVC_HAVE_NEON TRUE) 50 | else() 51 | message(FATAL_ERROR "Unexpected host cpu: ${CMAKE_SYSTEM_PROCESSOR}") 52 | endif() 53 | else() 54 | # Extract architecture family from user specified arch 55 | if("${XVC_TARGET_ARCH}" STREQUAL "x86_64") 56 | set(XVC_TARGET_ARCH "x86") 57 | elseif("${XVC_TARGET_ARCH}" MATCHES "^arm") 58 | if ("${XVC_TARGET_ARCH}" MATCHES "^arm64") 59 | set(XVC_HAVE_NEON TRUE) 60 | elseif ("${XVC_TARGET_ARCH}" MATCHES "^armv7|^arm.*-v7") 61 | set(XVC_HAVE_NEON TRUE) 62 | endif() 63 | set(XVC_TARGET_ARCH "ARM") 64 | elseif("${XVC_TARGET_ARCH}" MATCHES "^mips") 65 | set(XVC_TARGET_ARCH "MIPS") 66 | endif() 67 | endif() 68 | if(NOT "${XVC_TARGET_ARCH}" MATCHES "^(x86|ARM|MIPS)$") 69 | message(FATAL_ERROR "Unexpected target architecture: ${XVC_TARGET_ARCH}") 70 | endif() 71 | 72 | if(HIGH_BITDEPTH) 73 | add_definitions(-DXVC_HIGH_BITDEPTH=1) 74 | else() 75 | add_definitions(-DXVC_HIGH_BITDEPTH=0) 76 | endif() 77 | 78 | if(BUILD_SHARED_LIBS) 79 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 80 | endif() 81 | 82 | add_subdirectory(src) 83 | if(BUILD_APPS) 84 | add_subdirectory(app) 85 | endif() 86 | if(BUILD_TESTS OR BUILD_TESTS_LIBS) 87 | enable_testing() 88 | add_subdirectory(test) 89 | endif() 90 | 91 | # pkg-config support 92 | set(PKG_CONFIG_LINK_LIBS "") 93 | foreach(LIB ${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES}) 94 | if(IS_ABSOLUTE ${LIB} AND EXISTS ${LIB}) 95 | set(PKG_CONFIG_LINK_LIBS "${PKG_CONFIG_LINK_LIBS} ${LIB}") 96 | else() 97 | set(PKG_CONFIG_LINK_LIBS "${PKG_CONFIG_LINK_LIBS} -l${LIB}") 98 | endif() 99 | endforeach() 100 | configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/xvc.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/xvc.pc" @ONLY) 101 | 102 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/xvc.pc" 103 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") 104 | -------------------------------------------------------------------------------- /src/xvc_common_lib/reference_picture_lists.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_REFERENCE_PICTURE_LISTS_H_ 23 | #define XVC_COMMON_LIB_REFERENCE_PICTURE_LISTS_H_ 24 | 25 | #include 26 | #include 27 | 28 | #include "xvc_common_lib/cu_types.h" 29 | #include "xvc_common_lib/quantize.h" 30 | #include "xvc_common_lib/yuv_pic.h" 31 | 32 | namespace xvc { 33 | 34 | enum class RefPicList { 35 | kL0 = 0, 36 | kL1 = 1, 37 | kTotalNumber = 2 38 | }; 39 | 40 | class CodingUnit; 41 | class PictureData; 42 | 43 | class ReferencePictureLists { 44 | public: 45 | static bool IsRefPicListUsed(RefPicList ref_pic_list, InterDir inter_dir); 46 | static RefPicList Inverse(RefPicList ref_list) { 47 | return ref_list == RefPicList::kL0 ? RefPicList::kL1 : RefPicList::kL0; 48 | } 49 | 50 | int GetNumRefPics(RefPicList list) const { 51 | return (list == RefPicList::kL0) ? 52 | static_cast(l0_.size()) : static_cast(l1_.size()); 53 | } 54 | const YuvPicture* GetRefPic(RefPicList ref_list, int ref_idx) const { 55 | return ref_list == RefPicList::kL0 ? 56 | l0_[ref_idx].ref_pic.get() : l1_[ref_idx].ref_pic.get(); 57 | } 58 | const YuvPicture* GetRefOrigPic(RefPicList ref_list, int ref_idx) const { 59 | return ref_list == RefPicList::kL0 ? 60 | l0_[ref_idx].orig_pic.get() : l1_[ref_idx].orig_pic.get(); 61 | } 62 | PicNum GetRefPoc(RefPicList ref_list, int ref_idx) const { 63 | return (ref_list == RefPicList::kL0) ? l0_[ref_idx].poc : l1_[ref_idx].poc; 64 | } 65 | bool HasRefPoc(RefPicList ref_list, PicNum poc) const; 66 | bool HasOnlyBackReferences() const { return only_back_references_; } 67 | PicturePredictionType GetRefPicType(RefPicList ref_list, int ref_idx) const; 68 | int GetRefPicTid(RefPicList ref_list, int ref_idx) const; 69 | const CodingUnit* GetCodingUnitAt(RefPicList ref_list, int ref_idx, 70 | CuTree cu_tree, int posx, int posy) const; 71 | void SetRefPic(RefPicList ref_list, int index, PicNum ref_poc, 72 | const std::shared_ptr &pic_data, 73 | const std::shared_ptr &ref_pic, 74 | const std::shared_ptr &orig_pic); 75 | std::vector GetSamePocMappingFor(RefPicList ref_list) const; 76 | void ZeroOutReferences(); 77 | void Reset(PicNum current_poc); 78 | 79 | private: 80 | struct RefEntry { 81 | PicNum poc; 82 | std::shared_ptr ref_pic; 83 | std::shared_ptr orig_pic; 84 | std::shared_ptr data; 85 | }; 86 | std::vector l0_; 87 | std::vector l1_; 88 | PicNum current_poc_ = static_cast(-1); 89 | bool only_back_references_ = true; 90 | }; 91 | 92 | } // namespace xvc 93 | 94 | #endif // XVC_COMMON_LIB_REFERENCE_PICTURE_LISTS_H_ 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # xvc codec [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/divideon/xvc?branch=master&svg=true)](https://ci.appveyor.com/project/divideon/xvc) [![Travis Build Status](https://travis-ci.com/divideon/xvc.svg?branch=master)](https://travis-ci.com/divideon/xvc) 2 | 3 | The xvc codec is a next-generation software-defined video compression format, built using 4 | world-class compression technologies. 5 | 6 | The xvc software is available under a dual-licensing scheme with an LGPL option and a 7 | commercial option. 8 | 9 | Visit [xvc.io](https://xvc.io) for more information. 10 | 11 | The master branch represents the current official version of xvc. Development 12 | of new versions of xvc happens in the dev branch. 13 | 14 | ## Building instructions 15 | 16 | ### Prerequisites 17 | 18 | 1. [CMake](https://cmake.org) version 3.1 or higher. 19 | 2. [Git](https://git-scm.com/). 20 | 3. C++ compiler with C++11 support 21 | 22 | The following C++11 compilers have been known to work: 23 | 24 | * Visual Studio 2015 or later 25 | * GCC 4.8 or later 26 | * Clang 3.3 or later 27 | 28 | ### Linux build steps 29 | 30 | The following commands will checkout the project source code and create a 31 | directory called 'build' where the compiler output will be placed. 32 | CMake is then used for generating build files and compiling the xvc binaries. 33 | 34 | $ git clone https://github.com/divideon/xvc.git 35 | $ cd xvc 36 | $ mkdir build 37 | $ cd build 38 | $ cmake .. 39 | $ make 40 | 41 | This will create xvc encoder and decoder binaries in the xvc/build/app/ folder. 42 | 43 | ### Windows build steps 44 | 45 | The following commands will checkout the project source code and create a 46 | directory called 'build' where the compiler output will be placed. 47 | CMake is then used for generating build files and creating the Visual Studio 48 | solution. 49 | 50 | $ git clone https://github.com/divideon/xvc.git 51 | $ cd xvc 52 | $ mkdir build 53 | $ cd build 54 | $ cmake -G "Visual Studio 14 2015 Win64" .. 55 | 56 | The -G argument should be adjusted to match your version of Visual Studio and 57 | the target architecture. 58 | This will generate a Visual Studio solution called xvc.sln in the build folder. 59 | After building the solution, the xvc encoder and decoder binaries will be found 60 | in the xvc/build/app/Release/ folder. 61 | 62 | ## Testing the xvc codec 63 | 64 | ### Command line encoder and decoder 65 | 66 | For generating xvc bitstreams the following command shows typical usage: 67 | 68 | $ xvcenc -input-file input.yuv -input-width 1920 -input-height 1080 \ 69 | -framerate 30 -output-file mybitstream.xvc -qp 32 70 | 71 | For decoding an xvc bitstream use the xvcdec application: 72 | 73 | $ xvcdec -bitstream-file mybitstream.xvc -output-file decoded.yuv 74 | 75 | Both xvcenc and xvcdec supports reading and writing y4m output. 76 | 77 | Pipes can be used together with e.g. ffmpeg to stream y4m input to encoder: 78 | 79 | $ ffmpeg -i movie.mkv -f yuv4mpegpipe - | xvcenc -input-file - \ 80 | -qp 30 -output-file mybitstream.xvc 81 | 82 | On the decoder, pipes can also be used to stream decoded output fo ffplay: 83 | 84 | $ xvcdec -bitstream-file mybitstream.xvc -output-file - | ffplay -i - 85 | 86 | ### Command line syntax 87 | 88 | To show all available encoder arguments run: 89 | 90 | $ xvcenc -help 91 | 92 | For decoder arguments run: 93 | 94 | $ xvcdec -help 95 | 96 | ## Coding style 97 | 98 | The xvc source code follows the [Google C++ Style Guide]( 99 | https://google.github.io/styleguide/cppguide.html). 100 | 101 | ## Support 102 | 103 | For questions/comments please email support@xvc.io 104 | 105 | ## Contributing 106 | 107 | Patches are encouraged, and may be submitted by forking this project and 108 | submitting a pull request through GitHub. 109 | 110 | Please visit [xvc.io](https://xvc.io/developers) for more information on how 111 | to become an xvc contributor. 112 | 113 | -------------------------------------------------------------------------------- /src/xvc_common_lib/quantize.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_QUANTIZE_H_ 23 | #define XVC_COMMON_LIB_QUANTIZE_H_ 24 | 25 | #include 26 | #include 27 | 28 | #include "xvc_common_lib/common.h" 29 | #include "xvc_common_lib/picture_types.h" 30 | 31 | namespace xvc { 32 | 33 | class CodingUnit; 34 | 35 | class Qp { 36 | public: 37 | Qp(int qp, ChromaFormat chroma_format, int bitdepth, double lambda, 38 | int chroma_offset_table = 0, int chroma_offset_u = 0, 39 | int chroma_offset_v = 0); 40 | bool operator<(const Qp &qp) const { 41 | return qp_raw_[0] < qp.qp_raw_[0]; 42 | } 43 | bool operator<=(const Qp &qp) const { 44 | return qp_raw_[0] <= qp.qp_raw_[0]; 45 | } 46 | int GetQpRaw(YuvComponent comp) const { 47 | return qp_raw_[comp]; 48 | } 49 | int GetQpPer(YuvComponent comp) const { 50 | return qp_bitdepth_[comp] / kNumScalingListRem_; 51 | } 52 | int GetFwdScale(YuvComponent comp) const { 53 | return kFwdQuantScales_[qp_bitdepth_[comp] % kNumScalingListRem_]; 54 | } 55 | int GetInvScale(YuvComponent comp) const { 56 | return kInvQuantScales_[qp_bitdepth_[comp] % kNumScalingListRem_] 57 | << (qp_bitdepth_[comp] / kNumScalingListRem_); 58 | } 59 | double GetDistortionWeight(YuvComponent comp) const { 60 | return distortion_weight_[comp]; 61 | } 62 | double GetLambda() const { return lambda_[0]; } 63 | double GetLambdaSqrt() const { return lambda_sqrt_; } 64 | double GetLambdaScaled(YuvComponent comp) const { 65 | return lambda_[static_cast(comp)]; 66 | } 67 | 68 | private: 69 | static const int kChromaQpMax_ = 57; 70 | static const uint8_t kChromaScale_[kChromaQpMax_ + 1]; 71 | static const int kNumScalingListRem_ = 6; 72 | static const int kFwdQuantScales_[kNumScalingListRem_]; 73 | static const int kInvQuantScales_[kNumScalingListRem_]; 74 | static int ScaleChromaQp(int qp, ChromaFormat chroma_format, int bitdepth, 75 | int chroma_scaling_table, int offset); 76 | static double GetChromaDistWeight(int qp, ChromaFormat chroma_format, 77 | int chroma_scaling_table, int offset); 78 | 79 | std::array qp_raw_; 80 | std::array qp_bitdepth_; 81 | std::array distortion_weight_; 82 | std::array lambda_; 83 | double lambda_sqrt_; 84 | }; 85 | 86 | class Quantize { 87 | public: 88 | static const int kQuantShift = 14; 89 | static const int kIQuantShift = 6; 90 | 91 | void Inverse(YuvComponent comp, const Qp &qp, int width, int height, 92 | int bitdepth, const Coeff *in, ptrdiff_t in_stride, Coeff *out, 93 | ptrdiff_t out_stride); 94 | static int GetTransformShift(int width, int height, int bitdepth); 95 | }; 96 | 97 | } // namespace xvc 98 | 99 | #endif // XVC_COMMON_LIB_QUANTIZE_H_ 100 | -------------------------------------------------------------------------------- /test/xvc_test/resolution_test.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include 23 | 24 | #include "googletest/include/gtest/gtest.h" 25 | 26 | #include "xvc_test/decoder_helper.h" 27 | #include "xvc_test/encoder_helper.h" 28 | #include "xvc_test/yuv_helper.h" 29 | 30 | namespace { 31 | 32 | static constexpr int kQp = 27; 33 | static constexpr double kPsnrThreshold = 33.0; 34 | static constexpr int kFramesEncoded = 3; 35 | 36 | class ResolutionTest : public ::testing::TestWithParam, 37 | public ::xvc_test::EncoderHelper, public ::xvc_test::DecoderHelper { 38 | protected: 39 | void SetUp() override { 40 | EncoderHelper::Init(GetParam()); 41 | DecoderHelper::Init(); 42 | encoder_->SetSubGopLength(1); 43 | encoder_->SetQp(kQp); 44 | } 45 | 46 | void EncodeDecode(int width, int height) { 47 | std::vector orig_pics; 48 | encoder_->SetResolution(width, height); 49 | for (int poc = 0; poc < kFramesEncoded; poc++) { 50 | auto orig_pic = xvc_test::TestYuvPic(width, height, GetParam(), poc, poc); 51 | EncodeOneFrame(orig_pic.GetBytes(), orig_pic.GetBitdepth()); 52 | orig_pics.push_back(orig_pic); 53 | } 54 | // TODO(PH) Consider re-implementing without orig pic buffering 55 | // when we support low-delay decoding 56 | for (int poc = 0; poc < kFramesEncoded; poc++) { 57 | if (poc == 0) { 58 | DecodeSegmentHeaderSuccess(GetNextNalToDecode()); 59 | } 60 | if (DecodePictureSuccess(GetNextNalToDecode())) { 61 | auto &orig_pic = orig_pics.front(); 62 | double psnr = orig_pic.CalcPsnr(last_decoded_picture_.bytes); 63 | ASSERT_GE(psnr, kPsnrThreshold); 64 | orig_pics.erase(orig_pics.begin()); 65 | } 66 | } 67 | for (auto &orig_pic : orig_pics) { 68 | ASSERT_TRUE(DecoderFlushAndGet()); 69 | double psnr = orig_pic.CalcPsnr(last_decoded_picture_.bytes); 70 | ASSERT_GE(psnr, kPsnrThreshold); 71 | } 72 | ASSERT_FALSE(DecoderFlushAndGet()); 73 | } 74 | }; 75 | 76 | TEST_P(ResolutionTest, OddWidthx16) { 77 | EncodeDecode(xvc_test::TestYuvPic::kDefaultSize - 1, 16); 78 | } 79 | 80 | TEST_P(ResolutionTest, OddHeightx16) { 81 | EncodeDecode(16, xvc_test::TestYuvPic::kDefaultSize - 1); 82 | } 83 | 84 | TEST_P(ResolutionTest, Size8xN) { 85 | EncodeDecode(8, xvc_test::TestYuvPic::kDefaultSize); 86 | } 87 | 88 | TEST_P(ResolutionTest, SizeNx8) { 89 | EncodeDecode(xvc_test::TestYuvPic::kDefaultSize, 8); 90 | } 91 | 92 | TEST_P(ResolutionTest, Size24xN) { 93 | EncodeDecode(24, xvc_test::TestYuvPic::kDefaultSize); 94 | } 95 | 96 | TEST_P(ResolutionTest, SizeNx24) { 97 | EncodeDecode(xvc_test::TestYuvPic::kDefaultSize, 24); 98 | } 99 | 100 | INSTANTIATE_TEST_CASE_P(NormalBitdepth, ResolutionTest, 101 | ::testing::Values(8)); 102 | #if XVC_HIGH_BITDEPTH 103 | INSTANTIATE_TEST_CASE_P(HighBitdepth, ResolutionTest, 104 | ::testing::Values(10)); 105 | #endif 106 | 107 | } // namespace 108 | -------------------------------------------------------------------------------- /src/xvc_common_lib/utils.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "xvc_common_lib/utils.h" 23 | 24 | namespace xvc { 25 | 26 | namespace util { 27 | 28 | // TODO(dev) this should really be a lookup table 29 | int SizeToLog2(int size) { 30 | int log2 = 1; 31 | while ((1 << log2) < size) { 32 | log2++; 33 | } 34 | return log2; 35 | } 36 | 37 | // TODO(dev) this should really be a lookup table 38 | int SizeLog2Bits(int size) { 39 | int log2 = 1; 40 | while ((1 << log2) < size) { 41 | log2++; 42 | } 43 | return log2 - 2; 44 | } 45 | 46 | int Log2Floor(int x) { 47 | int log2 = 0; 48 | while (x > 1) { 49 | log2++; 50 | x >>= 1; 51 | } 52 | return log2; 53 | } 54 | 55 | int GetChromaShiftX(ChromaFormat chroma_format) { 56 | switch (chroma_format) { 57 | case ChromaFormat::kMonochrome: 58 | return 8; 59 | break; 60 | case ChromaFormat::k420: 61 | return 1; 62 | break; 63 | case ChromaFormat::k422: 64 | return 1; 65 | break; 66 | case ChromaFormat::k444: 67 | return 0; 68 | break; 69 | case ChromaFormat::kUndefined: 70 | default: 71 | assert(0); 72 | return 0; 73 | break; 74 | } 75 | } 76 | 77 | int GetChromaShiftY(ChromaFormat chroma_format) { 78 | switch (chroma_format) { 79 | case ChromaFormat::kMonochrome: 80 | return 8; 81 | break; 82 | case ChromaFormat::k420: 83 | return 1; 84 | break; 85 | case ChromaFormat::k422: 86 | return 0; 87 | break; 88 | case ChromaFormat::k444: 89 | return 0; 90 | break; 91 | case ChromaFormat::kUndefined: 92 | default: 93 | assert(0); 94 | return 0; 95 | break; 96 | } 97 | } 98 | 99 | int ScaleChromaX(int size, ChromaFormat chroma_format) { 100 | switch (chroma_format) { 101 | case ChromaFormat::kMonochrome: 102 | return 0; 103 | break; 104 | case ChromaFormat::k420: 105 | return size >> 1; 106 | break; 107 | case ChromaFormat::k422: 108 | return size >> 1; 109 | break; 110 | case ChromaFormat::k444: 111 | return size; 112 | break; 113 | case ChromaFormat::kArgb: 114 | return size; 115 | break; 116 | case ChromaFormat::kUndefined: 117 | default: 118 | assert(0); 119 | return 0; 120 | break; 121 | } 122 | } 123 | 124 | int ScaleChromaY(int size, ChromaFormat chroma_format) { 125 | switch (chroma_format) { 126 | case ChromaFormat::kMonochrome: 127 | return 0; 128 | break; 129 | case ChromaFormat::k420: 130 | return size >> 1; 131 | break; 132 | case ChromaFormat::k422: 133 | return size; 134 | break; 135 | case ChromaFormat::k444: 136 | return size; 137 | break; 138 | case ChromaFormat::kArgb: 139 | return size; 140 | break; 141 | case ChromaFormat::kUndefined: 142 | default: 143 | assert(0); 144 | return 0; 145 | break; 146 | } 147 | } 148 | 149 | } // namespace util 150 | 151 | } // namespace xvc 152 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/encoder_settings.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_ENCODER_SETTINGS_H_ 23 | #define XVC_ENC_LIB_ENCODER_SETTINGS_H_ 24 | 25 | #include 26 | #include 27 | 28 | #include "xvc_common_lib/restrictions.h" 29 | 30 | namespace xvc { 31 | 32 | enum struct SpeedMode { 33 | kPlacebo = 0, 34 | kSlow = 1, 35 | kFast = 2, 36 | kTotalNumber = 3, 37 | }; 38 | 39 | enum struct TuneMode { 40 | kDefault = 0, 41 | kPsnr = 1, 42 | kTotalNumber = 2, 43 | }; 44 | 45 | struct EncoderSettings { 46 | void Initialize(SpeedMode speed_mode); 47 | void Initialize(RestrictedMode mode); 48 | void Tune(TuneMode tune_mode); 49 | void ParseExplicitSettings(std::string explicit_settings); 50 | 51 | // Encoder rdo behavior 52 | static constexpr bool kEncoderStrictRdoBitCounting = false; 53 | static constexpr bool kEncoderCountActualWrittenBits = true; 54 | static_assert(EncoderSettings::kEncoderCountActualWrittenBits || 55 | EncoderSettings::kEncoderStrictRdoBitCounting, 56 | "Fast bit counting should use strict rdo bit signaling"); 57 | 58 | // Fast encoder decisions (always used) 59 | static const bool rdo_quant = true; 60 | static const bool fast_cu_split_based_on_full_cu = true; 61 | static const bool fast_mode_selection_for_cached_cu = true; 62 | static const bool skip_mode_decision_for_identical_cu = false; 63 | static const bool fast_inter_transform_dist = true; // not really any impact 64 | static const bool fast_inter_root_cbf_zero_bits = false; // very small loss 65 | static const int inter_search_range_bi = 4; 66 | 67 | // Speed mode dependent settings 68 | int inter_search_range_uni_max = 256; 69 | int inter_search_range_uni_min = 96; 70 | int bipred_refinement_iterations = -1; 71 | int always_evaluate_intra_in_inter = -1; 72 | int default_num_ref_pics = -1; 73 | int max_binary_split_depth = -1; 74 | int fast_transform_select_eval = -1; 75 | int fast_intra_mode_eval_level = -1; 76 | int fast_transform_size_64 = -1; 77 | int fast_transform_select = -1; 78 | int fast_inter_local_illumination_comp = -1; 79 | int fast_inter_adaptive_fullpel_mv = -1; 80 | 81 | // Settings with default values used in all speed modes 82 | int fast_merge_eval = 1; 83 | int fast_quad_split_based_on_binary_split = 1; 84 | int eval_prev_mv_search_result = 1; 85 | int fast_inter_pred_bits = 0; 86 | int rdo_quant_2x2 = 1; 87 | int intra_qp_offset = 0; 88 | int smooth_lambda_scaling = 1; 89 | int adaptive_qp = 2; 90 | int aqp_strength = 13; 91 | int structural_ssd = 1; 92 | int structural_strength = 16; 93 | int encapsulation_mode = 0; 94 | int leading_pictures = 0; 95 | int source_padding = 1; 96 | int chroma_qp_offset_table = 1; 97 | int chroma_qp_offset_u = 0; 98 | int chroma_qp_offset_v = 0; 99 | int flat_lambda = 0; 100 | float lambda_scale_a = 1.0f; 101 | float lambda_scale_b = 0.0f; 102 | RestrictedMode restricted_mode = RestrictedMode::kUnrestricted; 103 | }; 104 | 105 | } // namespace xvc 106 | 107 | #endif // XVC_ENC_LIB_ENCODER_SETTINGS_H_ 108 | -------------------------------------------------------------------------------- /src/xvc_common_lib/yuv_pic.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_YUV_PIC_H_ 23 | #define XVC_COMMON_LIB_YUV_PIC_H_ 24 | 25 | #include 26 | 27 | #include "xvc_common_lib/common.h" 28 | #include "xvc_common_lib/sample_buffer.h" 29 | 30 | namespace xvc { 31 | 32 | struct PictureFormat { 33 | PictureFormat() = default; 34 | PictureFormat(int _width, int _height, int _bitdepth, 35 | ChromaFormat _chroma_format, ColorMatrix _color_matrix, 36 | bool _dither) 37 | : width(_width), 38 | height(_height), 39 | bitdepth(_bitdepth), 40 | chroma_format(_chroma_format), 41 | color_matrix(_color_matrix), 42 | dither(_dither) { 43 | } 44 | int width = 0; 45 | int height = 0; 46 | int bitdepth = 0; 47 | ChromaFormat chroma_format = ChromaFormat::kUndefined; 48 | ColorMatrix color_matrix = ColorMatrix::kUndefined; 49 | bool dither = false; 50 | }; 51 | 52 | class YuvPicture { 53 | public: 54 | YuvPicture(const PictureFormat &pic_fmt, bool padding, 55 | int crop_width, int crop_height) 56 | : YuvPicture(pic_fmt.chroma_format, pic_fmt.width, pic_fmt.height, 57 | pic_fmt.bitdepth, padding, crop_width, crop_height) { 58 | } 59 | YuvPicture(ChromaFormat chroma_format, int width, int height, int bitdepth, 60 | bool padding, int crop_width, int crop_height); 61 | 62 | int GetWidth(YuvComponent comp) const { return width_[comp]; } 63 | int GetHeight(YuvComponent comp) const { return height_[comp]; } 64 | ptrdiff_t GetStride(YuvComponent comp) const { return stride_[comp]; } 65 | int GetTotalHeight(YuvComponent comp) const { return total_height_[comp]; } 66 | int GetSizeShiftX(YuvComponent comp) const { return shiftx_[comp]; } 67 | int GetSizeShiftY(YuvComponent comp) const { return shifty_[comp]; } 68 | int GetBitdepth() const { return bitdepth_; } 69 | size_t GetTotalSamples() const { return sample_buffer_.size(); } 70 | ChromaFormat GetChromaFormat() const { return chroma_format_; } 71 | int GetCropWidth() const { return crop_width_; } 72 | int GetCropHeight() const { return crop_height_; } 73 | int GetDisplayWidth(YuvComponent comp) const; 74 | int GetDisplayHeight(YuvComponent comp) const; 75 | 76 | Sample* GetSamplePtr(YuvComponent comp, int x, int y) { 77 | return comp_pel_[comp] + y * GetStride(comp) + x; 78 | } 79 | const Sample* GetSamplePtr(YuvComponent comp, int x, int y) const { 80 | return comp_pel_[comp] + y * GetStride(comp) + x; 81 | } 82 | SampleBuffer GetSampleBuffer(YuvComponent comp, int x, int y) { 83 | return SampleBuffer(GetSamplePtr(comp, x, y), GetStride(comp)); 84 | } 85 | SampleBufferConst GetSampleBuffer(YuvComponent comp, int x, int y) const { 86 | return SampleBufferConst(GetSamplePtr(comp, x, y), GetStride(comp)); 87 | } 88 | void CopyToSameBitdepth(std::vector *pic_bytes) const; 89 | void PadBorder(); 90 | 91 | private: 92 | ChromaFormat chroma_format_; 93 | int width_[constants::kMaxYuvComponents]; 94 | int height_[constants::kMaxYuvComponents]; 95 | ptrdiff_t stride_[constants::kMaxYuvComponents]; 96 | int total_height_[constants::kMaxYuvComponents]; 97 | int shiftx_[constants::kMaxYuvComponents]; 98 | int shifty_[constants::kMaxYuvComponents]; 99 | int bitdepth_; 100 | int crop_width_; 101 | int crop_height_; 102 | std::vector sample_buffer_; 103 | Sample *comp_pel_[constants::kMaxYuvComponents]; 104 | }; 105 | 106 | } // namespace xvc 107 | 108 | #endif // XVC_COMMON_LIB_YUV_PIC_H_ 109 | -------------------------------------------------------------------------------- /src/xvc_common_lib/intra_prediction.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_INTRA_PREDICTION_H_ 23 | #define XVC_COMMON_LIB_INTRA_PREDICTION_H_ 24 | 25 | #include 26 | 27 | #include "xvc_common_lib/coding_unit.h" 28 | #include "xvc_common_lib/common.h" 29 | 30 | namespace xvc { 31 | 32 | struct IntraPredictorLuma : std::array { 33 | int num_neighbor_modes = 0; 34 | }; 35 | using IntraPredictorChroma = std::array; 37 | 38 | class IntraPrediction { 39 | public: 40 | static const ptrdiff_t kRefSampleStride_ = constants::kMaxBlockSize * 2 + 1; 41 | struct RefState { 42 | std::array ref_samples; 43 | std::array ref_filtered; 44 | }; 45 | 46 | explicit IntraPrediction(int bitdepth); 47 | void Predict(IntraMode intra_mode, const CodingUnit &cu, YuvComponent comp, 48 | const RefState &ref_state, const YuvPicture &rec_pic, 49 | SampleBuffer *output_buffer); 50 | void FillReferenceState(const CodingUnit &cu, YuvComponent comp, 51 | const YuvPicture &rec_pic, RefState *ref_state); 52 | IntraPredictorLuma GetPredictorLuma(const CodingUnit &cu) const; 53 | IntraPredictorChroma GetPredictorsChroma(IntraMode luma_mode) const; 54 | static IntraMode Convert(IntraAngle angle); 55 | static IntraChromaMode Convert(IntraChromaAngle chroma_angle); 56 | 57 | private: 58 | static const int kDownscaleLumaPadding = sizeof(int) / (1 * sizeof(Sample)); 59 | struct NeighborState; 60 | struct LmParams; 61 | void FillPredictorLumaDefault(const CodingUnit &cu, 62 | IntraPredictorLuma *predictors) const; 63 | bool UseFilteredRefSamples(const CodingUnit &cu, IntraMode intra_mode); 64 | void PredIntraDC(int width, int height, bool dc_filter, 65 | const Sample *ref_samples, ptrdiff_t ref_stride, 66 | Sample *output_buffer, ptrdiff_t output_stride); 67 | void PlanarPred(int width, int height, 68 | const Sample *ref_samples, ptrdiff_t ref_stride, 69 | Sample *output_buffer, ptrdiff_t output_stride); 70 | void AngularPred(int width, int height, IntraMode mode, bool filter, 71 | const Sample *ref_samples, ptrdiff_t ref_stride, 72 | Sample *output_buffer, ptrdiff_t output_stride); 73 | void PredLmChroma(const CodingUnit &cu, YuvComponent comp, 74 | const YuvPicture &rec_pic, SampleBuffer *output_buffer); 75 | LmParams DeriveLmParams(const CodingUnit &cu, YuvComponent comp, 76 | const SampleBufferConst &comp_src, 77 | const SampleBufferConst &luma_src); 78 | NeighborState DetermineNeighbors(const CodingUnit &cu, YuvComponent comp); 79 | void ComputeRefSamples(int width, int height, 80 | const NeighborState &neighbors, 81 | const Sample *input, ptrdiff_t input_stride, 82 | Sample *output, ptrdiff_t output_stride); 83 | void FilterRefSamples(int width, int height, const Sample *src_ref, 84 | Sample *dst_ref, ptrdiff_t stride); 85 | void RescaleLuma(const CodingUnit &cu, int src_width, int src_height, 86 | const SampleBufferConst &src_buffer, 87 | int out_width, int out_height, SampleBuffer *out_buffer); 88 | 89 | const Restrictions restrictions_; 90 | int bitdepth_; 91 | SampleBufferStorage temp_pred_buffer_; 92 | }; 93 | 94 | } // namespace xvc 95 | 96 | #endif // XVC_COMMON_LIB_INTRA_PREDICTION_H_ 97 | -------------------------------------------------------------------------------- /src/xvc_dec_lib/entropy_decoder.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "xvc_dec_lib/entropy_decoder.h" 23 | 24 | #include "xvc_common_lib/cabac.h" 25 | 26 | namespace xvc { 27 | 28 | template 29 | EntropyDecoder::EntropyDecoder(BitReader *bit_reader) 30 | : bit_reader_(bit_reader) { 31 | range_ = 510; 32 | bits_needed_ = -24; 33 | value_ = 0; 34 | } 35 | 36 | template 37 | uint32_t EntropyDecoder::DecodeBin(Ctx *ctx) { 38 | uint32_t ctxmps = ctx->GetMps(); 39 | uint32_t lps = ctx->GetLps(range_); 40 | 41 | range_ -= lps; 42 | uint32_t scaled_range = range_ << 7; 43 | 44 | uint32_t binval; 45 | int num_bits; 46 | if (value_ < scaled_range) { 47 | binval = ctxmps; 48 | ctx->UpdateMPS(); 49 | num_bits = (scaled_range < (256 << 7)) ? 1 : 0; 50 | } else { 51 | binval = 1 - ctxmps; 52 | value_ -= scaled_range; 53 | range_ = lps; 54 | ctx->UpdateLPS(); 55 | num_bits = ctx->GetRenormBitsLps(lps); 56 | } 57 | 58 | value_ <<= num_bits; 59 | range_ <<= num_bits; 60 | bits_needed_ += num_bits; 61 | 62 | if (bits_needed_ >= 0) { 63 | value_ |= bit_reader_->ReadByte() << bits_needed_; 64 | bits_needed_ -= 8; 65 | } 66 | return binval; 67 | } 68 | 69 | template 70 | uint32_t EntropyDecoder::DecodeBypass() { 71 | value_ += value_; 72 | 73 | if (++bits_needed_ >= 0) { 74 | bits_needed_ = -8; 75 | value_ += bit_reader_->ReadByte(); 76 | } 77 | 78 | uint32_t binval = 0; 79 | uint32_t scaled_range = range_ << 7; 80 | if (value_ >= scaled_range) { 81 | binval = 1; 82 | value_ -= scaled_range; 83 | } 84 | return binval; 85 | } 86 | 87 | template 88 | uint32_t EntropyDecoder::DecodeBypassBins(int num_bins) { 89 | uint32_t bins = 0; 90 | while (num_bins > 8) { 91 | value_ = (value_ << 8) + (bit_reader_->ReadByte() << (8 + bits_needed_)); 92 | uint32_t scaled_range = range_ << 15; 93 | for (int i = 0; i < 8; i++) { 94 | bins += bins; 95 | scaled_range >>= 1; 96 | if (value_ >= scaled_range) { 97 | bins++; 98 | value_ -= scaled_range; 99 | } 100 | } 101 | num_bins -= 8; 102 | } 103 | bits_needed_ += num_bins; 104 | value_ <<= num_bins; 105 | 106 | if (bits_needed_ >= 0) { 107 | value_ += bit_reader_->ReadByte() << bits_needed_; 108 | bits_needed_ -= 8; 109 | } 110 | 111 | uint32_t scaled_range = range_ << (num_bins + 7); 112 | for (int i = 0; i < num_bins; i++) { 113 | bins += bins; 114 | scaled_range >>= 1; 115 | if (value_ >= scaled_range) { 116 | bins++; 117 | value_ -= scaled_range; 118 | } 119 | } 120 | return bins; 121 | } 122 | 123 | template 124 | uint32_t EntropyDecoder::DecodeBinTrm() { 125 | range_ -= 2; 126 | uint32_t scaled_range = range_ << 7; 127 | if (value_ >= scaled_range) { 128 | bit_reader_->Rewind(-bits_needed_); 129 | return 1; 130 | } 131 | if (scaled_range < (256 << 7)) { 132 | range_ = scaled_range >> 6; 133 | value_ <<= 1; 134 | if (++bits_needed_ == 0) { 135 | bits_needed_ = -8; 136 | value_ += bit_reader_->ReadByte(); 137 | } 138 | } 139 | return 0; 140 | } 141 | 142 | template 143 | void EntropyDecoder::Start() { 144 | range_ = 510; 145 | bits_needed_ = -8; 146 | value_ = (bit_reader_->ReadByte() << 8); 147 | value_ |= bit_reader_->ReadByte(); 148 | } 149 | 150 | template 151 | void EntropyDecoder::Finish() { 152 | bit_reader_->ReadBits(1); 153 | bit_reader_->SkipBits(); 154 | } 155 | 156 | template class EntropyDecoder; 157 | template class EntropyDecoder; 158 | 159 | } // namespace xvc 160 | -------------------------------------------------------------------------------- /src/xvc_common_lib/segment_header.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_SEGMENT_HEADER_H_ 23 | #define XVC_COMMON_LIB_SEGMENT_HEADER_H_ 24 | 25 | #include "xvc_common_lib/common.h" 26 | #include "xvc_common_lib/checksum.h" 27 | #include "xvc_common_lib/restrictions.h" 28 | #include "xvc_common_lib/yuv_pic.h" 29 | 30 | namespace xvc { 31 | 32 | enum class DeblockingMode { 33 | kDisabled = 0, 34 | kEnabled = 1, 35 | kPerPicture = 2, 36 | kCustom = 3, 37 | }; 38 | 39 | struct SegmentHeader { 40 | static PicNum CalcDocFromPoc(PicNum poc, PicNum sub_gop_length, 41 | PicNum sub_gop_start_poc_); 42 | static PicNum CalcPocFromDoc(PicNum doc, PicNum sub_gop_length, 43 | PicNum sub_gop_start_poc_); 44 | static int CalcTidFromDoc(PicNum doc, PicNum sub_gop_length, 45 | PicNum sub_gop_start_poc_); 46 | static int GetMaxTid(PicNum sub_gop_length); 47 | static int GetFramerateMaxTid(int decoder_ticks, int bitstream_ticks, 48 | PicNum sub_gop_length); 49 | static double GetFramerate(int max_tid, int bitstream_ticks, 50 | PicNum sub_gop_length); 51 | void SetWidth(int output_width) { 52 | output_pic_width_ = output_width; 53 | internal_pic_width_ = constants::kMinCuSize * 54 | ((output_width + constants::kMinCuSize - 1) / constants::kMinCuSize); 55 | } 56 | int GetOutputWidth() const { return output_pic_width_; } 57 | int GetInternalWidth() const { return internal_pic_width_; } 58 | void SetHeight(int output_height) { 59 | output_pic_height_ = output_height; 60 | internal_pic_height_ = constants::kMinCuSize * 61 | ((output_height + constants::kMinCuSize - 1) / constants::kMinCuSize); 62 | } 63 | int GetOutputHeight() const { return output_pic_height_; } 64 | int GetInternalHeight() const { return internal_pic_height_; } 65 | PictureFormat GetInternalPicFormat() const { 66 | return PictureFormat(internal_pic_width_, internal_pic_height_, 67 | internal_bitdepth, chroma_format, color_matrix, false); 68 | } 69 | int GetCropWidth() const { 70 | return !source_padding ? 0 : internal_pic_width_ - output_pic_width_; 71 | } 72 | int GetCropHeight() const { 73 | return !source_padding ? 0 : internal_pic_height_ - output_pic_height_; 74 | } 75 | 76 | uint32_t codec_identifier = static_cast(-1); 77 | uint32_t major_version = static_cast(-1); 78 | uint32_t minor_version = static_cast(-1); 79 | SegmentNum soc = static_cast(-1); 80 | ChromaFormat chroma_format = ChromaFormat::kUndefined; 81 | ColorMatrix color_matrix = ColorMatrix::kUndefined; 82 | int internal_bitdepth = -1; 83 | int bitstream_ticks = 0; 84 | PicNum max_sub_gop_length = 0; 85 | bool open_gop = false; 86 | bool low_delay = false; 87 | int leading_pictures = 0; 88 | int num_ref_pics = 0; 89 | int max_binary_split_depth = -1; 90 | Checksum::Mode checksum_mode = Checksum::Mode::kInvalid; 91 | bool source_padding = false; 92 | int adaptive_qp = -1; 93 | int chroma_qp_offset_table = -1; 94 | int chroma_qp_offset_u = 0; 95 | int chroma_qp_offset_v = 0; 96 | DeblockingMode deblocking_mode = DeblockingMode::kDisabled; 97 | int beta_offset = 0; 98 | int tc_offset = 0; 99 | Restrictions restrictions; 100 | 101 | private: 102 | int output_pic_width_ = 0; 103 | int output_pic_height_ = 0; 104 | int internal_pic_width_ = 0; 105 | int internal_pic_height_ = 0; 106 | static PicNum DocToPoc(PicNum sub_gop_length, PicNum doc); 107 | static PicNum PocToDoc(PicNum sub_gop_length, PicNum poc); 108 | static int DocToTid(PicNum sub_gop_length, PicNum doc); 109 | }; 110 | 111 | } // namespace xvc 112 | 113 | #endif // XVC_COMMON_LIB_SEGMENT_HEADER_H_ 114 | -------------------------------------------------------------------------------- /src/xvc_common_lib/common.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_COMMON_H_ 23 | #define XVC_COMMON_LIB_COMMON_H_ 24 | 25 | #include 26 | #include 27 | 28 | #ifndef XVC_HIGH_BITDEPTH 29 | #define XVC_HIGH_BITDEPTH 1 30 | #endif 31 | 32 | namespace xvc { 33 | 34 | #if !XVC_HIGH_BITDEPTH 35 | typedef uint8_t Sample; 36 | #else 37 | typedef uint16_t Sample; 38 | #endif 39 | typedef int16_t Coeff; 40 | typedef int16_t Residual; 41 | typedef uint64_t Cost; 42 | typedef uint64_t Distortion; 43 | typedef uint32_t Bits; 44 | typedef uint64_t PicNum; 45 | typedef uint8_t SegmentNum; 46 | 47 | enum class ChromaFormat : uint8_t { 48 | kMonochrome = 0, 49 | k420 = 1, 50 | k422 = 2, 51 | k444 = 3, 52 | kArgb = 4, 53 | kUndefined = 255, 54 | }; 55 | 56 | enum class ColorMatrix : uint8_t { 57 | kUndefined = 0, 58 | k601 = 1, 59 | k709 = 2, 60 | k2020 = 3, 61 | }; 62 | 63 | enum YuvComponent { 64 | kY = 0, 65 | kU = 1, 66 | kV = 2, 67 | }; 68 | 69 | enum class CuTree { 70 | Primary = 0, 71 | Secondary = 1, 72 | }; 73 | 74 | namespace constants { 75 | 76 | // xvc version 77 | const uint32_t kXvcCodecIdentifier = 7894627; 78 | const uint32_t kXvcMajorVersion = 2; 79 | const uint32_t kXvcMinorVersion = 0; 80 | static const uint32_t kSupportedOldBitstreamVersions[1][2] = { { 1, 0 } }; 81 | 82 | // Picture 83 | const int kMaxYuvComponents = 3; 84 | const int kMaxNumPlanes = 2; // luma and chroma 85 | const int kMaxNumCuTrees = 2; 86 | 87 | // CU limits 88 | const int kCtuSizeLog2 = 6; 89 | const int kCtuSize = 1 << kCtuSizeLog2; 90 | // CU size and depth for luma 91 | const int kMaxCuDepth = 3; 92 | const int kMaxCuDepthChroma = kMaxCuDepth + 1; 93 | const int kMinCuSize = (kCtuSize >> kMaxCuDepth); 94 | // Binary split 95 | const int kMaxBinarySplitDepth = 3; 96 | const int kMaxBinarySplitSizeInter = kCtuSize; 97 | const int kMaxBinarySplitSizeIntra1 = 32; 98 | const int kMaxBinarySplitSizeIntra2 = 16; 99 | const int kMinBinarySplitSize = 4; 100 | 101 | // Actual storage required (to allow for deeper chroma CU trees) 102 | const int kMaxBlockSize = kCtuSize; 103 | const int kMaxBlockDepthLuma = kMaxCuDepth + kMaxBinarySplitDepth; 104 | const int kMaxBlockDepthChroma = kMaxCuDepthChroma + kMaxBinarySplitDepth; 105 | const int kMaxBlockDepth = kMaxBlockDepthLuma > kMaxBlockDepthChroma ? 106 | kMaxBlockDepthLuma : kMaxBlockDepthChroma; 107 | const int kMinBlockSize = 4; 108 | const int kMaxBlockSamples = kMaxBlockSize * kMaxBlockSize; 109 | 110 | const int kQuadSplit = 4; 111 | 112 | // Transform 113 | const int kTransformSkipMaxArea = 4 * 4; 114 | const int kTransformSelectMinSigCoeffs = 3; 115 | const int kTransformZeroOutMinSize = 32; 116 | const int kMaxTransformSelectIdx = 4; 117 | 118 | // Prediction 119 | const int kNumIntraMpm = 3; 120 | const int kNumIntraMpmExt = 6; 121 | const int kNumInterMvPredictors = 2; 122 | const int kNumInterMergeCandidates = 5; 123 | const bool kTemporalMvPrediction = true; 124 | 125 | // Quant 126 | const int kMaxTrDynamicRange = 15; 127 | const int kMinAllowedQp = -64; 128 | const int kMaxAllowedQp = 63; 129 | const int kMaxQpDiff = 16; 130 | const int kQpSignalBase = 64; 131 | const int kChromaOffsetBits = 6; 132 | 133 | // Residual coding 134 | const int kMaxNumC1Flags = 8; 135 | const int kMaxNumC2Flags = 1; 136 | const int kSubblockShift = 2; 137 | const uint32_t kCoeffRemainBinReduction = 3; 138 | const int kSignHidingThreshold = 3; 139 | 140 | // Deblocking 141 | const int kDeblockOffsetBits = 6; 142 | 143 | // Maximum number of reference pictures per reference picture list 144 | const int kMaxNumRefPics = 5; 145 | 146 | // High-level syntax 147 | const int kTimeScale = 90000; 148 | const int kMaxTid = 8; 149 | const int kFrameRateBitDepth = 24; 150 | const int kPicSizeBits = 16; 151 | const PicNum kMaxSubGopLength = 64; 152 | const int kEncapsulationCode = 86; 153 | 154 | // Min and Max 155 | const int16_t kInt16Max = INT16_MAX; 156 | const int16_t kInt16Min = INT16_MIN; 157 | 158 | } // namespace constants 159 | 160 | } // namespace xvc 161 | 162 | #endif // XVC_COMMON_LIB_COMMON_H_ 163 | -------------------------------------------------------------------------------- /app/xvc_enc_app/encoder_app.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_APP_ENCODER_APP_H_ 23 | #define XVC_ENC_APP_ENCODER_APP_H_ 24 | 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "xvc_enc_lib/xvcenc.h" 35 | 36 | namespace xvc_app { 37 | 38 | class EncoderApp { 39 | public: 40 | EncoderApp(); 41 | ~EncoderApp(); 42 | void ReadArguments(int argc, const char *argv[]); 43 | void CheckParameters(); 44 | void PrintEncoderSettings(); 45 | void MainEncoderLoop(); 46 | void PrintStatistics(); 47 | 48 | private: 49 | xvc_enc_return_code ConfigureApiParams(xvc_encoder_parameters *params); 50 | std::pair EncodeOnePass(xvc_encoder_parameters *params, 51 | bool last = false); 52 | void StartPictureDetermination(xvc_encoder_parameters *out_params); 53 | void MultiPass(xvc_encoder_parameters *out_params); 54 | void ResetStreams(); 55 | bool ReadNextPicture(std::vector *picture_bytes); 56 | void PrintUsage(); 57 | void PrintNalInfo(xvc_enc_nal_unit nal_unit); 58 | 59 | std::istream *input_stream_ = nullptr; 60 | bool input_seekable_ = true; 61 | std::ifstream file_input_stream_; 62 | std::ofstream file_output_stream_; 63 | std::ofstream rec_stream_; 64 | std::streamoff start_skip_; 65 | std::streamoff picture_skip_; 66 | std::streamsize input_file_size_; 67 | 68 | int picture_index_ = 0; 69 | size_t total_bytes_ = 0; 70 | size_t max_segment_bytes_ = 0; 71 | int max_segment_pics_ = 0; 72 | double sum_psnr_y_ = 0; 73 | double sum_psnr_u_ = 0; 74 | double sum_psnr_v_ = 0; 75 | 76 | // command line arguments 77 | struct { 78 | std::string input_filename; 79 | std::string output_filename; 80 | std::string rec_file; 81 | int width = 0; 82 | int height = 0; 83 | xvc_enc_chroma_format chroma_format = XVC_ENC_CHROMA_FORMAT_UNDEFINED; 84 | xvc_enc_color_matrix color_matrix = XVC_ENC_COLOR_MATRIX_UNDEFINED; 85 | int input_bitdepth = 0; 86 | int internal_bitdepth = 0; 87 | double framerate = 0; 88 | int skip_pictures = 0; 89 | int temporal_subsample = -1; 90 | int max_num_pictures = -1; 91 | int sub_gop_length = -1; 92 | int max_keypic_distance = -1; 93 | int closed_gop = -1; 94 | int low_delay = -1; 95 | int num_ref_pics = -1; 96 | int restricted_mode = -1; 97 | int checksum_mode = -1; 98 | int chroma_qp_offset_table = -1; 99 | int chroma_qp_offset_u = std::numeric_limits::min(); 100 | int chroma_qp_offset_v = std::numeric_limits::min(); 101 | int deblock = -1; 102 | int beta_offset = std::numeric_limits::min(); 103 | int tc_offset = std::numeric_limits::min(); 104 | int qp = -1; 105 | int flat_lambda = -1; 106 | int multipass_rd = 0; 107 | int speed_mode = -1; 108 | int tune_mode = -1; 109 | int threads = -1; 110 | int profile = -1; 111 | int simd_mask = -1; 112 | std::string explicit_encoder_settings; 113 | int verbose = 0; 114 | } cli_; 115 | 116 | const xvc_encoder_api *xvc_api_ = nullptr; 117 | xvc_encoder_parameters *params_ = nullptr; 118 | xvc_encoder *encoder_ = nullptr; 119 | xvc_enc_pic_buffer rec_pic_buffer_ = { 0, 0 }; 120 | std::vector picture_bytes_; 121 | 122 | std::chrono::time_point start_; 123 | std::chrono::time_point end_; 124 | }; 125 | 126 | class LambdaCurve { 127 | public: 128 | LambdaCurve(const std::pair &p0, int qp0, 129 | const std::pair &p1, int qp1); 130 | LambdaCurve(const LambdaCurve &curve, 131 | const std::pair &p, int qp); 132 | bool IsPointBetter(const std::pair &p); 133 | double GetQpAtDistortion(uint64_t distortion); 134 | 135 | private: 136 | double dist_scale_; 137 | double dist_offset_; 138 | double qp_scale_; 139 | double qp_offset_; 140 | }; 141 | 142 | } // namespace xvc_app 143 | 144 | #endif // XVC_ENC_APP_ENCODER_APP_H_ 145 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/syntax_writer.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_SYNTAX_WRITER_H_ 23 | #define XVC_ENC_LIB_SYNTAX_WRITER_H_ 24 | 25 | #include "xvc_common_lib/cabac.h" 26 | #include "xvc_common_lib/coding_unit.h" 27 | #include "xvc_common_lib/intra_prediction.h" 28 | #include "xvc_common_lib/picture_types.h" 29 | #include "xvc_common_lib/quantize.h" 30 | #include "xvc_common_lib/transform.h" 31 | #include "xvc_enc_lib/entropy_encoder.h" 32 | 33 | namespace xvc { 34 | 35 | using Contexts = CabacContexts; 36 | 37 | class SyntaxWriter { 38 | public: 39 | SyntaxWriter(const Qp &qp, PicturePredictionType pic_type, 40 | BitWriter *bit_writer); 41 | SyntaxWriter(const Contexts &contexts, EntropyEncoder &&entropyenc); 42 | const Contexts& GetContexts() const { return ctx_; } 43 | Bits GetNumWrittenBits() const { 44 | return encoder_.GetNumWrittenBits(); 45 | } 46 | Bits GetFractionalBits() const { 47 | return encoder_.GetFractionalBits(); 48 | } 49 | void ResetBitCounting() { encoder_.ResetBitCounting(); } 50 | void Finish(); 51 | 52 | void WriteAffineFlag(const CodingUnit &cu, bool is_merge, bool use_affine); 53 | void WriteCbf(const CodingUnit &cu, YuvComponent comp, bool cbf); 54 | int WriteCoefficients(const CodingUnit &cu, YuvComponent comp, 55 | const Coeff *coeff, ptrdiff_t coeff_stride); 56 | void WriteEndOfSlice(bool end_of_slice); 57 | void WriteInterDir(const CodingUnit &cu, InterDir inter_dir); 58 | void WriteInterFullpelMvFlag(const CodingUnit &cu, bool fullpel_mv_only); 59 | void WriteInterMvd(const MvDelta &mvd); 60 | void WriteInterMvpIdx(const CodingUnit &cu, int mvp_idx); 61 | void WriteInterRefIdx(int ref_idx, int num_refs_available); 62 | void WriteIntraMode(IntraMode intra_mode, const IntraPredictorLuma &mpm); 63 | void WriteIntraChromaMode(IntraChromaMode chroma_mode, 64 | IntraPredictorChroma chroma_preds); 65 | void WriteLicFlag(bool use_lic); 66 | void WriteMergeFlag(bool merge); 67 | void WriteMergeIdx(int merge_idx); 68 | void WritePartitionType(const CodingUnit &cu, PartitionType type); 69 | void WritePredMode(PredictionMode pred_mode); 70 | void WriteQp(int qp_value, int predicted_qp, int aqp_mode); 71 | void WriteRootCbf(bool root_cbf); 72 | void WriteSkipFlag(const CodingUnit &cu, bool flag); 73 | void WriteSplitBinary(const CodingUnit &cu, 74 | SplitRestriction split_restriction, SplitType split); 75 | void WriteSplitQuad(const CodingUnit &cu, int max_depth, SplitType split); 76 | void WriteTransformSkip(const CodingUnit &cu, YuvComponent comp, 77 | bool tx_skip); 78 | void WriteTransformSelectEnable(const CodingUnit &cu, bool enable); 79 | void WriteTransformSelectIdx(const CodingUnit &cu, int type_idx); 80 | 81 | private: 82 | template 83 | int WriteCoeffSubblock(const CodingUnit &cu, YuvComponent comp, 84 | const Coeff *coeff, ptrdiff_t coeff_stride); 85 | void WriteCoeffLastPos(int width, int height, YuvComponent comp, 86 | ScanOrder scan_order, int last_pos_x, 87 | int last_pos_y); 88 | void WriteCoeffRemainExpGolomb(uint32_t abs_level, uint32_t golomb_rice_k); 89 | void WriteExpGolomb(uint32_t abs_level, uint32_t golomb_rice_k); 90 | void WriteUnaryMaxSymbol(uint32_t symbol, uint32_t max_val, 91 | ContextModel *ctx_start, ContextModel *ctx_rest); 92 | 93 | Contexts ctx_; 94 | EntropyEncoder encoder_; 95 | friend class RdoSyntaxWriter; 96 | }; 97 | 98 | class RdoSyntaxWriter : public SyntaxWriter { 99 | public: 100 | explicit RdoSyntaxWriter(const SyntaxWriter &writer); 101 | explicit RdoSyntaxWriter(const RdoSyntaxWriter &writer); 102 | RdoSyntaxWriter(const SyntaxWriter &writer, uint32_t bits_written); 103 | RdoSyntaxWriter(const SyntaxWriter &writer, uint32_t bits_written, 104 | uint32_t frac_bits); 105 | RdoSyntaxWriter& operator=(const RdoSyntaxWriter &writer); 106 | }; 107 | 108 | } // namespace xvc 109 | 110 | #endif // XVC_ENC_LIB_SYNTAX_WRITER_H_ 111 | -------------------------------------------------------------------------------- /test/xvc_test/decoder_scalability_test.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "googletest/include/gtest/gtest.h" 27 | 28 | #include "xvc_test/decoder_helper.h" 29 | #include "xvc_test/encoder_helper.h" 30 | #include "xvc_test/yuv_helper.h" 31 | 32 | using xvc_test::NalUnit; 33 | 34 | namespace { 35 | 36 | static const int kSubGopLength = 4; 37 | static const int kSegmentLength = 8; 38 | static const int qp = 32; 39 | 40 | class DecoderScalabilityTest : public ::testing::TestWithParam, 41 | public ::xvc_test::EncoderHelper, public ::xvc_test::DecoderHelper { 42 | protected: 43 | void SetUp() override { 44 | EncoderHelper::Init(); 45 | DecoderHelper::Init(); 46 | } 47 | 48 | std::vector EncodeBitstream(int width, int height, 49 | int internal_bitdepth, int frames) { 50 | const int input_bitdepth = 8; 51 | xvc::EncoderSettings encoder_settings = GetDefaultEncoderSettings(); 52 | encoder_settings.leading_pictures = GetParam() ? 1 : 0; 53 | SetupEncoder(encoder_settings, width, height, internal_bitdepth, qp); 54 | encoder_->SetSubGopLength(kSubGopLength); 55 | encoder_->SetSegmentLength(kSegmentLength); 56 | encoder_->SetClosedGopInterval(1000); // force open gop 57 | encoded_nal_units_.clear(); 58 | for (int i = 0; i < frames; i++) { 59 | auto orig_pic = xvc_test::TestYuvPic(width, height, input_bitdepth, i, i); 60 | EncodeOneFrame(orig_pic.GetBytes(), orig_pic.GetBitdepth()); 61 | } 62 | EncoderFlush(); 63 | return encoded_nal_units_; 64 | } 65 | 66 | int DecodeBitstream(int width, int height) { 67 | ResetBitstreamPosition(); 68 | DecodeSegmentHeaderSuccess(GetNextNalToDecode()); 69 | int decoded_pictures = 0; 70 | while (HasMoreNals()) { 71 | auto &nal = GetNextNalToDecode(); 72 | EXPECT_EQ(nal.size(), decoder_->DecodeNal(&nal[0], nal.size())); 73 | if (decoder_->GetDecodedPicture(&last_decoded_picture_)) { 74 | decoded_pictures++; 75 | } 76 | } 77 | while (DecoderFlushAndGet()) { 78 | decoded_pictures++; 79 | } 80 | return decoded_pictures; 81 | } 82 | }; 83 | 84 | TEST_P(DecoderScalabilityTest, ReferencePicDownscaling) { 85 | auto is_segment_header = [](const NalUnit &nal) { 86 | xvc::BitReader bit_reader(&nal[0], nal.size()); 87 | xvc::NalUnitType nal_type; 88 | EXPECT_TRUE(xvc::Decoder::ParseNalUnitHeader(&bit_reader, &nal_type, true)); 89 | return nal_type == xvc::NalUnitType::kSegmentHeader; 90 | }; 91 | std::vector bitstream1 = EncodeBitstream(16, 16, 8, 92 | 1 + 2 * kSegmentLength); 93 | std::vector bitstream2 = EncodeBitstream(24, 24, 8, 94 | 1 + 2 * kSegmentLength); 95 | encoded_nal_units_.clear(); 96 | 97 | // Copy first segment from bitstream 1 98 | auto it1 = std::find_if(bitstream1.begin() + 1, bitstream1.end(), 99 | is_segment_header); 100 | std::copy(bitstream1.begin(), it1, std::back_inserter(encoded_nal_units_)); 101 | 102 | // Copy second segment from bitstream 2 103 | auto it2 = std::find_if(bitstream2.begin() + 1, bitstream2.end(), 104 | is_segment_header); 105 | std::copy(it2, bitstream2.end(), std::back_inserter(encoded_nal_units_)); 106 | 107 | // Decode merged bitstream 108 | int decoded_pics = DecodeBitstream(16, 16); 109 | int expected_decoded_pics = 1 + 2 * kSegmentLength; 110 | // Half of pictures from 1st bitstream will be corrupted 111 | /// due to different reference picture 112 | int expected_corrupted_pics = kSubGopLength / 2; 113 | EXPECT_EQ(decoded_pics, expected_decoded_pics); 114 | // Number of corrupted pictures varies depending on qp and rdoq 115 | EXPECT_LE(decoder_->GetNumCorruptedPics(), expected_corrupted_pics + 1); 116 | EXPECT_GT(decoder_->GetNumCorruptedPics(), 0); 117 | } 118 | 119 | INSTANTIATE_TEST_CASE_P(LeadingPictures, DecoderScalabilityTest, 120 | ::testing::Bool()); 121 | 122 | } // namespace 123 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/transform_encoder.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_TRANSFORM_ENCODER_H_ 23 | #define XVC_ENC_LIB_TRANSFORM_ENCODER_H_ 24 | 25 | #include 26 | 27 | #include "xvc_common_lib/sample_buffer.h" 28 | #include "xvc_common_lib/quantize.h" 29 | #include "xvc_common_lib/transform.h" 30 | #include "xvc_common_lib/yuv_pic.h" 31 | #include "xvc_enc_lib/encoder_settings.h" 32 | #include "xvc_enc_lib/encoder_simd_functions.h" 33 | #include "xvc_enc_lib/rdo_quant.h" 34 | #include "xvc_enc_lib/sample_metric.h" 35 | #include "xvc_enc_lib/syntax_writer.h" 36 | #include "xvc_enc_lib/cu_writer.h" 37 | 38 | namespace xvc { 39 | 40 | enum class TxSearchFlags { 41 | kNone = 0, 42 | kNormalTx = 1 << 0, 43 | kCbfZero = 1 << 1, 44 | kTransformTskip = 1 << 2, 45 | kTransformSelect = 1 << 3, 46 | kFullEval = 0xFFFFFF, 47 | }; 48 | 49 | class TransformEncoder { 50 | public: 51 | struct RdCost { 52 | bool operator==(const RdCost &other) { return cost == other.cost; } 53 | bool operator<(const RdCost &other) { return cost < other.cost; } 54 | Cost cost; 55 | Distortion dist_reco; 56 | Distortion dist_resi; 57 | }; 58 | TransformEncoder(const EncoderSimdFunctions &simd, int bitdepth, 59 | int num_components, const YuvPicture &orig_pic, 60 | const EncoderSettings &encoder_settings); 61 | 62 | SampleBuffer& GetPredBuffer(YuvComponent comp) { 63 | return temp_pred_[static_cast(comp)]; 64 | } 65 | RdCost 66 | CompressAndEvalTransform(CodingUnit *cu, YuvComponent comp, 67 | const Qp &qp, const SyntaxWriter &writer, 68 | const YuvPicture &orig_pic, 69 | TxSearchFlags search_flags, const Cost *orig_cost, 70 | Distortion *out_dist_zero, CuWriter *cu_writer, 71 | YuvPicture *rec_pic); 72 | Distortion TransformAndReconstruct(CodingUnit *cu, YuvComponent comp, 73 | const Qp &qp, const SyntaxWriter &writer, 74 | const YuvPicture &orig_pic, 75 | YuvPicture *rec_pic); 76 | Bits GetCuBitsResidual(const CodingUnit &cu, const SyntaxWriter &writer, 77 | CuWriter *cu_writer); 78 | Bits GetCuBitsFull(const CodingUnit &cu, const SyntaxWriter &writer, 79 | CuWriter *cu_writer); 80 | 81 | private: 82 | void ReconstructZeroCbf(CodingUnit *cu, YuvComponent comp, 83 | const YuvPicture &orig_pic, YuvPicture *rec_pic); 84 | 85 | static const ptrdiff_t kBufferStride_ = constants::kMaxBlockSize; 86 | const EncoderSettings &encoder_settings_; 87 | const Sample min_pel_; 88 | const Sample max_pel_; 89 | const int num_components_; 90 | SampleMetric cu_metric_; 91 | InverseTransform inv_transform_; 92 | ForwardTransform fwd_transform_; 93 | Quantize inv_quant_; 94 | RdoQuant fwd_quant_; 95 | CodingUnit::ResidualState best_cu_state_; 96 | std::array temp_pred_; 97 | ResidualBufferStorage temp_resi_orig_; 98 | ResidualBufferStorage temp_resi_; 99 | CoeffBufferStorage temp_coeff_; 100 | }; 101 | 102 | inline TxSearchFlags operator~ (TxSearchFlags a) { 103 | return static_cast(~static_cast(a)); 104 | } 105 | inline TxSearchFlags operator| (TxSearchFlags a, TxSearchFlags b) { 106 | return static_cast(static_cast(a) | static_cast(b)); 107 | } 108 | inline TxSearchFlags operator& (TxSearchFlags a, TxSearchFlags b) { 109 | return static_cast(static_cast(a) & static_cast(b)); 110 | } 111 | inline TxSearchFlags& operator|= (TxSearchFlags& a, TxSearchFlags b) { // NOLINT 112 | a = static_cast(static_cast(a) | static_cast(b)); 113 | return a; 114 | } 115 | inline TxSearchFlags& operator&= (TxSearchFlags& a, TxSearchFlags b) { // NOLINT 116 | a = static_cast(static_cast(a) & static_cast(b)); 117 | return a; 118 | } 119 | 120 | } // namespace xvc 121 | 122 | #endif // XVC_ENC_LIB_TRANSFORM_ENCODER_H_ 123 | -------------------------------------------------------------------------------- /src/xvc_enc_lib/cu_encoder.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_ENC_LIB_CU_ENCODER_H_ 23 | #define XVC_ENC_LIB_CU_ENCODER_H_ 24 | 25 | #include 26 | #include 27 | 28 | #include "xvc_common_lib/picture_data.h" 29 | #include "xvc_common_lib/quantize.h" 30 | #include "xvc_common_lib/yuv_pic.h" 31 | #include "xvc_enc_lib/cu_cache.h" 32 | #include "xvc_enc_lib/cu_writer.h" 33 | #include "xvc_enc_lib/inter_search.h" 34 | #include "xvc_enc_lib/intra_search.h" 35 | #include "xvc_enc_lib/encoder_settings.h" 36 | #include "xvc_enc_lib/encoder_simd_functions.h" 37 | #include "xvc_enc_lib/syntax_writer.h" 38 | #include "xvc_enc_lib/transform_encoder.h" 39 | 40 | namespace xvc { 41 | 42 | class CuEncoder : public TransformEncoder { 43 | public: 44 | CuEncoder(const EncoderSimdFunctions &simd, const YuvPicture &orig_pic, 45 | YuvPicture *rec_pic, PictureData *pic_data, 46 | const EncoderSettings &encoder_settings); 47 | ~CuEncoder(); 48 | void EncodeCtu(int rsaddr, SyntaxWriter *writer); 49 | 50 | private: 51 | enum class RdMode { 52 | kInterMe, 53 | kInterFullpel, 54 | kInterLic, 55 | kInterLicFullpel, 56 | }; 57 | struct RdoCost; 58 | 59 | Distortion CompressCu(CodingUnit **cu, int rdo_depth, 60 | SplitRestriction split_restiction, 61 | RdoSyntaxWriter *rdo_writer, 62 | const Qp &qp); 63 | RdoCost CompressSplitCu(CodingUnit *cu, int rdo_depth, const Qp &qp, 64 | SplitType split_type, SplitRestriction split_restrct, 65 | RdoSyntaxWriter *rdo_writer); 66 | Distortion CompressNoSplit(CodingUnit **cu, int rdo_depth, 67 | SplitRestriction split_restrct, 68 | RdoSyntaxWriter *rdo_writer); 69 | Distortion CompressFast(CodingUnit *cu, const Qp &qp, 70 | const SyntaxWriter &writer); 71 | RdoCost CompressInterPic(CodingUnit **best_cu_ref, CodingUnit **temp_cu_ref, 72 | const Qp &qp, int rdo_depth, 73 | const CuCache::Result &cache_result, 74 | const SyntaxWriter &bitstream_writer); 75 | RdoCost CompressIntra(CodingUnit *cu, const Qp &qp, 76 | const SyntaxWriter &bitstream_writer); 77 | RdoCost CompressInter(CodingUnit *cu, const Qp &qp, 78 | const SyntaxWriter &bitstream_writer, RdMode rd_mode, 79 | Cost best_cu_cost); 80 | RdoCost CompressMerge(CodingUnit *cu, const Qp &qp, 81 | const SyntaxWriter &bitstream_writer, 82 | Cost best_cu_cost, bool fast_merge_skip); 83 | RdoCost CompressAffineMerge(CodingUnit *cu, const Qp &qp, 84 | const SyntaxWriter &bitstream_writer, 85 | Cost best_cu_cost); 86 | RdoCost GetCuCostWithoutSplit(const CodingUnit &cu, const Qp &qp, 87 | const SyntaxWriter &bitstream_writer, 88 | Distortion ssd); 89 | int CalcDeltaQpFromVariance(const CodingUnit *cu); 90 | void WriteCtu(int rsaddr, SyntaxWriter *writer); 91 | void SetQpForAllCusInCtu(CodingUnit *ctu, int qp); 92 | bool CanSkipAnySplitForCu(const CodingUnit &cu) const; 93 | bool CanSkipQuadSplitForCu(const CodingUnit &cu, 94 | bool binary_depth_greater_than_one) const; 95 | 96 | const YuvPicture &orig_pic_; 97 | const EncoderSettings &encoder_settings_; 98 | YuvPicture &rec_pic_; 99 | PictureData &pic_data_; 100 | InterSearch inter_search_; 101 | IntraSearch intra_search_; 102 | CuWriter cu_writer_; 103 | CuCache cu_cache_; 104 | uint32_t last_ctu_frac_bits_ = 0; 105 | // +2 for allow access to one depth lower than smallest CU in RDO 106 | std::array temp_cu_state_; 108 | CodingUnit::ResidualState rd_transform_state_; 109 | std::array, 110 | constants::kMaxNumCuTrees> rdo_temp_cu_; 111 | }; 112 | 113 | } // namespace xvc 114 | 115 | #endif // XVC_ENC_LIB_CU_ENCODER_H_ 116 | -------------------------------------------------------------------------------- /src/xvc_common_lib/reference_picture_lists.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "xvc_common_lib/reference_picture_lists.h" 23 | 24 | #include 25 | #include 26 | 27 | #include "xvc_common_lib/picture_data.h" 28 | 29 | namespace xvc { 30 | 31 | bool ReferencePictureLists::IsRefPicListUsed(RefPicList ref_pic_list, 32 | InterDir inter_dir) { 33 | switch (inter_dir) { 34 | case InterDir::kL0: 35 | return ref_pic_list == RefPicList::kL0; 36 | break; 37 | case InterDir::kL1: 38 | return ref_pic_list == RefPicList::kL1; 39 | break; 40 | case InterDir::kBi: 41 | return true; 42 | break; 43 | default: 44 | return false; 45 | } 46 | } 47 | 48 | bool ReferencePictureLists::HasRefPoc(RefPicList ref_list, PicNum poc) const { 49 | const std::vector &entry_list = 50 | ref_list == RefPicList::kL0 ? l0_ : l1_; 51 | return std::find_if(entry_list.begin(), entry_list.end(), 52 | [poc](const RefEntry &entry) { 53 | return entry.poc == poc; 54 | }) != entry_list.end(); 55 | } 56 | 57 | PicturePredictionType 58 | ReferencePictureLists::GetRefPicType(RefPicList ref_list, int ref_idx) const { 59 | const std::vector &entry_list = 60 | ref_list == RefPicList::kL0 ? l0_ : l1_; 61 | if (static_cast(entry_list.size()) <= ref_idx) { 62 | return PicturePredictionType::kInvalid; 63 | } 64 | return entry_list[ref_idx].data->GetPredictionType(); 65 | } 66 | 67 | int 68 | ReferencePictureLists::GetRefPicTid(RefPicList ref_list, int ref_idx) const { 69 | const std::vector &entry_list = 70 | ref_list == RefPicList::kL0 ? l0_ : l1_; 71 | if (static_cast(entry_list.size()) <= ref_idx) { 72 | return -1; 73 | } 74 | return entry_list[ref_idx].data->GetTid(); 75 | } 76 | 77 | const CodingUnit* 78 | ReferencePictureLists::GetCodingUnitAt(RefPicList ref_list, int index, 79 | CuTree cu_tree, int posx, 80 | int posy) const { 81 | const std::vector &entry_list = 82 | ref_list == RefPicList::kL0 ? l0_ : l1_; 83 | std::shared_ptr pic_data = entry_list[index].data; 84 | return pic_data->GetCuAt(cu_tree, posx, posy); 85 | } 86 | 87 | void ReferencePictureLists::SetRefPic( 88 | RefPicList list, int index, PicNum ref_poc, 89 | const std::shared_ptr &pic_data, 90 | const std::shared_ptr &ref_pic, 91 | const std::shared_ptr &orig_pic) { 92 | std::vector *entry_list = list == RefPicList::kL0 ? &l0_ : &l1_; 93 | if (index >= static_cast(entry_list->size())) { 94 | entry_list->resize(index + 1); 95 | } 96 | (*entry_list)[index].ref_pic = ref_pic; 97 | (*entry_list)[index].orig_pic = orig_pic; 98 | (*entry_list)[index].data = pic_data; 99 | (*entry_list)[index].poc = ref_poc; 100 | if (ref_poc > current_poc_) { 101 | only_back_references_ = false; 102 | } 103 | } 104 | 105 | std::vector 106 | ReferencePictureLists::GetSamePocMappingFor(RefPicList ref_list) const { 107 | RefPicList other_list = ReferencePictureLists::Inverse(ref_list); 108 | int num_ref_pics = GetNumRefPics(ref_list); 109 | int other_ref_pics = GetNumRefPics(other_list); 110 | std::vector mapping(num_ref_pics); 111 | for (int i = 0; i < num_ref_pics; i++) { 112 | mapping[i] = -1; 113 | PicNum ref_poc = GetRefPoc(ref_list, i); 114 | for (int j = 0; j < other_ref_pics; j++) { 115 | if (ref_poc == GetRefPoc(other_list, j)) { 116 | mapping[i] = j; 117 | break; 118 | } 119 | } 120 | } 121 | return mapping; 122 | } 123 | 124 | void ReferencePictureLists::ZeroOutReferences() { 125 | for (auto &ref : l0_) { 126 | ref.ref_pic.reset(); 127 | ref.orig_pic.reset(); 128 | ref.data.reset(); 129 | } 130 | for (auto &ref : l1_) { 131 | ref.ref_pic.reset(); 132 | ref.orig_pic.reset(); 133 | ref.data.reset(); 134 | } 135 | } 136 | 137 | void ReferencePictureLists::Reset(PicNum current_poc) { 138 | l0_.clear(); 139 | l1_.clear(); 140 | current_poc_ = current_poc; 141 | only_back_references_ = true; 142 | } 143 | 144 | } // namespace xvc 145 | -------------------------------------------------------------------------------- /src/xvc_dec_lib/picture_decoder.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_DEC_LIB_PICTURE_DECODER_H_ 23 | #define XVC_DEC_LIB_PICTURE_DECODER_H_ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "xvc_common_lib/checksum.h" 31 | #include "xvc_common_lib/common.h" 32 | #include "xvc_common_lib/picture_data.h" 33 | #include "xvc_common_lib/resample.h" 34 | #include "xvc_common_lib/segment_header.h" 35 | #include "xvc_common_lib/simd_functions.h" 36 | #include "xvc_common_lib/yuv_pic.h" 37 | #include "xvc_dec_lib/bit_reader.h" 38 | #include "xvc_dec_lib/syntax_reader.h" 39 | #include "xvc_dec_lib/xvcdec.h" 40 | 41 | namespace xvc { 42 | 43 | class PictureDecoder { 44 | public: 45 | struct PicNalHeader { 46 | NalUnitType nal_unit_type; 47 | SegmentNum soc; 48 | PicNum poc; 49 | PicNum doc; 50 | int tid; 51 | int pic_qp; 52 | bool highest_layer; 53 | bool deblock; 54 | bool allow_lic; 55 | }; 56 | 57 | PictureDecoder(const SimdFunctions &simd, const PictureFormat &pic_format, 58 | int crop_width, int crop_height); 59 | void Init(const SegmentHeader &segment, const PicNalHeader &header, 60 | ReferencePictureLists &&ref_pic_list, 61 | const PictureFormat &output_pic_format, int64_t user_data); 62 | bool Decode(const SegmentHeader &segment, 63 | const SegmentHeader &prev_segment_header, BitReader *bit_reader, 64 | bool post_process); 65 | bool Postprocess(const SegmentHeader &segment, BitReader *bit_reader); 66 | std::shared_ptr GetOrigPic() const { return nullptr; } 67 | std::shared_ptr GetPicData() const { return pic_data_; } 68 | std::shared_ptr GetPicData() { return pic_data_; } 69 | std::shared_ptr GetRecPic() const { return rec_pic_; } 70 | std::shared_ptr GetRecPic() { return rec_pic_; } 71 | int64_t GetNalUserData() const { return user_data_; } 72 | void SetOutputStatus(OutputStatus status) { 73 | output_status_.store(status, std::memory_order_release); 74 | } 75 | OutputStatus GetOutputStatus() const { 76 | return output_status_.load(std::memory_order_acquire); 77 | } 78 | const std::vector& GetOutputPictureBytes() const { 79 | return output_pic_bytes_; 80 | } 81 | void SetIsConforming(bool conforming) { conforming_ = conforming; } 82 | bool GetIsConforming() const { return conforming_; } 83 | bool IsReferenced() const { return ref_count > 0; } 84 | void AddReferenceCount(int val) const { ref_count += val; } 85 | void RemoveReferenceCount(int val) const { ref_count -= val; } 86 | const std::vector& GetLastChecksum() const { return pic_hash_; } 87 | std::shared_ptr GetAlternativeRecPic( 88 | const PictureFormat &pic_fmt, int crop_width, int crop_height) const; 89 | static PicNalHeader 90 | DecodeHeader(const SegmentHeader &segment_header, BitReader *bit_reader, 91 | PicNum *sub_gop_end_poc, PicNum *sub_gop_start_poc, 92 | PicNum *sub_gop_length, PicNum prev_sub_gop_length, 93 | PicNum doc, SegmentNum soc, int num_buffered_nals); 94 | 95 | private: 96 | void GenerateAlternativeRecPic(const SegmentHeader &segment, 97 | const SegmentHeader &prev_segment_header) const; 98 | bool ValidateChecksum(const SegmentHeader &segment, 99 | BitReader *bit_reader, Checksum::Mode checksum_mode); 100 | 101 | const SimdFunctions &simd_; 102 | Resampler output_resampler_; 103 | PictureFormat output_format_; 104 | std::shared_ptr pic_data_; 105 | std::shared_ptr rec_pic_; 106 | std::shared_ptr alt_rec_pic_; 107 | std::vector pic_hash_; 108 | std::vector output_pic_bytes_; 109 | bool conforming_ = false; 110 | int pic_qp_ = -1; 111 | int64_t user_data_ = 0; 112 | std::atomic output_status_ = { OutputStatus::kHasBeenOutput }; 113 | // TODO(PH) Mutable isn't really needed if const handling is relaxed... 114 | // Note that ref_count should only be modified on "main thread" 115 | mutable int ref_count = 0; 116 | }; 117 | 118 | } // namespace xvc 119 | 120 | #endif // XVC_DEC_LIB_PICTURE_DECODER_H_ 121 | -------------------------------------------------------------------------------- /src/xvc_common_lib/checksum.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "xvc_common_lib/checksum.h" 23 | 24 | #include 25 | 26 | #include "xvc_common_lib/utils_md5.h" 27 | 28 | namespace xvc { 29 | 30 | void Checksum::HashPicture(const YuvPicture &pic) { 31 | switch (method_) { 32 | case Method::kCrc: 33 | CalculateCrc(pic, mode_); 34 | break; 35 | 36 | case Method::kMd5: 37 | CalculateMd5(pic, mode_); 38 | break; 39 | 40 | default: 41 | assert(0); 42 | break; 43 | } 44 | } 45 | 46 | void Checksum::CalculateCrc(const YuvPicture &pic, Mode mode) { 47 | assert(mode == Mode::kMinOverhead || mode == Mode::kMaxRobust); 48 | int num_components = util::GetNumComponents(pic.GetChromaFormat()); 49 | uint32_t crcVal = 0xffff; 50 | 51 | for (int c = 0; c < num_components; c++) { 52 | YuvComponent comp = YuvComponent(c); 53 | if (mode == Mode::kMaxRobust) { 54 | crcVal = 0xffff; 55 | } 56 | auto src = pic.GetSamplePtr(comp, 0, 0); 57 | for (int y = 0; y < pic.GetHeight(comp); y++) { 58 | for (int x = 0; x < pic.GetWidth(comp); x++) { 59 | for (int bit = 0; bit < 8; bit++) { 60 | uint32_t crcMsb = (crcVal >> 15) & 1; 61 | uint32_t bitVal = (src[x] >> (7 - bit)) & 1; 62 | crcVal = (((crcVal << 1) + bitVal) & 0xffff) ^ (crcMsb * 0x1021); 63 | } 64 | if (pic.GetBitdepth() > 8) { 65 | for (int bit = 0; bit < 8; bit++) { 66 | uint32_t crcMsb = (crcVal >> 15) & 1; 67 | uint32_t bitVal = (src[x] >> (15 - bit)) & 1; 68 | crcVal = (((crcVal << 1) + bitVal) & 0xffff) ^ (crcMsb * 0x1021); 69 | } 70 | } 71 | } 72 | src += pic.GetStride(comp); 73 | } 74 | // For MaxRobust, one checksum value is calculated for each component. 75 | if (mode == Mode::kMaxRobust) { 76 | for (int bit = 0; bit < 16; bit++) { 77 | uint32_t crcMsb = (crcVal >> 15) & 1; 78 | crcVal = ((crcVal << 1) & 0xffff) ^ (crcMsb * 0x1021); 79 | } 80 | hash_.push_back((crcVal >> 8) & 0xff); 81 | hash_.push_back(crcVal & 0xff); 82 | } 83 | } 84 | // For MinOverhead, a single checksum value is calculated for the picture. 85 | if (mode == Mode::kMinOverhead) { 86 | for (int bit = 0; bit < 16; bit++) { 87 | uint32_t crcMsb = (crcVal >> 15) & 1; 88 | crcVal = ((crcVal << 1) & 0xffff) ^ (crcMsb * 0x1021); 89 | } 90 | hash_.push_back((crcVal >> 8) & 0xff); 91 | hash_.push_back(crcVal & 0xff); 92 | } 93 | } 94 | 95 | void Checksum::CalculateMd5(const YuvPicture &pic, Mode mode) { 96 | assert(mode == Mode::kMinOverhead || mode == Mode::kMaxRobust); 97 | int num_components = util::GetNumComponents(pic.GetChromaFormat()); 98 | util::MD5 md5; 99 | 100 | for (int c = 0; c < num_components; c++) { 101 | YuvComponent comp = YuvComponent(c); 102 | if (mode == Mode::kMaxRobust) { 103 | md5.Reset(); 104 | } 105 | auto src = pic.GetSamplePtr(comp, 0, 0); 106 | int bitdepth = pic.GetBitdepth(); 107 | int width = pic.GetWidth(comp); 108 | int row = bitdepth == 8 ? width : width << 1; 109 | const uint8_t* samples; 110 | std::vector row_buffer; 111 | if (bitdepth == 8 && sizeof(Sample) == 2) { 112 | row_buffer.resize(width); 113 | } 114 | for (int y = 0; y < pic.GetHeight(comp); y++) { 115 | if (bitdepth == 8 && sizeof(Sample) == 2) { 116 | for (int x = 0; x < width; x++) { 117 | row_buffer[x] = static_cast(src[x]); 118 | } 119 | samples = reinterpret_cast(&row_buffer[0]); 120 | } else { 121 | samples = reinterpret_cast(src); 122 | } 123 | // TODO(Dev) Consider enforcing little endian for high bitdepth yuv 124 | md5.Update(samples, row); 125 | src += pic.GetStride(comp); 126 | } 127 | // For MaxRobust, one checksum value is calculated for each component. 128 | if (mode == Mode::kMaxRobust) { 129 | size_t size = hash_.size(); 130 | hash_.resize(size + 16); 131 | md5.Final(&hash_[size]); 132 | } 133 | } 134 | // For MinOverhead, a single checksum value is calculated for the picture. 135 | if (mode == Mode::kMinOverhead) { 136 | hash_.resize(16); 137 | md5.Final(&hash_[0]); 138 | } 139 | } 140 | 141 | } // namespace xvc 142 | -------------------------------------------------------------------------------- /test/xvc_test/decoder_helper.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_TEST_DECODER_HELPER_H_ 23 | #define XVC_TEST_DECODER_HELPER_H_ 24 | 25 | #include 26 | #include 27 | 28 | #include "googletest/include/gtest/gtest.h" 29 | 30 | #include "xvc_dec_lib/decoder.h" 31 | 32 | namespace xvc_test { 33 | 34 | using NalUnit = std::vector; 35 | 36 | class DecoderHelper { 37 | public: 38 | void Init(bool use_threads = false) { 39 | const int num_threads = use_threads ? -1 : 0; 40 | decoder_ = std::unique_ptr(new ::xvc::Decoder(num_threads)); 41 | } 42 | 43 | void DecodeSegmentHeaderSuccess(const NalUnit &nal) { 44 | xvc::PicNum before_num_decoded_pics = decoder_->GetNumDecodedPics(); 45 | size_t decoded_bytes = decoder_->DecodeNal(&nal[0], nal.size()); 46 | EXPECT_EQ(nal.size(), decoded_bytes); 47 | EXPECT_EQ(::xvc::Decoder::State::kSegmentHeaderDecoded, 48 | decoder_->GetState()); 49 | EXPECT_EQ(before_num_decoded_pics, decoder_->GetNumDecodedPics()); 50 | EXPECT_EQ(0, decoder_->GetNumCorruptedPics()); 51 | EXPECT_FALSE(decoder_->GetDecodedPicture(&last_decoded_picture_)); 52 | EXPECT_EQ(nullptr, last_decoded_picture_.bytes); 53 | EXPECT_EQ(0, last_decoded_picture_.size); 54 | } 55 | 56 | void DecodeSegmentHeaderFailed(const NalUnit &nal) { 57 | xvc::PicNum before_num_decoded_pics = decoder_->GetNumDecodedPics(); 58 | size_t decoded_bytes = decoder_->DecodeNal(&nal[0], nal.size()); 59 | EXPECT_EQ(size_t(xvc::Decoder::kInvalidNal), decoded_bytes); 60 | EXPECT_EQ(before_num_decoded_pics, decoder_->GetNumDecodedPics()); 61 | EXPECT_FALSE(decoder_->GetDecodedPicture(&last_decoded_picture_)); 62 | EXPECT_EQ(nullptr, last_decoded_picture_.bytes); 63 | EXPECT_EQ(0, last_decoded_picture_.size); 64 | } 65 | 66 | bool DecodePictureSuccess(const NalUnit &nal, int64_t user_data = 0) { 67 | xvc::PicNum before_num_decoded_pics = decoder_->GetNumDecodedPics(); 68 | size_t decoded_bytes = decoder_->DecodeNal(&nal[0], nal.size(), user_data); 69 | EXPECT_EQ(nal.size(), decoded_bytes); 70 | EXPECT_EQ(::xvc::Decoder::State::kPicDecoded, decoder_->GetState()); 71 | EXPECT_EQ(before_num_decoded_pics + 1, decoder_->GetNumDecodedPics()); 72 | EXPECT_EQ(0, decoder_->GetNumCorruptedPics()); 73 | return decoder_->GetDecodedPicture(&last_decoded_picture_); 74 | } 75 | 76 | void DecodePictureFailed(const NalUnit &nal) { 77 | xvc::PicNum before_num_decoded_pics = decoder_->GetNumDecodedPics(); 78 | size_t decoded_bytes = decoder_->DecodeNal(&nal[0], nal.size()); 79 | EXPECT_EQ(size_t(xvc::Decoder::kInvalidNal), decoded_bytes); 80 | EXPECT_EQ(before_num_decoded_pics, decoder_->GetNumDecodedPics()); 81 | EXPECT_FALSE(decoder_->GetDecodedPicture(&last_decoded_picture_)); 82 | EXPECT_EQ(0, last_decoded_picture_.size); 83 | } 84 | 85 | bool DecoderFlushAndGet() { 86 | decoder_->FlushBufferedNalUnits(); 87 | return decoder_->GetDecodedPicture(&last_decoded_picture_); 88 | } 89 | 90 | xvc_decoded_picture* DecodeAndFlush(const NalUnit &nal) { 91 | if (DecodePictureSuccess(nal)) { 92 | return &last_decoded_picture_; 93 | } 94 | if (DecoderFlushAndGet()) { 95 | return &last_decoded_picture_; 96 | } 97 | return nullptr; 98 | } 99 | 100 | static 101 | void AssertValidPicture420(int width, int height, 102 | const xvc_decoded_picture &decoded_picture) { 103 | const int byte_width = 104 | width * (decoded_picture.stats.bitdepth == 8 ? 1 : 2); 105 | ASSERT_EQ(width, decoded_picture.stats.width); 106 | ASSERT_EQ(height, decoded_picture.stats.height); 107 | ASSERT_EQ(decoded_picture.planes[0], decoded_picture.bytes); 108 | ASSERT_EQ(decoded_picture.planes[1], decoded_picture.planes[0] + 109 | decoded_picture.stride[0] * height); 110 | ASSERT_EQ(decoded_picture.planes[2], decoded_picture.planes[1] + 111 | decoded_picture.stride[1] * height / 2); 112 | ASSERT_EQ(byte_width, decoded_picture.stride[0]); 113 | ASSERT_EQ(byte_width / 2, decoded_picture.stride[1]); 114 | ASSERT_EQ(byte_width / 2, decoded_picture.stride[2]); 115 | } 116 | 117 | protected: 118 | std::unique_ptr decoder_; 119 | xvc_decoded_picture last_decoded_picture_; 120 | }; 121 | 122 | } // namespace xvc_test 123 | 124 | #endif // XVC_TEST_DECODER_HELPER_H_ 125 | -------------------------------------------------------------------------------- /test/xvc_test/hls_test.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "googletest/include/gtest/gtest.h" 23 | 24 | #include "xvc_test/decoder_helper.h" 25 | #include "xvc_test/encoder_helper.h" 26 | 27 | namespace { 28 | 29 | class HlsTest : public ::testing::Test, 30 | public ::xvc_test::EncoderHelper, public ::xvc_test::DecoderHelper { 31 | public: 32 | void SetUp() override { 33 | EncoderHelper::Init(); 34 | DecoderHelper::Init(); 35 | } 36 | 37 | void EncodeWithVersion(int major_version, int minor_version) { 38 | const xvc::SegmentHeader *segment = encoder_->GetCurrentSegment(); 39 | // Forcing const cast since this behavior is typically not needed/exposed 40 | const_cast(segment)->major_version = major_version; 41 | const_cast(segment)->minor_version = minor_version; 42 | encoder_->SetResolution(0, 0); 43 | std::vector pic_bytes; 44 | auto nals = EncodeOneFrame(pic_bytes, 8); 45 | ASSERT_EQ(2, nals.size()); 46 | } 47 | 48 | void EncodeWithRfeValue(int nal_rfe_value) { 49 | encoder_->SetResolution(0, 0); 50 | std::vector pic_bytes; 51 | auto nals = EncodeOneFrame(pic_bytes, 8); 52 | ASSERT_EQ(2, nals.size()); 53 | // Rewrite value directly in bitstream 54 | uint8_t *nal_unit_header = &encoded_nal_units_[0][0]; 55 | nal_unit_header[0] |= (nal_rfe_value & 1) << 6; 56 | } 57 | }; 58 | 59 | TEST_F(HlsTest, RecvSameVersion) { 60 | EncodeWithVersion(xvc::constants::kXvcMajorVersion, 61 | xvc::constants::kXvcMinorVersion); 62 | DecodeSegmentHeaderSuccess(GetNextNalToDecode()); 63 | ASSERT_EQ(::xvc::Decoder::State::kSegmentHeaderDecoded, decoder_->GetState()); 64 | DecodePictureSuccess(GetNextNalToDecode()); 65 | EXPECT_EQ(::xvc::Decoder::State::kPicDecoded, decoder_->GetState()); 66 | } 67 | 68 | TEST_F(HlsTest, RecvLargerMajorVersion) { 69 | EncodeWithVersion(xvc::constants::kXvcMajorVersion + 1, 70 | xvc::constants::kXvcMinorVersion); 71 | DecodeSegmentHeaderFailed(GetNextNalToDecode()); 72 | ASSERT_EQ(::xvc::Decoder::State::kDecoderVersionTooLow, decoder_->GetState()); 73 | DecodePictureFailed(GetNextNalToDecode()); 74 | EXPECT_EQ(::xvc::Decoder::State::kDecoderVersionTooLow, decoder_->GetState()); 75 | } 76 | 77 | TEST_F(HlsTest, RecvLowerMajorVersion) { 78 | // Note that sample data in bitstream will still use current major version, 79 | // hence this test only works if resolution is (0, 0) 80 | EncodeWithVersion(xvc::constants::kXvcMajorVersion - 1, 81 | xvc::constants::kXvcMinorVersion); 82 | DecodeSegmentHeaderSuccess(GetNextNalToDecode()); 83 | ASSERT_EQ(::xvc::Decoder::State::kSegmentHeaderDecoded, decoder_->GetState()); 84 | DecodePictureSuccess(GetNextNalToDecode()); 85 | EXPECT_EQ(::xvc::Decoder::State::kPicDecoded, decoder_->GetState()); 86 | } 87 | 88 | TEST_F(HlsTest, RecvMajorVersionZero) { 89 | EncodeWithVersion(0, 90 | xvc::constants::kXvcMinorVersion); 91 | DecodeSegmentHeaderFailed(GetNextNalToDecode()); 92 | ASSERT_EQ(::xvc::Decoder::State::kBitstreamVersionTooLow, 93 | decoder_->GetState()); 94 | DecodePictureFailed(GetNextNalToDecode()); 95 | EXPECT_EQ(::xvc::Decoder::State::kBitstreamVersionTooLow, 96 | decoder_->GetState()); 97 | } 98 | 99 | TEST_F(HlsTest, RecvLargerMinorVersion) { 100 | EncodeWithVersion(xvc::constants::kXvcMajorVersion, 101 | xvc::constants::kXvcMinorVersion + 1); 102 | DecodeSegmentHeaderSuccess(GetNextNalToDecode()); 103 | ASSERT_EQ(::xvc::Decoder::State::kSegmentHeaderDecoded, decoder_->GetState()); 104 | DecodePictureSuccess(GetNextNalToDecode()); 105 | EXPECT_EQ(::xvc::Decoder::State::kPicDecoded, decoder_->GetState()); 106 | } 107 | 108 | TEST_F(HlsTest, RecvRfeZero) { 109 | EncodeWithRfeValue(0); 110 | DecodeSegmentHeaderSuccess(GetNextNalToDecode()); 111 | ASSERT_EQ(::xvc::Decoder::State::kSegmentHeaderDecoded, decoder_->GetState()); 112 | DecodePictureSuccess(GetNextNalToDecode()); 113 | EXPECT_EQ(::xvc::Decoder::State::kPicDecoded, decoder_->GetState()); 114 | } 115 | 116 | TEST_F(HlsTest, RecvRfeOne) { 117 | EncodeWithRfeValue(1); 118 | DecodeSegmentHeaderFailed(GetNextNalToDecode()); 119 | ASSERT_EQ(::xvc::Decoder::State::kNoSegmentHeader, decoder_->GetState()); 120 | DecodePictureFailed(GetNextNalToDecode()); 121 | EXPECT_EQ(::xvc::Decoder::State::kNoSegmentHeader, decoder_->GetState()); 122 | } 123 | 124 | } // namespace 125 | -------------------------------------------------------------------------------- /src/xvc_common_lib/quantize.cc: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #include "xvc_common_lib/quantize.h" 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "xvc_common_lib/utils.h" 29 | #include "xvc_common_lib/restrictions.h" 30 | #include "xvc_common_lib/transform.h" 31 | 32 | namespace xvc { 33 | 34 | const uint8_t Qp::kChromaScale_[Qp::kChromaQpMax_ + 1] = { 35 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 36 | 22, 23, 24, 25, 26, 27, 28, 29, 29, 30, 31, 32, 33, 33, 34, 34, 35, 35, 36, 37 | 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 38 | }; 39 | 40 | const int Qp::kFwdQuantScales_[kNumScalingListRem_] = { 41 | 26214, 23302, 20560, 18396, 16384, 14564 42 | }; 43 | 44 | const int Qp::kInvQuantScales_[kNumScalingListRem_] = { 45 | 40, 45, 51, 57, 64, 72 46 | }; 47 | 48 | Qp::Qp(int qp, ChromaFormat chroma_format, int bitdepth, double lambda, 49 | int chroma_offset_table, int chroma_offset_u, int chroma_offset_v) 50 | : lambda_({ lambda, lambda, lambda }), 51 | lambda_sqrt_(std::sqrt(lambda)) { 52 | qp_raw_[0] = qp; 53 | qp_raw_[1] = ScaleChromaQp(qp, chroma_format, bitdepth, 54 | chroma_offset_table, chroma_offset_u); 55 | qp_raw_[2] = ScaleChromaQp(qp, chroma_format, bitdepth, 56 | chroma_offset_table, chroma_offset_v); 57 | qp_bitdepth_[0] = 58 | std::max(0, qp_raw_[0] + kNumScalingListRem_ * (bitdepth - 8)); 59 | qp_bitdepth_[1] = 60 | std::max(0, qp_raw_[1] + kNumScalingListRem_ * (bitdepth - 8)); 61 | qp_bitdepth_[2] = 62 | std::max(0, qp_raw_[2] + kNumScalingListRem_ * (bitdepth - 8)); 63 | distortion_weight_[0] = 1.0; 64 | distortion_weight_[1] = 65 | GetChromaDistWeight(qp, chroma_format, 66 | chroma_offset_table, chroma_offset_u); 67 | distortion_weight_[2] = 68 | GetChromaDistWeight(qp, chroma_format, 69 | chroma_offset_table, chroma_offset_v); 70 | lambda_[1] = lambda / distortion_weight_[1]; 71 | lambda_[2] = lambda / distortion_weight_[2]; 72 | } 73 | 74 | int Qp::ScaleChromaQp(int qp, ChromaFormat chroma_format, int bitdepth, 75 | int chroma_scaling_table, int offset) { 76 | int chroma_qp = util::Clip3(qp + offset, 0, kChromaQpMax_); 77 | if (chroma_format == ChromaFormat::k420 && chroma_scaling_table == 1) { 78 | chroma_qp = kChromaScale_[chroma_qp]; 79 | } 80 | return chroma_qp; 81 | } 82 | 83 | double Qp::GetChromaDistWeight(int qp, ChromaFormat chroma_format, 84 | int chroma_scaling_table, int offset) { 85 | int chroma_qp = util::Clip3(qp, 0, kChromaQpMax_); 86 | int chroma_qp_with_offset = util::Clip3(qp + offset, 0, kChromaQpMax_); 87 | int comp_qp_offset = chroma_qp_with_offset - chroma_qp; 88 | if (chroma_format == ChromaFormat::k420 && chroma_scaling_table == 1) { 89 | comp_qp_offset = kChromaScale_[chroma_qp_with_offset] - chroma_qp; 90 | } 91 | return pow(2.0, -comp_qp_offset / 3.0); 92 | } 93 | 94 | void Quantize::Inverse(YuvComponent comp, const Qp &qp, int width, int height, 95 | int bitdepth, const Coeff *in, ptrdiff_t in_stride, 96 | Coeff *out, ptrdiff_t out_stride) { 97 | const bool size_rounding_bias = 98 | (util::SizeToLog2(width) + util::SizeToLog2(height)) % 2 != 0; 99 | const int transform_shift = GetTransformShift(width, height, bitdepth); 100 | const int shift = kIQuantShift - transform_shift + 101 | (size_rounding_bias ? 8 : 0); 102 | const int scale = qp.GetInvScale(comp) * (size_rounding_bias ? 181 : 1); 103 | 104 | if (shift > 0) { 105 | int offset = (1 << (shift - 1)); 106 | for (int y = 0; y < height; y++) { 107 | for (int x = 0; x < width; x++) { 108 | int coeff = ((in[x] * scale) + offset) >> shift; 109 | out[x] = util::Clip3(coeff, constants::kInt16Min, constants::kInt16Max); 110 | } 111 | in += in_stride; 112 | out += out_stride; 113 | } 114 | } else { 115 | int inv_shift = -shift; 116 | for (int y = 0; y < height; y++) { 117 | for (int x = 0; x < width; x++) { 118 | int coeff = ((in[x] * scale)) << inv_shift; 119 | out[x] = util::Clip3(coeff, constants::kInt16Min, constants::kInt16Max); 120 | } 121 | in += in_stride; 122 | out += out_stride; 123 | } 124 | } 125 | } 126 | 127 | int Quantize::GetTransformShift(int width, int height, int bitdepth) { 128 | const int tr_size_log2 = 129 | (util::SizeToLog2(width) + util::SizeToLog2(height)) >> 1; 130 | return constants::kMaxTrDynamicRange - bitdepth - tr_size_log2; 131 | } 132 | 133 | } // namespace xvc 134 | -------------------------------------------------------------------------------- /src/xvc_common_lib/resample.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2018, Divideon. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | * 18 | * This library is also available under a commercial license. 19 | * Please visit https://xvc.io/license/ for more information. 20 | ******************************************************************************/ 21 | 22 | #ifndef XVC_COMMON_LIB_RESAMPLE_H_ 23 | #define XVC_COMMON_LIB_RESAMPLE_H_ 24 | 25 | #include 26 | #include 27 | 28 | #include "xvc_common_lib/common.h" 29 | #include "xvc_common_lib/yuv_pic.h" 30 | 31 | namespace xvc { 32 | 33 | class Resampler { 34 | public: 35 | using PicPlane = std::pair; 36 | using PicPlanes = std::array; 37 | struct SimdFunc; 38 | 39 | explicit Resampler(const SimdFunc &simd) : simd_(simd) {} 40 | void ConvertFrom(const PictureFormat &src_format, const uint8_t *src_bytes, 41 | YuvPicture *out_pic); 42 | void ConvertFrom(const PictureFormat &src_format, 43 | const PicPlanes &input_planes, 44 | YuvPicture *out_pic); 45 | void ConvertTo(const YuvPicture &src_pic, const PictureFormat &output_format, 46 | std::vector *out_bytes); 47 | 48 | private: 49 | static const int kColorConversionBitdepth = 12; 50 | const uint8_t* 51 | CopyFromBytesFast(YuvComponent comp, const uint8_t *input_bytes, 52 | ptrdiff_t input_stride, int input_bitdepth, 53 | YuvPicture *out_pic) const; 54 | const uint8_t * 55 | CopyFromBytesWithPadding(YuvComponent comp, const uint8_t *src_bytes, 56 | ptrdiff_t src_stride, 57 | const PictureFormat &src_format, 58 | YuvPicture *out_pic) const; 59 | void CopyFromBytesWithResampling(const uint8_t *src_bytes, 60 | const PictureFormat &src_format, 61 | YuvPicture *out_pic) const; 62 | uint8_t* CopyToBytesWithShift(YuvComponent comp, const YuvPicture &src_pic, 63 | int out_bitdepth, bool dither, 64 | uint8_t *out8) const; 65 | void CopyToWithResize(const YuvPicture &src_pic, 66 | const PictureFormat &output_format, 67 | int dst_bitdepth, uint8_t *out8) const; 68 | template 69 | void ConvertColorSpace(uint8_t *dst, int width, int height, 70 | const uint16_t *src, int bitdepth, 71 | ColorMatrix color_matrix) const; 72 | void ConvertColorSpace8bit709(uint8_t *dst, int width, int height, 73 | const uint16_t *src) const; 74 | 75 | const SimdFunc &simd_; 76 | std::vector tmp_bytes_; 77 | }; 78 | 79 | struct Resampler::SimdFunc { 80 | static const int kDither = 2; // 0=off 1=on 81 | SimdFunc(); 82 | void(*copy_sample_byte)(int width, int height, 83 | const Sample *src, ptrdiff_t src_stride, 84 | uint8_t *out, ptrdiff_t out_stride); 85 | void(*copy_sample_short)(int width, int height, 86 | const Sample *src, ptrdiff_t src_stride, 87 | uint16_t *out, ptrdiff_t out_stride); 88 | void(*downshift_sample_byte[kDither])(int width, int height, int shift, 89 | int out_bitdepth, 90 | const Sample *src, ptrdiff_t src_stride, 91 | uint8_t *out, ptrdiff_t out_stride); 92 | void(*downshift_sample_short[kDither])(int width, int height, int shift, 93 | int out_bitdepth, const Sample *src, 94 | ptrdiff_t src_stride, uint16_t *out, 95 | ptrdiff_t out_stride); 96 | void(*upshift_sample_short)(int width, int height, int shift, 97 | const Sample *src, ptrdiff_t src_stride, 98 | uint16_t *out, ptrdiff_t out_stride); 99 | }; 100 | 101 | // TODO(PH) Refactor into Resampler class 102 | 103 | namespace resample { 104 | 105 | template 106 | void Resample(uint8_t *dst_start, int dst_width, int dst_height, 107 | ptrdiff_t dst_stride, int dst_bitdepth, 108 | const uint8_t *src_start, int src_width, int src_height, 109 | ptrdiff_t src_stride, int src_bitdepth); 110 | 111 | template 112 | void BilinearResample(uint8_t *dst_start, int dst_width, int dst_height, 113 | ptrdiff_t dst_stride, int dst_bitdepth, 114 | const uint8_t *src_start, int src_width, int src_height, 115 | ptrdiff_t src_stride, int src_bitdepth); 116 | 117 | } // namespace resample 118 | 119 | } // namespace xvc 120 | 121 | #endif // XVC_COMMON_LIB_RESAMPLE_H_ 122 | --------------------------------------------------------------------------------