diff --git a/.github/workflows/cmake-linux.yml b/.github/workflows/cmake-linux.yml new file mode 100644 index 0000000..6ca9f7a --- /dev/null +++ b/.github/workflows/cmake-linux.yml @@ -0,0 +1,46 @@ +name: CMake CI on Ubuntu + +on: + push: + pull_request: + branches: [ "master" ] + +jobs: + build: + name: ${{ matrix.os }}-${{ matrix.c_compiler }}-${{ matrix.build_type }} + runs-on: ${{ matrix.os }} + timeout-minutes: 5 + + strategy: + # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable. + fail-fast: false + + matrix: + os: [ubuntu-latest] + build_type: [Debug, Release] + c_compiler: [gcc, clang] + + steps: + - uses: actions/checkout@v3 + + - name: Configure CMake + run: | + cmake -S . -B build -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} + + - name: Build CMake + run: | + cmake --build build + + - name: Run CMake tests + run: | + ctest -C ${{ matrix.build_type }} --output-on-failure -V + + - name: Run Unit tests + working-directory: build + run: | + ./h264_analyze ../samples/JM_cqm_cabac.264 > tmp1.out + diff -u ../samples/JM_cqm_cabac.out tmp1.out + ./h264_analyze ../samples/x264_test.264 > tmp2.out + diff -u ../samples/x264_test.out tmp2.out + ./h264_analyze ../samples/riverbed-II-360p-48961.264 > tmp3.out + diff -u ../samples/riverbed-II-360p-48961.out tmp3.out diff --git a/.github/workflows/cmake-macos.yml b/.github/workflows/cmake-macos.yml new file mode 100644 index 0000000..9021ffe --- /dev/null +++ b/.github/workflows/cmake-macos.yml @@ -0,0 +1,46 @@ +name: CMake CI on MacOS + +on: + push: + pull_request: + branches: [ "master" ] + +jobs: + build: + name: ${{ matrix.os }}-${{ matrix.c_compiler }}-${{ matrix.build_type }} + runs-on: ${{ matrix.os }} + timeout-minutes: 5 + + strategy: + # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable. + fail-fast: false + + matrix: + os: [macos-latest] + build_type: [Debug, Release] + c_compiler: [clang] # Both clang and gcc on macos-runner are actually AppleClang 14.0.0 from Xcode + + steps: + - uses: actions/checkout@v3 + + - name: Configure CMake + run: | + cmake -S . -B build -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} + + - name: Build CMake + run: | + cmake --build build + + - name: Run CMake tests + run: | + ctest -C ${{ matrix.build_type }} --output-on-failure -V + + - name: Run Unit tests + working-directory: build + run: | + ./h264_analyze ../samples/JM_cqm_cabac.264 > tmp1.out + diff -u ../samples/JM_cqm_cabac.out tmp1.out + ./h264_analyze ../samples/x264_test.264 > tmp2.out + diff -u ../samples/x264_test.out tmp2.out + ./h264_analyze ../samples/riverbed-II-360p-48961.264 > tmp3.out + diff -u ../samples/riverbed-II-360p-48961.out tmp3.out diff --git a/.github/workflows/cmake-windows.yml b/.github/workflows/cmake-windows.yml new file mode 100644 index 0000000..dfef5ea --- /dev/null +++ b/.github/workflows/cmake-windows.yml @@ -0,0 +1,51 @@ +name: CMake CI on Windows + +on: + push: + pull_request: + branches: [ "master" ] + +jobs: + build: + name: ${{ matrix.os }}-${{ matrix.c_compiler }}-${{ matrix.build_type }} + runs-on: ${{ matrix.os }} + timeout-minutes: 5 + + strategy: + # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable. + fail-fast: false + + matrix: + os: [windows-latest] + build_type: [Debug, Release] + c_compiler: [cl] + + steps: + - uses: actions/checkout@v3 + + - name: Configure CMake + run: | + cmake -S . -B build -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} + + - name: Build CMake + run: | + cmake --build build --config ${{ matrix.build_type }} + + - name: Run CMake tests + run: | + ctest -C ${{ matrix.build_type }} --output-on-failure -V + + - name: Run Unit tests + working-directory: build/${{ matrix.build_type }} + run: | + $result = 0 + ./h264_analyze ../../samples/JM_cqm_cabac.264 > tmp1.out + git diff --exit-code --no-index ../../samples/JM_cqm_cabac.out tmp1.out + if ($LASTEXITCODE -ne 0){ $result = $LASTEXITCODE } + ./h264_analyze ../../samples/x264_test.264 > tmp2.out + git diff --exit-code --no-index ../../samples/x264_test.out tmp2.out + if ($LASTEXITCODE -ne 0){ $result = $LASTEXITCODE } + ./h264_analyze ../../samples/riverbed-II-360p-48961.264 > tmp3.out + git diff --exit-code --no-index ../../samples/riverbed-II-360p-48961.out tmp3.out + if ($LASTEXITCODE -ne 0){ $result = $LASTEXITCODE } + if ($result -ne 0){ throw $result } diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..9419cb6 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,76 @@ +cmake_minimum_required(VERSION 3.23) + +SET(CMAKE_C_STANDARD 99) + +project(h264bitstream + VERSION 0.2.0 + DESCRIPTION "A complete set of functions to read and write H.264 video bitstreams, in particular to examine or modify headers." + HOMEPAGE_URL https://github.com/aizvorski/h264bitstream + LANGUAGES C +) + +include(GNUInstallDirs) + +# Adding interface target for compiler flags +add_library(compile_options INTERFACE) +target_compile_options(compile_options INTERFACE -Wall -pedantic $,-O0,-O2>) +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(compile_options INTERFACE -Wextra -Wshadow -Wwrite-strings -Wno-unused -g) +endif() +if(APPLE) + # Compiler flags for creating universal (fat) binaries. + #target_compile_options(compile_options INTERFACE -force_cpusubtype_ALL -mmacosx-version-min=10.4 -arch i386 -arch ppc -arch x86_64) +endif() + +# Library sources +set(SOURCES + h264_nal.c + h264_sei.c + h264_stream.c +) + +set(HEADERS + bs.h + h264_avcc.h + h264_sei.h + h264_stream.h +) + +# These do not participate in build -- for now... +set(ADDITIONALS + h264_avcc.c + h264_slice_data.c + h264_slice_data.h +) + +add_library(h264bitstream ${SOURCES} ${HEADERS}) +target_sources(h264bitstream + PUBLIC FILE_SET headers TYPE HEADERS FILES ${HEADERS} +) +target_link_libraries(h264bitstream PRIVATE compile_options) + +add_executable(h264_analyze h264_analyze.c) +target_link_libraries(h264_analyze PRIVATE compile_options h264bitstream) + +add_executable(svc_split svc_split.c) +target_link_libraries(svc_split PRIVATE compile_options h264bitstream) + +install(TARGETS h264bitstream h264_analyze svc_split + FILE_SET headers +) + +if(UNIX) + # Support for pkg-config in consuming projects + set(prefix "${CMAKE_INSTALL_PREFIX}") + set(exec_prefix "${CMAKE_INSTALL_PREFIX}") + set(libdir "\${prefix}/${CMAKE_INSTALL_LIBDIR}") + set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") + + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/libh264bitstream.pc.in" + "${CMAKE_CURRENT_BINARY_DIR}/libh264bitstream.pc" + ) + + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libh264bitstream.pc" + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig" + ) +endif(UNIX) \ No newline at end of file diff --git a/libh264bitstream.pc.in b/libh264bitstream.pc.in new file mode 100644 index 0000000..3211162 --- /dev/null +++ b/libh264bitstream.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: @PROJECT_NAME@ +Description: @PROJECT_DESCRIPTION@ +Version: @PROJECT_VERSION@ +Libs: -L${libdir} -lh264bitstream +Cflags: -I${includedir} +Requires: